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"
41 #ifndef IO_COMPLETION_ALL_ACCESS
42 #define IO_COMPLETION_ALL_ACCESS 0x001F0003
45 static BOOL (WINAPI
* pGetVolumePathNameW
)(LPCWSTR
, LPWSTR
, DWORD
);
46 static UINT (WINAPI
*pGetSystemWow64DirectoryW
)( LPWSTR
, UINT
);
48 static VOID (WINAPI
*pRtlFreeUnicodeString
)( PUNICODE_STRING
);
49 static VOID (WINAPI
*pRtlInitUnicodeString
)( PUNICODE_STRING
, LPCWSTR
);
50 static BOOL (WINAPI
*pRtlDosPathNameToNtPathName_U
)( LPCWSTR
, PUNICODE_STRING
, PWSTR
*, CURDIR
* );
51 static NTSTATUS (WINAPI
*pRtlWow64EnableFsRedirectionEx
)( ULONG
, ULONG
* );
53 static NTSTATUS (WINAPI
*pNtCreateMailslotFile
)( PHANDLE
, ULONG
, POBJECT_ATTRIBUTES
, PIO_STATUS_BLOCK
,
54 ULONG
, ULONG
, ULONG
, PLARGE_INTEGER
);
55 static NTSTATUS (WINAPI
*pNtCreateFile
)(PHANDLE
,ACCESS_MASK
,POBJECT_ATTRIBUTES
,PIO_STATUS_BLOCK
,PLARGE_INTEGER
,ULONG
,ULONG
,ULONG
,ULONG
,PVOID
,ULONG
);
56 static NTSTATUS (WINAPI
*pNtOpenFile
)(PHANDLE
,ACCESS_MASK
,POBJECT_ATTRIBUTES
,PIO_STATUS_BLOCK
,ULONG
,ULONG
);
57 static NTSTATUS (WINAPI
*pNtDeleteFile
)(POBJECT_ATTRIBUTES ObjectAttributes
);
58 static NTSTATUS (WINAPI
*pNtReadFile
)(HANDLE hFile
, HANDLE hEvent
,
59 PIO_APC_ROUTINE apc
, void* apc_user
,
60 PIO_STATUS_BLOCK io_status
, void* buffer
, ULONG length
,
61 PLARGE_INTEGER offset
, PULONG key
);
62 static NTSTATUS (WINAPI
*pNtWriteFile
)(HANDLE hFile
, HANDLE hEvent
,
63 PIO_APC_ROUTINE apc
, void* apc_user
,
64 PIO_STATUS_BLOCK io_status
,
65 const void* buffer
, ULONG length
,
66 PLARGE_INTEGER offset
, PULONG key
);
67 static NTSTATUS (WINAPI
*pNtCancelIoFile
)(HANDLE hFile
, PIO_STATUS_BLOCK io_status
);
68 static NTSTATUS (WINAPI
*pNtCancelIoFileEx
)(HANDLE hFile
, PIO_STATUS_BLOCK iosb
, PIO_STATUS_BLOCK io_status
);
69 static NTSTATUS (WINAPI
*pNtClose
)( PHANDLE
);
71 static NTSTATUS (WINAPI
*pNtCreateIoCompletion
)(PHANDLE
, ACCESS_MASK
, POBJECT_ATTRIBUTES
, ULONG
);
72 static NTSTATUS (WINAPI
*pNtOpenIoCompletion
)(PHANDLE
, ACCESS_MASK
, POBJECT_ATTRIBUTES
);
73 static NTSTATUS (WINAPI
*pNtQueryIoCompletion
)(HANDLE
, IO_COMPLETION_INFORMATION_CLASS
, PVOID
, ULONG
, PULONG
);
74 static NTSTATUS (WINAPI
*pNtRemoveIoCompletion
)(HANDLE
, PULONG_PTR
, PULONG_PTR
, PIO_STATUS_BLOCK
, PLARGE_INTEGER
);
75 static NTSTATUS (WINAPI
*pNtSetIoCompletion
)(HANDLE
, ULONG_PTR
, ULONG_PTR
, NTSTATUS
, SIZE_T
);
76 static NTSTATUS (WINAPI
*pNtSetInformationFile
)(HANDLE
, PIO_STATUS_BLOCK
, PVOID
, ULONG
, FILE_INFORMATION_CLASS
);
77 static NTSTATUS (WINAPI
*pNtQueryInformationFile
)(HANDLE
, PIO_STATUS_BLOCK
, PVOID
, ULONG
, FILE_INFORMATION_CLASS
);
78 static NTSTATUS (WINAPI
*pNtQueryDirectoryFile
)(HANDLE
,HANDLE
,PIO_APC_ROUTINE
,PVOID
,PIO_STATUS_BLOCK
,
79 PVOID
,ULONG
,FILE_INFORMATION_CLASS
,BOOLEAN
,PUNICODE_STRING
,BOOLEAN
);
80 static NTSTATUS (WINAPI
*pNtQueryVolumeInformationFile
)(HANDLE
,PIO_STATUS_BLOCK
,PVOID
,ULONG
,FS_INFORMATION_CLASS
);
81 static NTSTATUS (WINAPI
*pNtQueryFullAttributesFile
)(const OBJECT_ATTRIBUTES
*, FILE_NETWORK_OPEN_INFORMATION
*);
83 static inline BOOL
is_signaled( HANDLE obj
)
85 return WaitForSingleObject( obj
, 0 ) == WAIT_OBJECT_0
;
88 static const char* debugstr_longlong(ULONGLONG ll
)
91 if (sizeof(ll
) > sizeof(unsigned long) && ll
>> 32)
92 sprintf(str
, "%lx%08lx", (unsigned long)(ll
>> 32), (unsigned long)ll
);
94 sprintf(str
, "%lx", (unsigned long)ll
);
98 #define PIPENAME "\\\\.\\pipe\\ntdll_tests_file.c"
99 #define TEST_BUF_LEN 3
101 static BOOL
create_pipe( HANDLE
*read
, HANDLE
*write
, ULONG flags
, ULONG size
)
103 *read
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_INBOUND
| flags
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
104 1, size
, size
, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
105 ok(*read
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
107 *write
= CreateFileA(PIPENAME
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
108 ok(*write
!= INVALID_HANDLE_VALUE
, "CreateFile failed (%d)\n", GetLastError());
113 static HANDLE
create_temp_file( ULONG flags
)
115 char path
[MAX_PATH
], buffer
[MAX_PATH
];
118 GetTempPathA( MAX_PATH
, path
);
119 GetTempFileNameA( path
, "foo", 0, buffer
);
120 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
121 flags
| FILE_FLAG_DELETE_ON_CLOSE
, 0);
122 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
123 return (handle
== INVALID_HANDLE_VALUE
) ? 0 : handle
;
126 #define CVALUE_FIRST 0xfffabbcc
127 #define CKEY_FIRST 0x1030341
128 #define CKEY_SECOND 0x132E46
130 static ULONG_PTR completionKey
;
131 static IO_STATUS_BLOCK ioSb
;
132 static ULONG_PTR completionValue
;
134 static ULONG
get_pending_msgs(HANDLE h
)
139 res
= pNtQueryIoCompletion( h
, IoCompletionBasicInformation
, &a
, sizeof(a
), &req
);
140 ok( res
== STATUS_SUCCESS
, "NtQueryIoCompletion failed: %x\n", res
);
141 if (res
!= STATUS_SUCCESS
) return -1;
142 ok( req
== sizeof(a
), "Unexpected response size: %x\n", req
);
146 static BOOL
get_msg(HANDLE h
)
148 LARGE_INTEGER timeout
= {{-10000000*3}};
149 DWORD res
= pNtRemoveIoCompletion( h
, &completionKey
, &completionValue
, &ioSb
, &timeout
);
150 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %x\n", res
);
151 if (res
!= STATUS_SUCCESS
)
153 completionKey
= completionValue
= 0;
154 memset(&ioSb
, 0, sizeof(ioSb
));
161 static void WINAPI
apc( void *arg
, IO_STATUS_BLOCK
*iosb
, ULONG reserved
)
165 trace( "apc called block %p iosb.status %x iosb.info %lu\n",
166 iosb
, U(*iosb
).Status
, iosb
->Information
);
168 ok( !reserved
, "reserved is not 0: %x\n", reserved
);
171 static void create_file_test(void)
173 static const WCHAR systemrootW
[] = {'\\','S','y','s','t','e','m','R','o','o','t',
174 '\\','f','a','i','l','i','n','g',0};
175 static const WCHAR questionmarkInvalidNameW
[] = {'a','f','i','l','e','?',0};
176 static const WCHAR pipeInvalidNameW
[] = {'a','|','b',0};
177 static const WCHAR pathInvalidNtW
[] = {'\\','\\','?','\\',0};
178 static const WCHAR pathInvalidNt2W
[] = {'\\','?','?','\\',0};
179 static const WCHAR pathInvalidDosW
[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
180 FILE_NETWORK_OPEN_INFORMATION info
;
183 WCHAR path
[MAX_PATH
];
184 OBJECT_ATTRIBUTES attr
;
186 UNICODE_STRING nameW
;
188 GetCurrentDirectoryW( MAX_PATH
, path
);
189 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
190 attr
.Length
= sizeof(attr
);
191 attr
.RootDirectory
= 0;
192 attr
.ObjectName
= &nameW
;
193 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
194 attr
.SecurityDescriptor
= NULL
;
195 attr
.SecurityQualityOfService
= NULL
;
197 /* try various open modes and options on directories */
198 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
199 FILE_OPEN
, FILE_DIRECTORY_FILE
, NULL
, 0 );
200 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
203 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
204 FILE_CREATE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
205 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
206 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
208 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
209 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
210 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
213 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
214 FILE_SUPERSEDE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
215 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
217 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
218 FILE_OVERWRITE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
219 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
221 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
222 FILE_OVERWRITE_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
223 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
225 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
226 FILE_OPEN
, 0, NULL
, 0 );
227 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
230 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
231 FILE_CREATE
, 0, NULL
, 0 );
232 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
233 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
235 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
236 FILE_OPEN_IF
, 0, NULL
, 0 );
237 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
240 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
241 FILE_SUPERSEDE
, 0, NULL
, 0 );
242 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
243 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
245 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
246 FILE_OVERWRITE
, 0, NULL
, 0 );
247 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
248 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
250 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
251 FILE_OVERWRITE_IF
, 0, NULL
, 0 );
252 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
253 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
255 pRtlFreeUnicodeString( &nameW
);
257 pRtlInitUnicodeString( &nameW
, systemrootW
);
258 attr
.Length
= sizeof(attr
);
259 attr
.RootDirectory
= NULL
;
260 attr
.ObjectName
= &nameW
;
261 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
262 attr
.SecurityDescriptor
= NULL
;
263 attr
.SecurityQualityOfService
= NULL
;
265 status
= pNtCreateFile( &dir
, FILE_APPEND_DATA
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_NORMAL
, 0,
266 FILE_OPEN_IF
, FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
268 ok( status
== STATUS_INVALID_PARAMETER
,
269 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
271 /* Invalid chars in file/dirnames */
272 pRtlDosPathNameToNtPathName_U(questionmarkInvalidNameW
, &nameW
, NULL
, NULL
);
273 attr
.ObjectName
= &nameW
;
274 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
275 FILE_SHARE_READ
, FILE_CREATE
,
276 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
277 ok(status
== STATUS_OBJECT_NAME_INVALID
,
278 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
280 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
282 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
283 ok(status
== STATUS_OBJECT_NAME_INVALID
,
284 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
285 pRtlFreeUnicodeString(&nameW
);
287 pRtlDosPathNameToNtPathName_U(pipeInvalidNameW
, &nameW
, NULL
, NULL
);
288 attr
.ObjectName
= &nameW
;
289 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
290 FILE_SHARE_READ
, FILE_CREATE
,
291 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
292 ok(status
== STATUS_OBJECT_NAME_INVALID
,
293 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
295 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
297 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
298 ok(status
== STATUS_OBJECT_NAME_INVALID
,
299 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
300 pRtlFreeUnicodeString(&nameW
);
302 pRtlInitUnicodeString( &nameW
, pathInvalidNtW
);
303 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
304 FILE_SHARE_READ
, FILE_CREATE
,
305 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
306 ok( status
== STATUS_OBJECT_NAME_INVALID
,
307 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
309 status
= pNtQueryFullAttributesFile( &attr
, &info
);
310 todo_wine
ok( status
== STATUS_OBJECT_NAME_INVALID
,
311 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
313 pRtlInitUnicodeString( &nameW
, pathInvalidNt2W
);
314 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
315 FILE_SHARE_READ
, FILE_CREATE
,
316 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
317 ok( status
== STATUS_OBJECT_NAME_INVALID
,
318 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
320 status
= pNtQueryFullAttributesFile( &attr
, &info
);
321 todo_wine
ok( status
== STATUS_OBJECT_NAME_INVALID
,
322 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
324 pRtlInitUnicodeString( &nameW
, pathInvalidDosW
);
325 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
326 FILE_SHARE_READ
, FILE_CREATE
,
327 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
328 ok( status
== STATUS_OBJECT_NAME_INVALID
,
329 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
331 status
= pNtQueryFullAttributesFile( &attr
, &info
);
332 todo_wine
ok( status
== STATUS_OBJECT_NAME_INVALID
,
333 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
336 static void open_file_test(void)
338 static const char testdata
[] = "Hello World";
339 static WCHAR fooW
[] = {'f','o','o',0};
341 HANDLE dir
, root
, handle
, file
;
342 WCHAR path
[MAX_PATH
], tmpfile
[MAX_PATH
];
344 OBJECT_ATTRIBUTES attr
;
346 UNICODE_STRING nameW
;
348 BOOL ret
, restart
= TRUE
;
351 len
= GetWindowsDirectoryW( path
, MAX_PATH
);
352 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
353 attr
.Length
= sizeof(attr
);
354 attr
.RootDirectory
= 0;
355 attr
.ObjectName
= &nameW
;
356 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
357 attr
.SecurityDescriptor
= NULL
;
358 attr
.SecurityQualityOfService
= NULL
;
359 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
360 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
361 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
362 pRtlFreeUnicodeString( &nameW
);
364 path
[3] = 0; /* root of the drive */
365 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
366 status
= pNtOpenFile( &root
, GENERIC_READ
, &attr
, &io
,
367 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
368 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
369 pRtlFreeUnicodeString( &nameW
);
371 /* test opening system dir with RootDirectory set to windows dir */
372 GetSystemDirectoryW( path
, MAX_PATH
);
373 while (path
[len
] == '\\') len
++;
374 nameW
.Buffer
= path
+ len
;
375 nameW
.Length
= lstrlenW(path
+ len
) * sizeof(WCHAR
);
376 attr
.RootDirectory
= dir
;
377 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
378 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
379 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
380 CloseHandle( handle
);
382 /* try uppercase name */
383 for (i
= len
; path
[i
]; i
++) if (path
[i
] >= 'a' && path
[i
] <= 'z') path
[i
] -= 'a' - 'A';
384 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
385 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
386 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
387 CloseHandle( handle
);
389 /* try with leading backslash */
391 nameW
.Length
+= sizeof(WCHAR
);
392 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
393 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
394 ok( status
== STATUS_INVALID_PARAMETER
||
395 status
== STATUS_OBJECT_NAME_INVALID
||
396 status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
397 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
398 if (!status
) CloseHandle( handle
);
400 /* try with empty name */
402 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
403 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
404 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
405 CloseHandle( handle
);
407 /* try open by file id */
409 while (!pNtQueryDirectoryFile( dir
, NULL
, NULL
, NULL
, &io
, data
, sizeof(data
),
410 FileIdBothDirectoryInformation
, TRUE
, NULL
, restart
))
412 FILE_ID_BOTH_DIRECTORY_INFORMATION
*info
= (FILE_ID_BOTH_DIRECTORY_INFORMATION
*)data
;
416 if (!info
->FileId
.QuadPart
) continue;
418 nameW
.Buffer
= (WCHAR
*)&info
->FileId
;
419 nameW
.Length
= sizeof(info
->FileId
);
420 info
->FileName
[info
->FileNameLength
/sizeof(WCHAR
)] = 0;
421 attr
.RootDirectory
= dir
;
422 /* We skip 'open' files by not specifying FILE_SHARE_WRITE */
423 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
425 FILE_OPEN_BY_FILE_ID
|
426 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
427 ok( status
== STATUS_SUCCESS
|| status
== STATUS_ACCESS_DENIED
|| status
== STATUS_NOT_IMPLEMENTED
|| status
== STATUS_SHARING_VIOLATION
,
428 "open %s failed %x\n", wine_dbgstr_w(info
->FileName
), status
);
429 if (status
== STATUS_NOT_IMPLEMENTED
)
431 win_skip( "FILE_OPEN_BY_FILE_ID not supported\n" );
434 if (status
== STATUS_SHARING_VIOLATION
)
435 trace( "%s is currently open\n", wine_dbgstr_w(info
->FileName
) );
438 BYTE buf
[sizeof(FILE_ALL_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
440 if (!pNtQueryInformationFile( handle
, &io
, buf
, sizeof(buf
), FileAllInformation
))
442 FILE_ALL_INFORMATION
*fai
= (FILE_ALL_INFORMATION
*)buf
;
444 /* check that it's the same file/directory */
446 /* don't check the size for directories */
447 if (!(info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
448 ok( info
->EndOfFile
.QuadPart
== fai
->StandardInformation
.EndOfFile
.QuadPart
,
449 "mismatched file size for %s\n", wine_dbgstr_w(info
->FileName
));
451 ok( info
->CreationTime
.QuadPart
== fai
->BasicInformation
.CreationTime
.QuadPart
,
452 "mismatched creation time for %s\n", wine_dbgstr_w(info
->FileName
));
454 CloseHandle( handle
);
456 /* try same thing from drive root */
457 attr
.RootDirectory
= root
;
458 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
459 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
460 FILE_OPEN_BY_FILE_ID
|
461 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
462 ok( status
== STATUS_SUCCESS
|| status
== STATUS_NOT_IMPLEMENTED
,
463 "open %s failed %x\n", wine_dbgstr_w(info
->FileName
), status
);
464 if (!status
) CloseHandle( handle
);
471 GetTempPathW( MAX_PATH
, path
);
472 GetTempFileNameW( path
, fooW
, 0, tmpfile
);
473 pRtlDosPathNameToNtPathName_U( tmpfile
, &nameW
, NULL
, NULL
);
475 file
= CreateFileW( tmpfile
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
476 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError() );
477 numbytes
= 0xdeadbeef;
478 ret
= WriteFile( file
, testdata
, sizeof(testdata
) - 1, &numbytes
, NULL
);
479 ok( ret
, "WriteFile failed with error %u\n", GetLastError() );
480 ok( numbytes
== sizeof(testdata
) - 1, "failed to write all data\n" );
483 attr
.Length
= sizeof(attr
);
484 attr
.RootDirectory
= 0;
485 attr
.ObjectName
= &nameW
;
486 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
487 attr
.SecurityDescriptor
= NULL
;
488 attr
.SecurityQualityOfService
= NULL
;
489 status
= pNtOpenFile( &file
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
490 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
491 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
492 pRtlFreeUnicodeString( &nameW
);
494 numbytes
= 0xdeadbeef;
495 memset( data
, 0, sizeof(data
) );
496 ret
= ReadFile( file
, data
, sizeof(data
), &numbytes
, NULL
);
497 ok( ret
, "ReadFile failed with error %u\n", GetLastError() );
498 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
499 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
501 nameW
.Length
= sizeof(fooW
) - sizeof(WCHAR
);
503 attr
.RootDirectory
= file
;
504 attr
.ObjectName
= &nameW
;
505 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
506 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
507 ok( status
== STATUS_OBJECT_PATH_NOT_FOUND
,
508 "expected STATUS_OBJECT_PATH_NOT_FOUND, got %08x\n", status
);
512 attr
.RootDirectory
= file
;
513 attr
.ObjectName
= &nameW
;
514 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
515 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
516 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(tmpfile
), status
);
518 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
519 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
520 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
521 ok( numbytes
== 0, "SetFilePointer returned %u\n", numbytes
);
523 numbytes
= 0xdeadbeef;
524 memset( data
, 0, sizeof(data
) );
525 ret
= ReadFile( root
, data
, sizeof(data
), &numbytes
, NULL
);
526 ok( ret
, "ReadFile failed with error %u\n", GetLastError() );
527 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
528 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
530 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
531 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
532 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
533 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
537 DeleteFileW( tmpfile
);
540 static void delete_file_test(void)
543 OBJECT_ATTRIBUTES attr
;
544 UNICODE_STRING nameW
;
545 WCHAR pathW
[MAX_PATH
];
546 WCHAR pathsubW
[MAX_PATH
];
547 static const WCHAR testdirW
[] = {'n','t','d','e','l','e','t','e','f','i','l','e',0};
548 static const WCHAR subdirW
[] = {'\\','s','u','b',0};
550 ret
= GetTempPathW(MAX_PATH
, pathW
);
553 ok(0, "couldn't get temp dir\n");
556 if (ret
+ sizeof(testdirW
)/sizeof(WCHAR
)-1 + sizeof(subdirW
)/sizeof(WCHAR
)-1 >= MAX_PATH
)
558 ok(0, "MAX_PATH exceeded in constructing paths\n");
562 lstrcatW(pathW
, testdirW
);
563 lstrcpyW(pathsubW
, pathW
);
564 lstrcatW(pathsubW
, subdirW
);
566 ret
= CreateDirectoryW(pathW
, NULL
);
567 ok(ret
== TRUE
, "couldn't create directory ntdeletefile\n");
568 if (!pRtlDosPathNameToNtPathName_U(pathW
, &nameW
, NULL
, NULL
))
570 ok(0,"RtlDosPathNametoNtPathName_U failed\n");
574 attr
.Length
= sizeof(attr
);
575 attr
.RootDirectory
= 0;
576 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
577 attr
.ObjectName
= &nameW
;
578 attr
.SecurityDescriptor
= NULL
;
579 attr
.SecurityQualityOfService
= NULL
;
581 /* test NtDeleteFile on an empty directory */
582 ret
= pNtDeleteFile(&attr
);
583 ok(ret
== STATUS_SUCCESS
, "NtDeleteFile should succeed in removing an empty directory\n");
584 ret
= RemoveDirectoryW(pathW
);
585 ok(ret
== FALSE
, "expected to fail removing directory, NtDeleteFile should have removed it\n");
587 /* test NtDeleteFile on a non-empty directory */
588 ret
= CreateDirectoryW(pathW
, NULL
);
589 ok(ret
== TRUE
, "couldn't create directory ntdeletefile ?!\n");
590 ret
= CreateDirectoryW(pathsubW
, NULL
);
591 ok(ret
== TRUE
, "couldn't create directory subdir\n");
592 ret
= pNtDeleteFile(&attr
);
593 ok(ret
== STATUS_SUCCESS
, "expected NtDeleteFile to ret STATUS_SUCCESS\n");
594 ret
= RemoveDirectoryW(pathsubW
);
595 ok(ret
== TRUE
, "expected to remove directory ntdeletefile\\sub\n");
596 ret
= RemoveDirectoryW(pathW
);
597 ok(ret
== TRUE
, "expected to remove directory ntdeletefile, NtDeleteFile failed.\n");
599 pRtlFreeUnicodeString( &nameW
);
602 static void read_file_test(void)
604 const char text
[] = "foobar";
605 HANDLE handle
, read
, write
;
607 IO_STATUS_BLOCK iosb
, iosb2
;
611 LARGE_INTEGER offset
;
612 HANDLE event
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
617 if (!create_pipe( &read
, &write
, FILE_FLAG_OVERLAPPED
, 4096 )) return;
619 /* try read with no data */
620 U(iosb
).Status
= 0xdeadbabe;
621 iosb
.Information
= 0xdeadbeef;
622 ok( is_signaled( read
), "read handle is not signaled\n" );
623 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 1, NULL
, NULL
);
624 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
625 ok( !is_signaled( read
), "read handle is signaled\n" );
626 ok( !is_signaled( event
), "event is signaled\n" );
627 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
628 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
629 ok( !apc_count
, "apc was called\n" );
630 ret
= WriteFile( write
, buffer
, 1, &written
, NULL
);
631 ok(ret
&& written
== 1, "WriteFile error %d\n", GetLastError());
632 /* iosb updated here by async i/o */
633 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
634 ok( U(iosb
).Status
== 0, "wrong status %x\n", U(iosb
).Status
);
635 ok( iosb
.Information
== 1, "wrong info %lu\n", iosb
.Information
);
636 ok( !is_signaled( read
), "read handle is signaled\n" );
637 ok( is_signaled( event
), "event is not signaled\n" );
638 ok( !apc_count
, "apc was called\n" );
640 SleepEx( 1, FALSE
); /* non-alertable sleep */
641 ok( !apc_count
, "apc was called\n" );
642 SleepEx( 1, TRUE
); /* alertable sleep */
643 ok( apc_count
== 1, "apc not called\n" );
645 /* with no event, the pipe handle itself gets signaled */
647 U(iosb
).Status
= 0xdeadbabe;
648 iosb
.Information
= 0xdeadbeef;
649 ok( !is_signaled( read
), "read handle is not signaled\n" );
650 status
= pNtReadFile( read
, 0, apc
, &apc_count
, &iosb
, buffer
, 1, NULL
, NULL
);
651 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
652 ok( !is_signaled( read
), "read handle is signaled\n" );
653 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
654 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
655 ok( !apc_count
, "apc was called\n" );
656 ret
= WriteFile( write
, buffer
, 1, &written
, NULL
);
657 ok(ret
&& written
== 1, "WriteFile error %d\n", GetLastError());
658 /* iosb updated here by async i/o */
659 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
660 ok( U(iosb
).Status
== 0, "wrong status %x\n", U(iosb
).Status
);
661 ok( iosb
.Information
== 1, "wrong info %lu\n", iosb
.Information
);
662 ok( is_signaled( read
), "read handle is signaled\n" );
663 ok( !apc_count
, "apc was called\n" );
665 SleepEx( 1, FALSE
); /* non-alertable sleep */
666 ok( !apc_count
, "apc was called\n" );
667 SleepEx( 1, TRUE
); /* alertable sleep */
668 ok( apc_count
== 1, "apc not called\n" );
670 /* now read with data ready */
672 U(iosb
).Status
= 0xdeadbabe;
673 iosb
.Information
= 0xdeadbeef;
675 ret
= WriteFile( write
, buffer
, 1, &written
, NULL
);
676 ok(ret
&& written
== 1, "WriteFile error %d\n", GetLastError());
677 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 1, NULL
, NULL
);
678 ok( status
== STATUS_SUCCESS
, "wrong status %x\n", status
);
679 ok( U(iosb
).Status
== 0, "wrong status %x\n", U(iosb
).Status
);
680 ok( iosb
.Information
== 1, "wrong info %lu\n", iosb
.Information
);
681 ok( is_signaled( event
), "event is not signaled\n" );
682 ok( !apc_count
, "apc was called\n" );
683 SleepEx( 1, FALSE
); /* non-alertable sleep */
684 ok( !apc_count
, "apc was called\n" );
685 SleepEx( 1, TRUE
); /* alertable sleep */
686 ok( apc_count
== 1, "apc not called\n" );
688 /* try read with no data */
690 U(iosb
).Status
= 0xdeadbabe;
691 iosb
.Information
= 0xdeadbeef;
692 ok( is_signaled( event
), "event is not signaled\n" ); /* check that read resets the event */
693 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
694 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
695 ok( !is_signaled( event
), "event is signaled\n" );
696 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
697 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
698 ok( !apc_count
, "apc was called\n" );
699 ret
= WriteFile( write
, buffer
, 1, &written
, NULL
);
700 ok(ret
&& written
== 1, "WriteFile error %d\n", GetLastError());
701 /* partial read is good enough */
702 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
703 ok( is_signaled( event
), "event is signaled\n" );
704 ok( U(iosb
).Status
== 0, "wrong status %x\n", U(iosb
).Status
);
705 ok( iosb
.Information
== 1, "wrong info %lu\n", iosb
.Information
);
706 ok( !apc_count
, "apc was called\n" );
707 SleepEx( 1, TRUE
); /* alertable sleep */
708 ok( apc_count
== 1, "apc was not called\n" );
710 /* read from disconnected pipe */
712 U(iosb
).Status
= 0xdeadbabe;
713 iosb
.Information
= 0xdeadbeef;
714 CloseHandle( write
);
715 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 1, NULL
, NULL
);
716 ok( status
== STATUS_PIPE_BROKEN
, "wrong status %x\n", status
);
717 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
718 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
719 ok( !is_signaled( event
), "event is signaled\n" );
720 ok( !apc_count
, "apc was called\n" );
721 SleepEx( 1, TRUE
); /* alertable sleep */
722 ok( !apc_count
, "apc was called\n" );
725 /* read from closed handle */
727 U(iosb
).Status
= 0xdeadbabe;
728 iosb
.Information
= 0xdeadbeef;
730 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 1, NULL
, NULL
);
731 ok( status
== STATUS_INVALID_HANDLE
, "wrong status %x\n", status
);
732 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
733 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
734 ok( is_signaled( event
), "event is signaled\n" ); /* not reset on invalid handle */
735 ok( !apc_count
, "apc was called\n" );
736 SleepEx( 1, TRUE
); /* alertable sleep */
737 ok( !apc_count
, "apc was called\n" );
739 /* disconnect while async read is in progress */
740 if (!create_pipe( &read
, &write
, FILE_FLAG_OVERLAPPED
, 4096 )) return;
742 U(iosb
).Status
= 0xdeadbabe;
743 iosb
.Information
= 0xdeadbeef;
744 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
745 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
746 ok( !is_signaled( event
), "event is signaled\n" );
747 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
748 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
749 ok( !apc_count
, "apc was called\n" );
750 CloseHandle( write
);
751 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
752 ok( U(iosb
).Status
== STATUS_PIPE_BROKEN
, "wrong status %x\n", U(iosb
).Status
);
753 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
754 ok( is_signaled( event
), "event is signaled\n" );
755 ok( !apc_count
, "apc was called\n" );
756 SleepEx( 1, TRUE
); /* alertable sleep */
757 ok( apc_count
== 1, "apc was not called\n" );
760 if (!create_pipe( &read
, &write
, FILE_FLAG_OVERLAPPED
, 4096 )) return;
761 ret
= DuplicateHandle(GetCurrentProcess(), read
, GetCurrentProcess(), &handle
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
762 ok(ret
, "Failed to duplicate handle: %d\n", GetLastError());
765 U(iosb
).Status
= 0xdeadbabe;
766 iosb
.Information
= 0xdeadbeef;
767 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
768 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
769 ok( !is_signaled( event
), "event is signaled\n" );
770 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
771 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
772 ok( !apc_count
, "apc was called\n" );
773 /* Cancel by other handle */
774 status
= pNtCancelIoFile( read
, &iosb2
);
775 ok(status
== STATUS_SUCCESS
, "failed to cancel by different handle: %x\n", status
);
776 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
777 ok( U(iosb
).Status
== STATUS_CANCELLED
, "wrong status %x\n", U(iosb
).Status
);
778 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
779 ok( is_signaled( event
), "event is signaled\n" );
780 ok( !apc_count
, "apc was called\n" );
781 SleepEx( 1, TRUE
); /* alertable sleep */
782 ok( apc_count
== 1, "apc was not called\n" );
785 U(iosb
).Status
= 0xdeadbabe;
786 iosb
.Information
= 0xdeadbeef;
787 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
788 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
789 ok( !is_signaled( event
), "event is signaled\n" );
790 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
791 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
792 ok( !apc_count
, "apc was called\n" );
793 /* Close queued handle */
795 SleepEx( 1, TRUE
); /* alertable sleep */
796 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
797 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
798 status
= pNtCancelIoFile( read
, &iosb2
);
799 ok(status
== STATUS_INVALID_HANDLE
, "cancelled by closed handle?\n");
800 status
= pNtCancelIoFile( handle
, &iosb2
);
801 ok(status
== STATUS_SUCCESS
, "failed to cancel: %x\n", status
);
802 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
803 ok( U(iosb
).Status
== STATUS_CANCELLED
, "wrong status %x\n", U(iosb
).Status
);
804 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
805 ok( is_signaled( event
), "event is signaled\n" );
806 ok( !apc_count
, "apc was called\n" );
807 SleepEx( 1, TRUE
); /* alertable sleep */
808 ok( apc_count
== 1, "apc was not called\n" );
809 CloseHandle( handle
);
810 CloseHandle( write
);
812 if (pNtCancelIoFileEx
)
814 /* Basic Cancel Ex */
815 if (!create_pipe( &read
, &write
, FILE_FLAG_OVERLAPPED
, 4096 )) return;
818 U(iosb
).Status
= 0xdeadbabe;
819 iosb
.Information
= 0xdeadbeef;
820 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
821 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
822 ok( !is_signaled( event
), "event is signaled\n" );
823 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
824 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
825 ok( !apc_count
, "apc was called\n" );
826 status
= pNtCancelIoFileEx( read
, &iosb
, &iosb2
);
827 ok(status
== STATUS_SUCCESS
, "Failed to cancel I/O\n");
828 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
829 ok( U(iosb
).Status
== STATUS_CANCELLED
, "wrong status %x\n", U(iosb
).Status
);
830 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
831 ok( is_signaled( event
), "event is signaled\n" );
832 ok( !apc_count
, "apc was called\n" );
833 SleepEx( 1, TRUE
); /* alertable sleep */
834 ok( apc_count
== 1, "apc was not called\n" );
838 U(iosb
).Status
= 0xdeadbabe;
839 iosb
.Information
= 0xdeadbeef;
840 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
841 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
842 ok( !is_signaled( event
), "event is signaled\n" );
843 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
844 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
845 ok( !apc_count
, "apc was called\n" );
846 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
847 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
848 ok( !is_signaled( event
), "event is signaled\n" );
849 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
850 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
851 ok( !apc_count
, "apc was called\n" );
852 status
= pNtCancelIoFileEx( read
, &iosb
, &iosb2
);
853 ok(status
== STATUS_SUCCESS
, "Failed to cancel I/O\n");
854 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
855 ok( U(iosb
).Status
== STATUS_CANCELLED
, "wrong status %x\n", U(iosb
).Status
);
856 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
857 ok( is_signaled( event
), "event is signaled\n" );
858 ok( !apc_count
, "apc was called\n" );
859 SleepEx( 1, TRUE
); /* alertable sleep */
860 ok( apc_count
== 2, "apc was not called\n" );
863 CloseHandle( write
);
866 /* now try a real file */
867 if (!(handle
= create_temp_file( FILE_FLAG_OVERLAPPED
))) return;
869 U(iosb
).Status
= 0xdeadbabe;
870 iosb
.Information
= 0xdeadbeef;
873 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
874 ok( status
== STATUS_SUCCESS
|| status
== STATUS_PENDING
, "wrong status %x\n", status
);
875 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
876 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
877 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
878 ok( is_signaled( event
), "event is signaled\n" );
879 ok( !apc_count
, "apc was called\n" );
880 SleepEx( 1, TRUE
); /* alertable sleep */
881 ok( apc_count
== 1, "apc was not called\n" );
884 U(iosb
).Status
= 0xdeadbabe;
885 iosb
.Information
= 0xdeadbeef;
888 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
889 ok( status
== STATUS_SUCCESS
||
890 status
== STATUS_PENDING
, /* vista */
891 "wrong status %x\n", status
);
892 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
893 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
894 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
895 ok( is_signaled( event
), "event is signaled\n" );
896 ok( !apc_count
, "apc was called\n" );
897 SleepEx( 1, TRUE
); /* alertable sleep */
898 ok( apc_count
== 1, "apc was not called\n" );
900 /* read beyond eof */
902 U(iosb
).Status
= 0xdeadbabe;
903 iosb
.Information
= 0xdeadbeef;
904 offset
.QuadPart
= strlen(text
) + 2;
905 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
906 ok(status
== STATUS_PENDING
|| status
== STATUS_END_OF_FILE
/* before Vista */, "expected STATUS_PENDING or STATUS_END_OF_FILE, got %#x\n", status
);
907 if (status
== STATUS_PENDING
) /* vista */
909 WaitForSingleObject( event
, 1000 );
910 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %x\n", U(iosb
).Status
);
911 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
912 ok( is_signaled( event
), "event is signaled\n" );
913 ok( !apc_count
, "apc was called\n" );
914 SleepEx( 1, TRUE
); /* alertable sleep */
915 ok( apc_count
== 1, "apc was not called\n" );
917 CloseHandle( handle
);
919 /* now a non-overlapped file */
920 if (!(handle
= create_temp_file(0))) return;
922 U(iosb
).Status
= 0xdeadbabe;
923 iosb
.Information
= 0xdeadbeef;
925 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
926 ok( status
== STATUS_END_OF_FILE
||
927 status
== STATUS_SUCCESS
||
928 status
== STATUS_PENDING
, /* vista */
929 "wrong status %x\n", status
);
930 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
931 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
932 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
933 ok( is_signaled( event
), "event is signaled\n" );
934 ok( !apc_count
, "apc was called\n" );
935 SleepEx( 1, TRUE
); /* alertable sleep */
936 ok( apc_count
== 1, "apc was not called\n" );
939 U(iosb
).Status
= 0xdeadbabe;
940 iosb
.Information
= 0xdeadbeef;
943 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
944 ok( status
== STATUS_SUCCESS
, "wrong status %x\n", status
);
945 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
946 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
947 ok( is_signaled( event
), "event is signaled\n" );
948 ok( !apc_count
, "apc was called\n" );
949 SleepEx( 1, TRUE
); /* alertable sleep */
950 todo_wine
ok( !apc_count
, "apc was called\n" );
952 /* read beyond eof */
954 U(iosb
).Status
= 0xdeadbabe;
955 iosb
.Information
= 0xdeadbeef;
956 offset
.QuadPart
= strlen(text
) + 2;
958 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
959 ok( status
== STATUS_END_OF_FILE
, "wrong status %x\n", status
);
960 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %x\n", U(iosb
).Status
);
961 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
962 ok( is_signaled( event
), "event is not signaled\n" );
963 ok( !apc_count
, "apc was called\n" );
964 SleepEx( 1, TRUE
); /* alertable sleep */
965 ok( !apc_count
, "apc was called\n" );
967 CloseHandle( handle
);
969 CloseHandle( event
);
972 static void append_file_test(void)
974 static const char text
[6] = "foobar";
977 IO_STATUS_BLOCK iosb
;
978 LARGE_INTEGER offset
;
979 char path
[MAX_PATH
], buffer
[MAX_PATH
], buf
[16];
982 GetTempPathA( MAX_PATH
, path
);
983 GetTempFileNameA( path
, "foo", 0, buffer
);
985 handle
= CreateFileA(buffer
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
986 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
989 iosb
.Information
= -1;
990 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
, 2, NULL
, NULL
);
991 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
992 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
993 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
997 /* It is possible to open a file with only FILE_APPEND_DATA access flags.
998 It matches the O_WRONLY|O_APPEND open() posix behavior */
999 handle
= CreateFileA(buffer
, FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1000 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
1002 U(iosb
).Status
= -1;
1003 iosb
.Information
= -1;
1004 offset
.QuadPart
= 1;
1005 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 2, 2, &offset
, NULL
);
1006 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
1007 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1008 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
1010 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
1011 ok(ret
== 4, "expected 4, got %u\n", ret
);
1013 U(iosb
).Status
= -1;
1014 iosb
.Information
= -1;
1015 offset
.QuadPart
= 3;
1016 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 4, 2, &offset
, NULL
);
1017 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
1018 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1019 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
1021 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
1022 ok(ret
== 6, "expected 6, got %u\n", ret
);
1024 CloseHandle(handle
);
1026 handle
= CreateFileA(buffer
, FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1027 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
1029 memset(buf
, 0, sizeof(buf
));
1030 U(iosb
).Status
= -1;
1031 iosb
.Information
= -1;
1032 offset
.QuadPart
= 0;
1033 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
1034 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
1035 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1036 ok(iosb
.Information
== 6, "expected 6, got %lu\n", iosb
.Information
);
1038 ok(memcmp(buf
, text
, 6) == 0, "wrong file contents: %s\n", buf
);
1040 U(iosb
).Status
= -1;
1041 iosb
.Information
= -1;
1042 offset
.QuadPart
= 0;
1043 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 3, 3, &offset
, NULL
);
1044 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
1045 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1046 ok(iosb
.Information
== 3, "expected 3, got %lu\n", iosb
.Information
);
1048 memset(buf
, 0, sizeof(buf
));
1049 U(iosb
).Status
= -1;
1050 iosb
.Information
= -1;
1051 offset
.QuadPart
= 0;
1052 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
1053 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
1054 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1055 ok(iosb
.Information
== 6, "expected 6, got %lu\n", iosb
.Information
);
1057 ok(memcmp(buf
, "barbar", 6) == 0, "wrong file contents: %s\n", buf
);
1059 CloseHandle(handle
);
1060 DeleteFileA(buffer
);
1063 static void nt_mailslot_test(void)
1066 ACCESS_MASK DesiredAccess
;
1067 OBJECT_ATTRIBUTES attr
;
1069 ULONG CreateOptions
;
1070 ULONG MailslotQuota
;
1071 ULONG MaxMessageSize
;
1072 LARGE_INTEGER TimeOut
;
1073 IO_STATUS_BLOCK IoStatusBlock
;
1076 WCHAR buffer1
[] = { '\\','?','?','\\','M','A','I','L','S','L','O','T','\\',
1077 'R',':','\\','F','R','E','D','\0' };
1079 TimeOut
.QuadPart
= -1;
1081 pRtlInitUnicodeString(&str
, buffer1
);
1082 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
1083 CreateOptions
= MailslotQuota
= MaxMessageSize
= 0;
1084 DesiredAccess
= GENERIC_READ
;
1087 * Check for NULL pointer handling
1089 rc
= pNtCreateMailslotFile(NULL
, DesiredAccess
,
1090 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1092 ok( rc
== STATUS_ACCESS_VIOLATION
||
1093 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
1094 "rc = %x not STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER\n", rc
);
1097 * Test to see if the Timeout can be NULL
1099 hslot
= (HANDLE
)0xdeadbeef;
1100 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
1101 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1103 ok( rc
== STATUS_SUCCESS
||
1104 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
1105 "rc = %x not STATUS_SUCCESS or STATUS_INVALID_PARAMETER\n", rc
);
1106 ok( hslot
!= 0, "Handle is invalid\n");
1108 if ( rc
== STATUS_SUCCESS
) pNtClose(hslot
);
1111 * Test that the length field is checked properly
1114 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
1115 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1117 todo_wine
ok( rc
== STATUS_INVALID_PARAMETER
, "rc = %x not c000000d STATUS_INVALID_PARAMETER\n", rc
);
1119 if (rc
== STATUS_SUCCESS
) pNtClose(hslot
);
1121 attr
.Length
= sizeof(OBJECT_ATTRIBUTES
)+1;
1122 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
1123 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1125 todo_wine
ok( rc
== STATUS_INVALID_PARAMETER
, "rc = %x not c000000d STATUS_INVALID_PARAMETER\n", rc
);
1127 if (rc
== STATUS_SUCCESS
) pNtClose(hslot
);
1130 * Test handling of a NULL unicode string in ObjectName
1132 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
1133 attr
.ObjectName
= NULL
;
1134 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
1135 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1137 ok( rc
== STATUS_OBJECT_PATH_SYNTAX_BAD
||
1138 rc
== STATUS_INVALID_PARAMETER
,
1139 "rc = %x not STATUS_OBJECT_PATH_SYNTAX_BAD or STATUS_INVALID_PARAMETER\n", rc
);
1141 if (rc
== STATUS_SUCCESS
) pNtClose(hslot
);
1146 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
1147 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
1148 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1150 ok( rc
== STATUS_SUCCESS
, "Create MailslotFile failed rc = %x\n", rc
);
1151 ok( hslot
!= 0, "Handle is invalid\n");
1153 rc
= pNtClose(hslot
);
1154 ok( rc
== STATUS_SUCCESS
, "NtClose failed\n");
1157 static void test_iocp_setcompletion(HANDLE h
)
1163 if (sizeof(size
) > 4) size
|= (ULONGLONG
)0x12345678 << 32;
1165 res
= pNtSetIoCompletion( h
, CKEY_FIRST
, CVALUE_FIRST
, STATUS_INVALID_DEVICE_REQUEST
, size
);
1166 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %x\n", res
);
1168 count
= get_pending_msgs(h
);
1169 ok( count
== 1, "Unexpected msg count: %d\n", count
);
1173 ok( completionKey
== CKEY_FIRST
, "Invalid completion key: %lx\n", completionKey
);
1174 ok( ioSb
.Information
== size
, "Invalid ioSb.Information: %lu\n", ioSb
.Information
);
1175 ok( U(ioSb
).Status
== STATUS_INVALID_DEVICE_REQUEST
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1176 ok( completionValue
== CVALUE_FIRST
, "Invalid completion value: %lx\n", completionValue
);
1179 count
= get_pending_msgs(h
);
1180 ok( !count
, "Unexpected msg count: %d\n", count
);
1183 static void test_iocp_fileio(HANDLE h
)
1185 static const char pipe_name
[] = "\\\\.\\pipe\\iocompletiontestnamedpipe";
1187 IO_STATUS_BLOCK iosb
;
1188 FILE_COMPLETION_INFORMATION fci
= {h
, CKEY_SECOND
};
1189 HANDLE hPipeSrv
, hPipeClt
;
1192 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
1193 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
1194 if (hPipeSrv
!= INVALID_HANDLE_VALUE
)
1196 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1197 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
1198 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
1200 U(iosb
).Status
= 0xdeadbeef;
1201 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1202 ok( res
== STATUS_INVALID_PARAMETER
, "Unexpected NtSetInformationFile on non-overlapped handle: %x\n", res
);
1203 ok( U(iosb
).Status
== STATUS_INVALID_PARAMETER
/* 98 */ || U(iosb
).Status
== 0xdeadbeef /* NT4+ */,
1204 "Unexpected iosb.Status on non-overlapped handle: %x\n", U(iosb
).Status
);
1205 CloseHandle(hPipeClt
);
1207 CloseHandle( hPipeSrv
);
1210 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
1211 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
1212 if (hPipeSrv
== INVALID_HANDLE_VALUE
)
1215 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1216 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
1217 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
1219 OVERLAPPED o
= {0,};
1220 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
1224 U(iosb
).Status
= 0xdeadbeef;
1225 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1226 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1227 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1229 memset( send_buf
, 0, TEST_BUF_LEN
);
1230 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1231 count
= get_pending_msgs(h
);
1232 ok( !count
, "Unexpected msg count: %ld\n", count
);
1233 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1234 count
= get_pending_msgs(h
);
1235 ok( !count
, "Unexpected msg count: %ld\n", count
);
1236 WriteFile( hPipeClt
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1240 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1241 ok( ioSb
.Information
== 3, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1242 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1243 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1244 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] );
1246 count
= get_pending_msgs(h
);
1247 ok( !count
, "Unexpected msg count: %ld\n", count
);
1249 memset( send_buf
, 0, TEST_BUF_LEN
);
1250 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1251 WriteFile( hPipeClt
, send_buf
, 2, &read
, NULL
);
1252 count
= get_pending_msgs(h
);
1253 ok( !count
, "Unexpected msg count: %ld\n", count
);
1254 ReadFile( hPipeSrv
, recv_buf
, 2, &read
, &o
);
1255 count
= get_pending_msgs(h
);
1256 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1259 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1260 ok( ioSb
.Information
== 2, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1261 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1262 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1263 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] );
1266 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1267 CloseHandle( hPipeSrv
);
1268 count
= get_pending_msgs(h
);
1269 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1272 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1273 ok( ioSb
.Information
== 0, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1274 /* wine sends wrong status here */
1275 todo_wine
ok( U(ioSb
).Status
== STATUS_PIPE_BROKEN
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1276 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1280 CloseHandle( hPipeClt
);
1282 /* test associating a completion port with a handle after an async is queued */
1283 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
1284 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
1285 if (hPipeSrv
== INVALID_HANDLE_VALUE
)
1287 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1288 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
1289 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
1291 OVERLAPPED o
= {0,};
1292 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
1296 memset( send_buf
, 0, TEST_BUF_LEN
);
1297 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1298 count
= get_pending_msgs(h
);
1299 ok( !count
, "Unexpected msg count: %ld\n", count
);
1300 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1302 U(iosb
).Status
= 0xdeadbeef;
1303 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1304 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1305 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1306 count
= get_pending_msgs(h
);
1307 ok( !count
, "Unexpected msg count: %ld\n", count
);
1309 WriteFile( hPipeClt
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1313 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1314 ok( ioSb
.Information
== 3, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1315 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1316 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1317 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] );
1319 count
= get_pending_msgs(h
);
1320 ok( !count
, "Unexpected msg count: %ld\n", count
);
1323 CloseHandle( hPipeSrv
);
1324 CloseHandle( hPipeClt
);
1327 static void test_file_full_size_information(void)
1330 FILE_FS_FULL_SIZE_INFORMATION ffsi
;
1331 FILE_FS_SIZE_INFORMATION fsi
;
1335 if(!(h
= create_temp_file(0))) return ;
1337 memset(&ffsi
,0,sizeof(ffsi
));
1338 memset(&fsi
,0,sizeof(fsi
));
1340 /* Assume No Quota Settings configured on Wine Testbot */
1341 res
= pNtQueryVolumeInformationFile(h
, &io
, &ffsi
, sizeof ffsi
, FileFsFullSizeInformation
);
1342 todo_wine
ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %x\n", res
);
1343 res
= pNtQueryVolumeInformationFile(h
, &io
, &fsi
, sizeof fsi
, FileFsSizeInformation
);
1344 ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %x\n", res
);
1346 /* Test for FileFsSizeInformation */
1347 ok(fsi
.TotalAllocationUnits
.QuadPart
> 0,
1348 "[fsi] TotalAllocationUnits expected positive, got 0x%s\n",
1349 debugstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
));
1350 ok(fsi
.AvailableAllocationUnits
.QuadPart
> 0,
1351 "[fsi] AvailableAllocationUnits expected positive, got 0x%s\n",
1352 debugstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
));
1354 /* Assume file system is NTFS */
1355 ok(fsi
.BytesPerSector
== 512, "[fsi] BytesPerSector expected 512, got %d\n",fsi
.BytesPerSector
);
1356 ok(fsi
.SectorsPerAllocationUnit
== 8, "[fsi] SectorsPerAllocationUnit expected 8, got %d\n",fsi
.SectorsPerAllocationUnit
);
1360 ok(ffsi
.TotalAllocationUnits
.QuadPart
> 0,
1361 "[ffsi] TotalAllocationUnits expected positive, got negative value 0x%s\n",
1362 debugstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1363 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
> 0,
1364 "[ffsi] CallerAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1365 debugstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1366 ok(ffsi
.ActualAvailableAllocationUnits
.QuadPart
> 0,
1367 "[ffsi] ActualAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1368 debugstr_longlong(ffsi
.ActualAvailableAllocationUnits
.QuadPart
));
1369 ok(ffsi
.TotalAllocationUnits
.QuadPart
== fsi
.TotalAllocationUnits
.QuadPart
,
1370 "[ffsi] TotalAllocationUnits error fsi:0x%s, ffsi:0x%s\n",
1371 debugstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
),
1372 debugstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1373 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
== fsi
.AvailableAllocationUnits
.QuadPart
,
1374 "[ffsi] CallerAvailableAllocationUnits error fsi:0x%s, ffsi: 0x%s\n",
1375 debugstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
),
1376 debugstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1379 /* Assume file system is NTFS */
1382 ok(ffsi
.BytesPerSector
== 512, "[ffsi] BytesPerSector expected 512, got %d\n",ffsi
.BytesPerSector
);
1383 ok(ffsi
.SectorsPerAllocationUnit
== 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %d\n",ffsi
.SectorsPerAllocationUnit
);
1389 static void test_file_basic_information(void)
1392 FILE_BASIC_INFORMATION fbi
;
1395 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1397 if (!(h
= create_temp_file(0))) return;
1399 /* Check default first */
1400 memset(&fbi
, 0, sizeof(fbi
));
1401 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1402 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1403 ok ( (fbi
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1404 "attribute %x not expected\n", fbi
.FileAttributes
);
1407 /* Clear fbi to avoid setting times */
1408 memset(&fbi
, 0, sizeof(fbi
));
1409 fbi
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1410 U(io
).Status
= 0xdeadbeef;
1411 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1412 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1413 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %x\n", U(io
).Status
);
1415 memset(&fbi
, 0, sizeof(fbi
));
1416 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1417 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1418 todo_wine
ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %x not FILE_ATTRIBUTE_SYSTEM\n", fbi
.FileAttributes
);
1421 memset(&fbi
, 0, sizeof(fbi
));
1422 fbi
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1423 U(io
).Status
= 0xdeadbeef;
1424 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1425 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1426 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %x\n", U(io
).Status
);
1428 memset(&fbi
, 0, sizeof(fbi
));
1429 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1430 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1431 todo_wine
ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %x not FILE_ATTRIBUTE_HIDDEN\n", fbi
.FileAttributes
);
1433 /* Check NORMAL last of all (to make sure we can clear attributes) */
1434 memset(&fbi
, 0, sizeof(fbi
));
1435 fbi
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1436 U(io
).Status
= 0xdeadbeef;
1437 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1438 ok ( res
== STATUS_SUCCESS
, "can't set normal attribute, NtSetInformationFile returned %x\n", res
);
1439 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set normal attribute, io.Status is %x\n", U(io
).Status
);
1441 memset(&fbi
, 0, sizeof(fbi
));
1442 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1443 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1444 todo_wine
ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_NORMAL
, "attribute %x not 0\n", fbi
.FileAttributes
);
1449 static void test_file_all_information(void)
1452 /* FileAllInformation, like FileNameInformation, has a variable-length pathname
1453 * buffer at the end. Vista objects with STATUS_BUFFER_OVERFLOW if you
1454 * don't leave enough room there.
1457 FILE_ALL_INFORMATION fai
;
1462 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1464 if (!(h
= create_temp_file(0))) return;
1466 /* Check default first */
1467 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1468 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1469 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1470 "attribute %x not expected\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1473 /* Clear fbi to avoid setting times */
1474 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1475 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1476 U(io
).Status
= 0xdeadbeef;
1477 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1478 ok ( res
== STATUS_INVALID_INFO_CLASS
|| broken(res
== STATUS_NOT_IMPLEMENTED
), "shouldn't be able to set FileAllInformation, res %x\n", res
);
1479 todo_wine
ok ( U(io
).Status
== 0xdeadbeef, "shouldn't be able to set FileAllInformation, io.Status is %x\n", U(io
).Status
);
1480 U(io
).Status
= 0xdeadbeef;
1481 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1482 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1483 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1485 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1486 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1487 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1488 todo_wine
ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %x not FILE_ATTRIBUTE_SYSTEM\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1491 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1492 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1493 U(io
).Status
= 0xdeadbeef;
1494 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1495 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1496 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1498 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1499 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1500 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1501 todo_wine
ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %x not FILE_ATTRIBUTE_HIDDEN\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1503 /* Check NORMAL last of all (to make sure we can clear attributes) */
1504 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1505 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1506 U(io
).Status
= 0xdeadbeef;
1507 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1508 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1509 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1511 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1512 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1513 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1514 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
);
1519 static void delete_object( WCHAR
*path
)
1521 BOOL ret
= DeleteFileW( path
);
1522 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_ACCESS_DENIED
,
1523 "DeleteFileW failed with %u\n", GetLastError() );
1524 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1526 ret
= RemoveDirectoryW( path
);
1527 ok( ret
, "RemoveDirectoryW failed with %u\n", GetLastError() );
1531 static void test_file_rename_information(void)
1533 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
1534 static const WCHAR fooW
[] = {'f','o','o',0};
1535 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
1536 FILE_RENAME_INFORMATION
*fri
;
1537 FILE_NAME_INFORMATION
*fni
;
1538 BOOL success
, fileDeleted
;
1539 UNICODE_STRING name_str
;
1540 HANDLE handle
, handle2
;
1544 GetTempPathW( MAX_PATH
, tmp_path
);
1546 /* oldpath is a file, newpath doesn't exist */
1547 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1548 ok( res
!= 0, "failed to create temp file\n" );
1549 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1550 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1552 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1553 ok( res
!= 0, "failed to create temp file\n" );
1554 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1555 DeleteFileW( newpath
);
1556 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1557 fri
->Replace
= FALSE
;
1558 fri
->RootDir
= NULL
;
1559 fri
->FileNameLength
= name_str
.Length
;
1560 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1561 pRtlFreeUnicodeString( &name_str
);
1563 U(io
).Status
= 0xdeadbeef;
1564 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1565 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1566 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1567 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1568 ok( fileDeleted
, "file should not exist\n" );
1569 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1570 ok( !fileDeleted
, "file should exist\n" );
1572 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1573 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1574 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1575 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1576 ok( !lstrcmpW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1577 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1578 HeapFree( GetProcessHeap(), 0, fni
);
1580 CloseHandle( handle
);
1581 HeapFree( GetProcessHeap(), 0, fri
);
1582 delete_object( oldpath
);
1583 delete_object( newpath
);
1585 /* oldpath is a file, newpath is a file, Replace = FALSE */
1586 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1587 ok( res
!= 0, "failed to create temp file\n" );
1588 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1589 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1591 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1592 ok( res
!= 0, "failed to create temp file\n" );
1593 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1594 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1595 fri
->Replace
= FALSE
;
1596 fri
->RootDir
= NULL
;
1597 fri
->FileNameLength
= name_str
.Length
;
1598 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1599 pRtlFreeUnicodeString( &name_str
);
1601 U(io
).Status
= 0xdeadbeef;
1602 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1603 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1604 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1605 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1606 ok( !fileDeleted
, "file should exist\n" );
1607 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1608 ok( !fileDeleted
, "file should exist\n" );
1610 CloseHandle( handle
);
1611 HeapFree( GetProcessHeap(), 0, fri
);
1612 delete_object( oldpath
);
1613 delete_object( newpath
);
1615 /* oldpath is a file, newpath is a file, Replace = TRUE */
1616 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1617 ok( res
!= 0, "failed to create temp file\n" );
1618 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1619 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1621 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1622 ok( res
!= 0, "failed to create temp file\n" );
1623 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1624 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1625 fri
->Replace
= TRUE
;
1626 fri
->RootDir
= NULL
;
1627 fri
->FileNameLength
= name_str
.Length
;
1628 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1629 pRtlFreeUnicodeString( &name_str
);
1631 U(io
).Status
= 0xdeadbeef;
1632 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1633 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1634 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1635 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1636 ok( fileDeleted
, "file should not exist\n" );
1637 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1638 ok( !fileDeleted
, "file should exist\n" );
1640 CloseHandle( handle
);
1641 HeapFree( GetProcessHeap(), 0, fri
);
1642 delete_object( oldpath
);
1643 delete_object( newpath
);
1645 /* oldpath is a file, newpath is a file, Replace = FALSE, target file opened */
1646 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1647 ok( res
!= 0, "failed to create temp file\n" );
1648 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1649 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1651 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1652 ok( res
!= 0, "failed to create temp file\n" );
1653 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1654 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1656 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1657 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1658 fri
->Replace
= FALSE
;
1659 fri
->RootDir
= NULL
;
1660 fri
->FileNameLength
= name_str
.Length
;
1661 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1662 pRtlFreeUnicodeString( &name_str
);
1664 U(io
).Status
= 0xdeadbeef;
1665 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1666 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1667 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1668 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1669 ok( !fileDeleted
, "file should exist\n" );
1670 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1671 ok( !fileDeleted
, "file should exist\n" );
1673 CloseHandle( handle
);
1674 CloseHandle( handle2
);
1675 HeapFree( GetProcessHeap(), 0, fri
);
1676 delete_object( oldpath
);
1677 delete_object( newpath
);
1679 /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened */
1680 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1681 ok( res
!= 0, "failed to create temp file\n" );
1682 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1683 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1685 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1686 ok( res
!= 0, "failed to create temp file\n" );
1687 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1688 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1690 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1691 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1692 fri
->Replace
= TRUE
;
1693 fri
->RootDir
= NULL
;
1694 fri
->FileNameLength
= name_str
.Length
;
1695 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1696 pRtlFreeUnicodeString( &name_str
);
1698 U(io
).Status
= 0xdeadbeef;
1699 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1700 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1701 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1702 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1703 ok( !fileDeleted
, "file should exist\n" );
1704 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1705 ok( !fileDeleted
, "file should exist\n" );
1707 CloseHandle( handle
);
1708 CloseHandle( handle2
);
1709 HeapFree( GetProcessHeap(), 0, fri
);
1710 delete_object( oldpath
);
1711 delete_object( newpath
);
1713 /* oldpath is a directory, newpath doesn't exist, Replace = FALSE */
1714 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1715 ok( res
!= 0, "failed to create temp file\n" );
1716 DeleteFileW( oldpath
);
1717 success
= CreateDirectoryW( oldpath
, NULL
);
1718 ok( success
!= 0, "failed to create temp directory\n" );
1719 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1720 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1722 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1723 ok( res
!= 0, "failed to create temp file\n" );
1724 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1725 DeleteFileW( newpath
);
1726 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1727 fri
->Replace
= FALSE
;
1728 fri
->RootDir
= NULL
;
1729 fri
->FileNameLength
= name_str
.Length
;
1730 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1731 pRtlFreeUnicodeString( &name_str
);
1733 U(io
).Status
= 0xdeadbeef;
1734 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1735 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1736 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1737 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1738 ok( fileDeleted
, "file should not exist\n" );
1739 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1740 ok( !fileDeleted
, "file should exist\n" );
1742 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1743 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1744 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1745 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1746 ok( !lstrcmpW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1747 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1748 HeapFree( GetProcessHeap(), 0, fni
);
1750 CloseHandle( handle
);
1751 HeapFree( GetProcessHeap(), 0, fri
);
1752 delete_object( oldpath
);
1753 delete_object( newpath
);
1755 /* oldpath is a directory (but child object opened), newpath doesn't exist, Replace = FALSE */
1756 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1757 ok( res
!= 0, "failed to create temp file\n" );
1758 DeleteFileW( oldpath
);
1759 success
= CreateDirectoryW( oldpath
, NULL
);
1760 ok( success
!= 0, "failed to create temp directory\n" );
1761 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1762 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1764 lstrcpyW( newpath
, oldpath
);
1765 lstrcatW( newpath
, foo_txtW
);
1766 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
1767 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1769 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1770 ok( res
!= 0, "failed to create temp file\n" );
1771 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1772 DeleteFileW( newpath
);
1773 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1774 fri
->Replace
= FALSE
;
1775 fri
->RootDir
= NULL
;
1776 fri
->FileNameLength
= name_str
.Length
;
1777 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1778 pRtlFreeUnicodeString( &name_str
);
1780 U(io
).Status
= 0xdeadbeef;
1781 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1782 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1783 todo_wine
ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1784 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1785 todo_wine
ok( !fileDeleted
, "file should exist\n" );
1786 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1787 todo_wine
ok( fileDeleted
, "file should not exist\n" );
1789 CloseHandle( handle
);
1790 CloseHandle( handle2
);
1791 HeapFree( GetProcessHeap(), 0, fri
);
1792 delete_object( oldpath
);
1793 if (res
== STATUS_SUCCESS
) /* remove when Wine is fixed */
1795 lstrcpyW( oldpath
, newpath
);
1796 lstrcatW( oldpath
, foo_txtW
);
1797 delete_object( oldpath
);
1799 delete_object( newpath
);
1801 /* oldpath is a directory, newpath is a file, Replace = FALSE */
1802 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1803 ok( res
!= 0, "failed to create temp file\n" );
1804 DeleteFileW( oldpath
);
1805 success
= CreateDirectoryW( oldpath
, NULL
);
1806 ok( success
!= 0, "failed to create temp directory\n" );
1807 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1808 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1810 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1811 ok( res
!= 0, "failed to create temp file\n" );
1812 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1813 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1814 fri
->Replace
= FALSE
;
1815 fri
->RootDir
= NULL
;
1816 fri
->FileNameLength
= name_str
.Length
;
1817 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1818 pRtlFreeUnicodeString( &name_str
);
1820 U(io
).Status
= 0xdeadbeef;
1821 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1822 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1823 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1824 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1825 ok( !fileDeleted
, "file should exist\n" );
1826 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1827 ok( !fileDeleted
, "file should exist\n" );
1829 CloseHandle( handle
);
1830 HeapFree( GetProcessHeap(), 0, fri
);
1831 delete_object( oldpath
);
1832 delete_object( newpath
);
1834 /* oldpath is a directory, newpath is a file, Replace = FALSE, target file opened */
1835 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1836 ok( res
!= 0, "failed to create temp file\n" );
1837 DeleteFileW( oldpath
);
1838 success
= CreateDirectoryW( oldpath
, NULL
);
1839 ok( success
!= 0, "failed to create temp directory\n" );
1840 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1841 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1843 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1844 ok( res
!= 0, "failed to create temp file\n" );
1845 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1846 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1848 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1849 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1850 fri
->Replace
= FALSE
;
1851 fri
->RootDir
= NULL
;
1852 fri
->FileNameLength
= name_str
.Length
;
1853 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1854 pRtlFreeUnicodeString( &name_str
);
1856 U(io
).Status
= 0xdeadbeef;
1857 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1858 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1859 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1860 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1861 ok( !fileDeleted
, "file should exist\n" );
1862 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1863 ok( !fileDeleted
, "file should exist\n" );
1865 CloseHandle( handle
);
1866 CloseHandle( handle2
);
1867 HeapFree( GetProcessHeap(), 0, fri
);
1868 delete_object( oldpath
);
1869 delete_object( newpath
);
1871 /* oldpath is a directory, newpath is a file, Replace = TRUE */
1872 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1873 ok( res
!= 0, "failed to create temp file\n" );
1874 DeleteFileW( oldpath
);
1875 success
= CreateDirectoryW( oldpath
, NULL
);
1876 ok( success
!= 0, "failed to create temp directory\n" );
1877 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1878 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1880 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1881 ok( res
!= 0, "failed to create temp file\n" );
1882 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1883 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1884 fri
->Replace
= TRUE
;
1885 fri
->RootDir
= NULL
;
1886 fri
->FileNameLength
= name_str
.Length
;
1887 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1888 pRtlFreeUnicodeString( &name_str
);
1890 U(io
).Status
= 0xdeadbeef;
1891 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1892 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1893 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1894 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1895 ok( fileDeleted
, "file should not exist\n" );
1896 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1897 ok( !fileDeleted
, "file should exist\n" );
1899 CloseHandle( handle
);
1900 HeapFree( GetProcessHeap(), 0, fri
);
1901 delete_object( oldpath
);
1902 delete_object( newpath
);
1904 /* oldpath is a directory, newpath is a file, Replace = TRUE, target file opened */
1905 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1906 ok( res
!= 0, "failed to create temp file\n" );
1907 DeleteFileW( oldpath
);
1908 success
= CreateDirectoryW( oldpath
, NULL
);
1909 ok( success
!= 0, "failed to create temp directory\n" );
1910 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1911 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1913 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1914 ok( res
!= 0, "failed to create temp file\n" );
1915 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1916 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1918 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1919 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1920 fri
->Replace
= TRUE
;
1921 fri
->RootDir
= NULL
;
1922 fri
->FileNameLength
= name_str
.Length
;
1923 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1924 pRtlFreeUnicodeString( &name_str
);
1926 U(io
).Status
= 0xdeadbeef;
1927 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1928 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1929 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1930 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1931 ok( !fileDeleted
, "file should exist\n" );
1932 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1933 ok( !fileDeleted
, "file should exist\n" );
1935 CloseHandle( handle
);
1936 CloseHandle( handle2
);
1937 HeapFree( GetProcessHeap(), 0, fri
);
1938 delete_object( oldpath
);
1939 delete_object( newpath
);
1941 /* oldpath is a directory, newpath is a directory, Replace = FALSE */
1942 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1943 ok( res
!= 0, "failed to create temp file\n" );
1944 DeleteFileW( oldpath
);
1945 success
= CreateDirectoryW( oldpath
, NULL
);
1946 ok( success
!= 0, "failed to create temp directory\n" );
1947 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1948 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1950 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1951 ok( res
!= 0, "failed to create temp file\n" );
1952 DeleteFileW( newpath
);
1953 success
= CreateDirectoryW( newpath
, NULL
);
1954 ok( success
!= 0, "failed to create temp directory\n" );
1955 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1956 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1957 fri
->Replace
= FALSE
;
1958 fri
->RootDir
= NULL
;
1959 fri
->FileNameLength
= name_str
.Length
;
1960 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1961 pRtlFreeUnicodeString( &name_str
);
1963 U(io
).Status
= 0xdeadbeef;
1964 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1965 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1966 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1967 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1968 ok( !fileDeleted
, "file should exist\n" );
1969 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1970 ok( !fileDeleted
, "file should exist\n" );
1972 CloseHandle( handle
);
1973 HeapFree( GetProcessHeap(), 0, fri
);
1974 delete_object( oldpath
);
1975 delete_object( newpath
);
1977 /* oldpath is a directory, newpath is a directory, Replace = TRUE */
1978 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1979 ok( res
!= 0, "failed to create temp file\n" );
1980 DeleteFileW( oldpath
);
1981 success
= CreateDirectoryW( oldpath
, NULL
);
1982 ok( success
!= 0, "failed to create temp directory\n" );
1983 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1984 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1986 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1987 ok( res
!= 0, "failed to create temp file\n" );
1988 DeleteFileW( newpath
);
1989 success
= CreateDirectoryW( newpath
, NULL
);
1990 ok( success
!= 0, "failed to create temp directory\n" );
1991 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1992 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1993 fri
->Replace
= TRUE
;
1994 fri
->RootDir
= NULL
;
1995 fri
->FileNameLength
= name_str
.Length
;
1996 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1997 pRtlFreeUnicodeString( &name_str
);
1999 U(io
).Status
= 0xdeadbeef;
2000 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2001 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2002 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2003 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2004 ok( !fileDeleted
, "file should exist\n" );
2005 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2006 ok( !fileDeleted
, "file should exist\n" );
2008 CloseHandle( handle
);
2009 HeapFree( GetProcessHeap(), 0, fri
);
2010 delete_object( oldpath
);
2011 delete_object( newpath
);
2013 /* oldpath is a directory, newpath is a directory, Replace = TRUE, target file opened */
2014 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2015 ok( res
!= 0, "failed to create temp file\n" );
2016 DeleteFileW( oldpath
);
2017 success
= CreateDirectoryW( oldpath
, NULL
);
2018 ok( success
!= 0, "failed to create temp directory\n" );
2019 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2020 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2022 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2023 ok( res
!= 0, "failed to create temp file\n" );
2024 DeleteFileW( newpath
);
2025 success
= CreateDirectoryW( newpath
, NULL
);
2026 ok( success
!= 0, "failed to create temp directory\n" );
2027 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2028 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2030 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2031 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2032 fri
->Replace
= TRUE
;
2033 fri
->RootDir
= NULL
;
2034 fri
->FileNameLength
= name_str
.Length
;
2035 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2036 pRtlFreeUnicodeString( &name_str
);
2038 U(io
).Status
= 0xdeadbeef;
2039 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2040 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2041 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2042 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2043 ok( !fileDeleted
, "file should exist\n" );
2044 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2045 ok( !fileDeleted
, "file should exist\n" );
2047 CloseHandle( handle
);
2048 CloseHandle( handle2
);
2049 HeapFree( GetProcessHeap(), 0, fri
);
2050 delete_object( oldpath
);
2051 delete_object( newpath
);
2053 /* oldpath is a file, newpath is a directory, Replace = FALSE */
2054 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2055 ok( res
!= 0, "failed to create temp file\n" );
2056 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2057 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2059 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2060 ok( res
!= 0, "failed to create temp file\n" );
2061 DeleteFileW( newpath
);
2062 success
= CreateDirectoryW( newpath
, NULL
);
2063 ok( success
!= 0, "failed to create temp directory\n" );
2064 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2065 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2066 fri
->Replace
= FALSE
;
2067 fri
->RootDir
= NULL
;
2068 fri
->FileNameLength
= name_str
.Length
;
2069 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2070 pRtlFreeUnicodeString( &name_str
);
2072 U(io
).Status
= 0xdeadbeef;
2073 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2074 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2075 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2076 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2077 ok( !fileDeleted
, "file should exist\n" );
2078 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2079 ok( !fileDeleted
, "file should exist\n" );
2081 CloseHandle( handle
);
2082 HeapFree( GetProcessHeap(), 0, fri
);
2083 delete_object( oldpath
);
2084 delete_object( newpath
);
2086 /* oldpath is a file, newpath is a directory, Replace = TRUE */
2087 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2088 ok( res
!= 0, "failed to create temp file\n" );
2089 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2090 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2092 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2093 ok( res
!= 0, "failed to create temp file\n" );
2094 DeleteFileW( newpath
);
2095 success
= CreateDirectoryW( newpath
, NULL
);
2096 ok( success
!= 0, "failed to create temp directory\n" );
2097 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2098 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2099 fri
->Replace
= TRUE
;
2100 fri
->RootDir
= NULL
;
2101 fri
->FileNameLength
= name_str
.Length
;
2102 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2103 pRtlFreeUnicodeString( &name_str
);
2105 U(io
).Status
= 0xdeadbeef;
2106 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2107 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2108 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2109 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2110 ok( !fileDeleted
, "file should exist\n" );
2111 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2112 ok( !fileDeleted
, "file should exist\n" );
2114 CloseHandle( handle
);
2115 HeapFree( GetProcessHeap(), 0, fri
);
2116 delete_object( oldpath
);
2117 delete_object( newpath
);
2119 /* oldpath is a file, newpath doesn't exist, test with RootDir != NULL */
2120 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2121 ok( res
!= 0, "failed to create temp file\n" );
2122 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2123 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2125 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2126 ok( res
!= 0, "failed to create temp file\n" );
2127 DeleteFileW( newpath
);
2128 for (filename
= newpath
, p
= newpath
; *p
; p
++)
2129 if (*p
== '\\') filename
= p
+ 1;
2130 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2131 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2133 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
2134 fri
->Replace
= FALSE
;
2135 fri
->RootDir
= handle2
;
2136 fri
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
2137 memcpy( fri
->FileName
, filename
, fri
->FileNameLength
);
2139 U(io
).Status
= 0xdeadbeef;
2140 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2141 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2142 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2143 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2144 ok( fileDeleted
, "file should not exist\n" );
2145 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2146 ok( !fileDeleted
, "file should exist\n" );
2148 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2149 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2150 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2151 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2152 todo_wine
ok( !lstrcmpW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
2153 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2154 HeapFree( GetProcessHeap(), 0, fni
);
2156 CloseHandle( handle
);
2157 CloseHandle( handle2
);
2158 HeapFree( GetProcessHeap(), 0, fri
);
2159 delete_object( oldpath
);
2160 delete_object( newpath
);
2163 static void test_file_link_information(void)
2165 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
2166 static const WCHAR fooW
[] = {'f','o','o',0};
2167 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
2168 FILE_LINK_INFORMATION
*fli
;
2169 FILE_NAME_INFORMATION
*fni
;
2170 BOOL success
, fileDeleted
;
2171 UNICODE_STRING name_str
;
2172 HANDLE handle
, handle2
;
2176 GetTempPathW( MAX_PATH
, tmp_path
);
2178 /* oldpath is a file, newpath doesn't exist */
2179 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2180 ok( res
!= 0, "failed to create temp file\n" );
2181 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2182 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2184 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2185 ok( res
!= 0, "failed to create temp file\n" );
2186 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2187 DeleteFileW( newpath
);
2188 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2189 fli
->ReplaceIfExists
= FALSE
;
2190 fli
->RootDirectory
= NULL
;
2191 fli
->FileNameLength
= name_str
.Length
;
2192 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2193 pRtlFreeUnicodeString( &name_str
);
2195 U(io
).Status
= 0xdeadbeef;
2196 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2197 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2198 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2199 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2200 ok( !fileDeleted
, "file should exist\n" );
2201 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2202 ok( !fileDeleted
, "file should exist\n" );
2204 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2205 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2206 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2207 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2208 ok( !lstrcmpW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2209 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2210 HeapFree( GetProcessHeap(), 0, fni
);
2212 CloseHandle( handle
);
2213 HeapFree( GetProcessHeap(), 0, fli
);
2214 delete_object( oldpath
);
2215 delete_object( newpath
);
2217 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE */
2218 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2219 ok( res
!= 0, "failed to create temp file\n" );
2220 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2221 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2223 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2224 ok( res
!= 0, "failed to create temp file\n" );
2225 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2226 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2227 fli
->ReplaceIfExists
= FALSE
;
2228 fli
->RootDirectory
= NULL
;
2229 fli
->FileNameLength
= name_str
.Length
;
2230 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2231 pRtlFreeUnicodeString( &name_str
);
2233 U(io
).Status
= 0xdeadbeef;
2234 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2235 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2236 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2237 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2238 ok( !fileDeleted
, "file should exist\n" );
2239 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2240 ok( !fileDeleted
, "file should exist\n" );
2242 CloseHandle( handle
);
2243 HeapFree( GetProcessHeap(), 0, fli
);
2244 delete_object( oldpath
);
2245 delete_object( newpath
);
2247 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE */
2248 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2249 ok( res
!= 0, "failed to create temp file\n" );
2250 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2251 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2253 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2254 ok( res
!= 0, "failed to create temp file\n" );
2255 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2256 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2257 fli
->ReplaceIfExists
= TRUE
;
2258 fli
->RootDirectory
= NULL
;
2259 fli
->FileNameLength
= name_str
.Length
;
2260 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2261 pRtlFreeUnicodeString( &name_str
);
2263 U(io
).Status
= 0xdeadbeef;
2264 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2265 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2266 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2267 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2268 ok( !fileDeleted
, "file should exist\n" );
2269 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2270 ok( !fileDeleted
, "file should exist\n" );
2272 CloseHandle( handle
);
2273 HeapFree( GetProcessHeap(), 0, fli
);
2274 delete_object( oldpath
);
2275 delete_object( newpath
);
2277 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2278 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2279 ok( res
!= 0, "failed to create temp file\n" );
2280 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2281 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2283 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2284 ok( res
!= 0, "failed to create temp file\n" );
2285 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2286 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2288 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2289 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2290 fli
->ReplaceIfExists
= FALSE
;
2291 fli
->RootDirectory
= NULL
;
2292 fli
->FileNameLength
= name_str
.Length
;
2293 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2294 pRtlFreeUnicodeString( &name_str
);
2296 U(io
).Status
= 0xdeadbeef;
2297 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2298 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2299 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2300 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2301 ok( !fileDeleted
, "file should exist\n" );
2302 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2303 ok( !fileDeleted
, "file should exist\n" );
2305 CloseHandle( handle
);
2306 CloseHandle( handle2
);
2307 HeapFree( GetProcessHeap(), 0, fli
);
2308 delete_object( oldpath
);
2309 delete_object( newpath
);
2311 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2312 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2313 ok( res
!= 0, "failed to create temp file\n" );
2314 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2315 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2317 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2318 ok( res
!= 0, "failed to create temp file\n" );
2319 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2320 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2322 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2323 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2324 fli
->ReplaceIfExists
= TRUE
;
2325 fli
->RootDirectory
= NULL
;
2326 fli
->FileNameLength
= name_str
.Length
;
2327 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2328 pRtlFreeUnicodeString( &name_str
);
2330 U(io
).Status
= 0xdeadbeef;
2331 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2332 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2333 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2334 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2335 ok( !fileDeleted
, "file should exist\n" );
2336 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2337 ok( !fileDeleted
, "file should exist\n" );
2339 CloseHandle( handle
);
2340 CloseHandle( handle2
);
2341 HeapFree( GetProcessHeap(), 0, fli
);
2342 delete_object( oldpath
);
2343 delete_object( newpath
);
2345 /* oldpath is a directory, newpath doesn't exist, ReplaceIfExists = FALSE */
2346 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2347 ok( res
!= 0, "failed to create temp file\n" );
2348 DeleteFileW( oldpath
);
2349 success
= CreateDirectoryW( oldpath
, NULL
);
2350 ok( success
!= 0, "failed to create temp directory\n" );
2351 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2352 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2354 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2355 ok( res
!= 0, "failed to create temp file\n" );
2356 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2357 DeleteFileW( newpath
);
2358 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2359 fli
->ReplaceIfExists
= FALSE
;
2360 fli
->RootDirectory
= NULL
;
2361 fli
->FileNameLength
= name_str
.Length
;
2362 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2363 pRtlFreeUnicodeString( &name_str
);
2365 U(io
).Status
= 0xdeadbeef;
2366 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2367 todo_wine
ok( U(io
).Status
== 0xdeadbeef , "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2368 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2369 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2370 ok( !fileDeleted
, "file should exist\n" );
2371 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2372 ok( fileDeleted
, "file should not exist\n" );
2374 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2375 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2376 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2377 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2378 ok( !lstrcmpW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2379 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2380 HeapFree( GetProcessHeap(), 0, fni
);
2382 CloseHandle( handle
);
2383 HeapFree( GetProcessHeap(), 0, fli
);
2384 delete_object( oldpath
);
2385 delete_object( newpath
);
2387 /* oldpath is a directory (but child object opened), newpath doesn't exist, ReplaceIfExists = FALSE */
2388 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2389 ok( res
!= 0, "failed to create temp file\n" );
2390 DeleteFileW( oldpath
);
2391 success
= CreateDirectoryW( oldpath
, NULL
);
2392 ok( success
!= 0, "failed to create temp directory\n" );
2393 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2394 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2396 lstrcpyW( newpath
, oldpath
);
2397 lstrcatW( newpath
, foo_txtW
);
2398 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
2399 ok( handle2
!= 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 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2404 DeleteFileW( newpath
);
2405 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2406 fli
->ReplaceIfExists
= FALSE
;
2407 fli
->RootDirectory
= NULL
;
2408 fli
->FileNameLength
= name_str
.Length
;
2409 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2410 pRtlFreeUnicodeString( &name_str
);
2412 U(io
).Status
= 0xdeadbeef;
2413 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2414 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2415 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2416 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2417 ok( !fileDeleted
, "file should exist\n" );
2418 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2419 ok( fileDeleted
, "file should not exist\n" );
2421 CloseHandle( handle
);
2422 CloseHandle( handle2
);
2423 HeapFree( GetProcessHeap(), 0, fli
);
2424 delete_object( oldpath
);
2425 delete_object( newpath
);
2427 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE */
2428 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2429 ok( res
!= 0, "failed to create temp file\n" );
2430 DeleteFileW( oldpath
);
2431 success
= CreateDirectoryW( oldpath
, NULL
);
2432 ok( success
!= 0, "failed to create temp directory\n" );
2433 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2434 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2436 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2437 ok( res
!= 0, "failed to create temp file\n" );
2438 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2439 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2440 fli
->ReplaceIfExists
= FALSE
;
2441 fli
->RootDirectory
= NULL
;
2442 fli
->FileNameLength
= name_str
.Length
;
2443 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2444 pRtlFreeUnicodeString( &name_str
);
2446 U(io
).Status
= 0xdeadbeef;
2447 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2448 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2449 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2450 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2451 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2452 ok( !fileDeleted
, "file should exist\n" );
2453 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2454 ok( !fileDeleted
, "file should exist\n" );
2456 CloseHandle( handle
);
2457 HeapFree( GetProcessHeap(), 0, fli
);
2458 delete_object( oldpath
);
2459 delete_object( newpath
);
2461 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2462 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2463 ok( res
!= 0, "failed to create temp file\n" );
2464 DeleteFileW( oldpath
);
2465 success
= CreateDirectoryW( oldpath
, NULL
);
2466 ok( success
!= 0, "failed to create temp directory\n" );
2467 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2468 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2470 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2471 ok( res
!= 0, "failed to create temp file\n" );
2472 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2473 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2475 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2476 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2477 fli
->ReplaceIfExists
= FALSE
;
2478 fli
->RootDirectory
= NULL
;
2479 fli
->FileNameLength
= name_str
.Length
;
2480 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2481 pRtlFreeUnicodeString( &name_str
);
2483 U(io
).Status
= 0xdeadbeef;
2484 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2485 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2486 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2487 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2488 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2489 ok( !fileDeleted
, "file should exist\n" );
2490 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2491 ok( !fileDeleted
, "file should exist\n" );
2493 CloseHandle( handle
);
2494 CloseHandle( handle2
);
2495 HeapFree( GetProcessHeap(), 0, fli
);
2496 delete_object( oldpath
);
2497 delete_object( newpath
);
2499 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE */
2500 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2501 ok( res
!= 0, "failed to create temp file\n" );
2502 DeleteFileW( oldpath
);
2503 success
= CreateDirectoryW( oldpath
, NULL
);
2504 ok( success
!= 0, "failed to create temp directory\n" );
2505 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2506 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2508 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2509 ok( res
!= 0, "failed to create temp file\n" );
2510 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2511 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2512 fli
->ReplaceIfExists
= TRUE
;
2513 fli
->RootDirectory
= NULL
;
2514 fli
->FileNameLength
= name_str
.Length
;
2515 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2516 pRtlFreeUnicodeString( &name_str
);
2518 U(io
).Status
= 0xdeadbeef;
2519 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2520 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2521 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2522 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2523 ok( !fileDeleted
, "file should exist\n" );
2524 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2525 ok( !fileDeleted
, "file should exist\n" );
2527 CloseHandle( handle
);
2528 HeapFree( GetProcessHeap(), 0, fli
);
2529 delete_object( oldpath
);
2530 delete_object( newpath
);
2532 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2533 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2534 ok( res
!= 0, "failed to create temp file\n" );
2535 DeleteFileW( oldpath
);
2536 success
= CreateDirectoryW( oldpath
, NULL
);
2537 ok( success
!= 0, "failed to create temp directory\n" );
2538 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2539 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2541 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2542 ok( res
!= 0, "failed to create temp file\n" );
2543 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2544 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2546 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2547 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2548 fli
->ReplaceIfExists
= TRUE
;
2549 fli
->RootDirectory
= NULL
;
2550 fli
->FileNameLength
= name_str
.Length
;
2551 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2552 pRtlFreeUnicodeString( &name_str
);
2554 U(io
).Status
= 0xdeadbeef;
2555 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2556 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2557 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2558 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2559 ok( !fileDeleted
, "file should exist\n" );
2560 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2561 ok( !fileDeleted
, "file should exist\n" );
2563 CloseHandle( handle
);
2564 CloseHandle( handle2
);
2565 HeapFree( GetProcessHeap(), 0, fli
);
2566 delete_object( oldpath
);
2567 delete_object( newpath
);
2569 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = FALSE */
2570 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2571 ok( res
!= 0, "failed to create temp file\n" );
2572 DeleteFileW( oldpath
);
2573 success
= CreateDirectoryW( oldpath
, NULL
);
2574 ok( success
!= 0, "failed to create temp directory\n" );
2575 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2576 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2578 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2579 ok( res
!= 0, "failed to create temp file\n" );
2580 DeleteFileW( newpath
);
2581 success
= CreateDirectoryW( newpath
, NULL
);
2582 ok( success
!= 0, "failed to create temp directory\n" );
2583 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2584 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2585 fli
->ReplaceIfExists
= FALSE
;
2586 fli
->RootDirectory
= NULL
;
2587 fli
->FileNameLength
= name_str
.Length
;
2588 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2589 pRtlFreeUnicodeString( &name_str
);
2591 U(io
).Status
= 0xdeadbeef;
2592 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2593 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2594 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2595 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2596 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2597 ok( !fileDeleted
, "file should exist\n" );
2598 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2599 ok( !fileDeleted
, "file should exist\n" );
2601 CloseHandle( handle
);
2602 HeapFree( GetProcessHeap(), 0, fli
);
2603 delete_object( oldpath
);
2604 delete_object( newpath
);
2606 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE */
2607 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2608 ok( res
!= 0, "failed to create temp file\n" );
2609 DeleteFileW( oldpath
);
2610 success
= CreateDirectoryW( oldpath
, NULL
);
2611 ok( success
!= 0, "failed to create temp directory\n" );
2612 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2613 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2615 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2616 ok( res
!= 0, "failed to create temp file\n" );
2617 DeleteFileW( newpath
);
2618 success
= CreateDirectoryW( newpath
, NULL
);
2619 ok( success
!= 0, "failed to create temp directory\n" );
2620 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2621 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2622 fli
->ReplaceIfExists
= TRUE
;
2623 fli
->RootDirectory
= NULL
;
2624 fli
->FileNameLength
= name_str
.Length
;
2625 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2626 pRtlFreeUnicodeString( &name_str
);
2628 U(io
).Status
= 0xdeadbeef;
2629 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2630 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2631 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2632 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2633 ok( !fileDeleted
, "file should exist\n" );
2634 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2635 ok( !fileDeleted
, "file should exist\n" );
2637 CloseHandle( handle
);
2638 HeapFree( GetProcessHeap(), 0, fli
);
2639 delete_object( oldpath
);
2640 delete_object( newpath
);
2642 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE, target file opened */
2643 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2644 ok( res
!= 0, "failed to create temp file\n" );
2645 DeleteFileW( oldpath
);
2646 success
= CreateDirectoryW( oldpath
, NULL
);
2647 ok( success
!= 0, "failed to create temp directory\n" );
2648 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2649 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2651 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2652 ok( res
!= 0, "failed to create temp file\n" );
2653 DeleteFileW( newpath
);
2654 success
= CreateDirectoryW( newpath
, NULL
);
2655 ok( success
!= 0, "failed to create temp directory\n" );
2656 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2657 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2659 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2660 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2661 fli
->ReplaceIfExists
= TRUE
;
2662 fli
->RootDirectory
= NULL
;
2663 fli
->FileNameLength
= name_str
.Length
;
2664 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2665 pRtlFreeUnicodeString( &name_str
);
2667 U(io
).Status
= 0xdeadbeef;
2668 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2669 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2670 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2671 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2672 ok( !fileDeleted
, "file should exist\n" );
2673 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2674 ok( !fileDeleted
, "file should exist\n" );
2676 CloseHandle( handle
);
2677 CloseHandle( handle2
);
2678 HeapFree( GetProcessHeap(), 0, fli
);
2679 delete_object( oldpath
);
2680 delete_object( newpath
);
2682 /* oldpath is a file, newpath is a directory, ReplaceIfExists = FALSE */
2683 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2684 ok( res
!= 0, "failed to create temp file\n" );
2685 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2686 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2688 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2689 ok( res
!= 0, "failed to create temp file\n" );
2690 DeleteFileW( newpath
);
2691 success
= CreateDirectoryW( newpath
, NULL
);
2692 ok( success
!= 0, "failed to create temp directory\n" );
2693 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2694 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2695 fli
->ReplaceIfExists
= FALSE
;
2696 fli
->RootDirectory
= NULL
;
2697 fli
->FileNameLength
= name_str
.Length
;
2698 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2699 pRtlFreeUnicodeString( &name_str
);
2701 U(io
).Status
= 0xdeadbeef;
2702 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2703 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2704 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2705 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2706 ok( !fileDeleted
, "file should exist\n" );
2707 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2708 ok( !fileDeleted
, "file should exist\n" );
2710 CloseHandle( handle
);
2711 HeapFree( GetProcessHeap(), 0, fli
);
2712 delete_object( oldpath
);
2713 delete_object( newpath
);
2715 /* oldpath is a file, newpath is a directory, ReplaceIfExists = TRUE */
2716 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2717 ok( res
!= 0, "failed to create temp file\n" );
2718 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2719 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2721 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2722 ok( res
!= 0, "failed to create temp file\n" );
2723 DeleteFileW( newpath
);
2724 success
= CreateDirectoryW( newpath
, NULL
);
2725 ok( success
!= 0, "failed to create temp directory\n" );
2726 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2727 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2728 fli
->ReplaceIfExists
= TRUE
;
2729 fli
->RootDirectory
= NULL
;
2730 fli
->FileNameLength
= name_str
.Length
;
2731 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2732 pRtlFreeUnicodeString( &name_str
);
2734 U(io
).Status
= 0xdeadbeef;
2735 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2736 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2737 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2738 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2739 ok( !fileDeleted
, "file should exist\n" );
2740 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2741 ok( !fileDeleted
, "file should exist\n" );
2743 CloseHandle( handle
);
2744 HeapFree( GetProcessHeap(), 0, fli
);
2745 delete_object( oldpath
);
2746 delete_object( newpath
);
2748 /* oldpath is a file, newpath doesn't exist, test with RootDirectory != NULL */
2749 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2750 ok( res
!= 0, "failed to create temp file\n" );
2751 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2752 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2754 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2755 ok( res
!= 0, "failed to create temp file\n" );
2756 DeleteFileW( newpath
);
2757 for (filename
= newpath
, p
= newpath
; *p
; p
++)
2758 if (*p
== '\\') filename
= p
+ 1;
2759 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2760 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2762 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
2763 fli
->ReplaceIfExists
= FALSE
;
2764 fli
->RootDirectory
= handle2
;
2765 fli
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
2766 memcpy( fli
->FileName
, filename
, fli
->FileNameLength
);
2768 U(io
).Status
= 0xdeadbeef;
2769 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2770 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2771 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2772 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2773 ok( !fileDeleted
, "file should exist\n" );
2774 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2775 ok( !fileDeleted
, "file should exist\n" );
2777 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2778 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2779 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2780 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2781 ok( !lstrcmpW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2782 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2783 HeapFree( GetProcessHeap(), 0, fni
);
2785 CloseHandle( handle
);
2786 CloseHandle( handle2
);
2787 HeapFree( GetProcessHeap(), 0, fli
);
2788 delete_object( oldpath
);
2789 delete_object( newpath
);
2792 static void test_file_both_information(void)
2795 FILE_BOTH_DIR_INFORMATION fbi
;
2799 if (!(h
= create_temp_file(0))) return;
2801 memset(&fbi
, 0, sizeof(fbi
));
2802 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBothDirectoryInformation
);
2803 ok ( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "shouldn't be able to query FileBothDirectoryInformation, res %x\n", res
);
2808 static void test_file_disposition_information(void)
2810 char tmp_path
[MAX_PATH
], buffer
[MAX_PATH
+ 16];
2812 HANDLE handle
, handle2
;
2815 FILE_DISPOSITION_INFORMATION fdi
;
2819 GetTempPathA( MAX_PATH
, tmp_path
);
2821 /* tests for info struct size */
2822 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2823 handle
= CreateFileA( buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2824 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2825 res
= pNtSetInformationFile( handle
, &io
, &fdi
, 0, FileDispositionInformation
);
2827 ok( res
== STATUS_INFO_LENGTH_MISMATCH
, "expected STATUS_INFO_LENGTH_MISMATCH, got %x\n", res
);
2829 res
= pNtSetInformationFile( handle
, &io
, &fdi2
, sizeof(fdi2
), FileDispositionInformation
);
2830 ok( res
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %x\n", res
);
2831 CloseHandle( handle
);
2832 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2833 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2834 DeleteFileA( buffer
);
2836 /* cannot set disposition on file not opened with delete access */
2837 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2838 handle
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2839 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2840 res
= pNtQueryInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2841 ok( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "Unexpected NtQueryInformationFile result (expected STATUS_INVALID_INFO_CLASS, got %x)\n", res
);
2842 fdi
.DoDeleteFile
= TRUE
;
2843 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2844 ok( res
== STATUS_ACCESS_DENIED
, "unexpected FileDispositionInformation result (expected STATUS_ACCESS_DENIED, got %x)\n", res
);
2845 CloseHandle( handle
);
2846 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2847 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2848 DeleteFileA( buffer
);
2850 /* can set disposition on file opened with proper access */
2851 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2852 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2853 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2854 fdi
.DoDeleteFile
= TRUE
;
2855 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2856 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2857 CloseHandle( handle
);
2858 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2859 ok( fileDeleted
, "File should have been deleted\n" );
2860 DeleteFileA( buffer
);
2862 /* cannot set disposition on readonly file */
2863 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2864 DeleteFileA( buffer
);
2865 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
2866 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2867 fdi
.DoDeleteFile
= TRUE
;
2868 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2869 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2870 CloseHandle( handle
);
2871 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2872 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2873 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
2874 DeleteFileA( buffer
);
2876 /* cannot set disposition on readonly file */
2877 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2878 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
2879 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2880 fdi
.DoDeleteFile
= TRUE
;
2881 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2883 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2884 CloseHandle( handle
);
2885 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2887 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2888 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
2889 DeleteFileA( buffer
);
2891 /* can set disposition on file and then reset it */
2892 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2893 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2894 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2895 fdi
.DoDeleteFile
= TRUE
;
2896 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2897 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2898 fdi
.DoDeleteFile
= FALSE
;
2899 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2900 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2901 CloseHandle( handle
);
2902 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2903 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2904 DeleteFileA( buffer
);
2906 /* Delete-on-close flag doesn't change file disposition until a handle is closed */
2907 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2908 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2909 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2910 fdi
.DoDeleteFile
= FALSE
;
2911 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2912 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2913 CloseHandle( handle
);
2914 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2915 ok( fileDeleted
, "File should have been deleted\n" );
2916 DeleteFileA( buffer
);
2918 /* Delete-on-close flag sets disposition when a handle is closed and then it could be changed back */
2919 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2920 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2921 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2922 ok( DuplicateHandle( GetCurrentProcess(), handle
, GetCurrentProcess(), &handle2
, 0, FALSE
, DUPLICATE_SAME_ACCESS
), "DuplicateHandle failed\n" );
2923 CloseHandle( handle
);
2924 fdi
.DoDeleteFile
= FALSE
;
2925 res
= pNtSetInformationFile( handle2
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2926 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2927 CloseHandle( handle2
);
2928 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2929 ok( fileDeleted
, "File should have been deleted\n" );
2930 DeleteFileA( buffer
);
2932 /* can set disposition on a directory opened with proper access */
2933 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2934 DeleteFileA( buffer
);
2935 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2936 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2937 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2938 fdi
.DoDeleteFile
= TRUE
;
2939 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2940 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2941 CloseHandle( handle
);
2942 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2943 ok( fileDeleted
, "Directory should have been deleted\n" );
2944 RemoveDirectoryA( buffer
);
2946 /* RemoveDirectory sets directory disposition and it can be undone */
2947 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2948 DeleteFileA( buffer
);
2949 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2950 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2951 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2952 RemoveDirectoryA( buffer
);
2953 fdi
.DoDeleteFile
= FALSE
;
2954 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2955 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2956 CloseHandle( handle
);
2957 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2958 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
2959 RemoveDirectoryA( buffer
);
2961 /* cannot set disposition on a non-empty directory */
2962 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2963 DeleteFileA( buffer
);
2964 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2965 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2966 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2967 dirpos
= lstrlenA( buffer
);
2968 lstrcpyA( buffer
+ dirpos
, "\\tst" );
2969 handle2
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2970 CloseHandle( handle2
);
2971 fdi
.DoDeleteFile
= TRUE
;
2972 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2974 ok( res
== STATUS_DIRECTORY_NOT_EMPTY
, "unexpected FileDispositionInformation result (expected STATUS_DIRECTORY_NOT_EMPTY, got %x)\n", res
);
2975 DeleteFileA( buffer
);
2976 buffer
[dirpos
] = '\0';
2977 CloseHandle( handle
);
2978 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2980 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
2981 RemoveDirectoryA( buffer
);
2984 static void test_iocompletion(void)
2986 HANDLE h
= INVALID_HANDLE_VALUE
;
2989 res
= pNtCreateIoCompletion( &h
, IO_COMPLETION_ALL_ACCESS
, NULL
, 0);
2991 ok( res
== 0, "NtCreateIoCompletion anonymous failed: %x\n", res
);
2992 ok( h
&& h
!= INVALID_HANDLE_VALUE
, "Invalid handle returned\n" );
2994 if ( h
&& h
!= INVALID_HANDLE_VALUE
)
2996 test_iocp_setcompletion(h
);
2997 test_iocp_fileio(h
);
3002 static void test_file_name_information(void)
3004 WCHAR
*file_name
, *volume_prefix
, *expected
;
3005 FILE_NAME_INFORMATION
*info
;
3006 ULONG old_redir
= 1, tmp
;
3007 UINT file_name_size
;
3014 /* GetVolumePathName is not present before w2k */
3015 if (!pGetVolumePathNameW
) {
3016 win_skip("GetVolumePathNameW not found\n");
3020 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
3021 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3022 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3023 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3025 len
= GetSystemDirectoryW( file_name
, file_name_size
);
3026 ok(len
== file_name_size
- 1,
3027 "GetSystemDirectoryW returned %u, expected %u.\n",
3028 len
, file_name_size
- 1);
3030 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3031 ok(len
, "GetVolumePathNameW failed.\n");
3033 len
= lstrlenW( volume_prefix
);
3034 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3035 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3036 expected
[file_name_size
- len
- 1] = '\0';
3038 /* A bit more than we actually need, but it keeps the calculation simple. */
3039 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3040 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3042 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
3043 h
= CreateFileW( file_name
, GENERIC_READ
,
3044 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3045 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3046 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
3047 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3049 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileNameInformation
);
3050 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#x.\n", hr
);
3052 memset( info
, 0xcc, info_size
);
3053 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileNameInformation
);
3054 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3055 hr
, STATUS_BUFFER_OVERFLOW
);
3056 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#x, expected %#x.\n",
3057 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
3058 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %u\n", info
->FileNameLength
);
3059 ok(info
->FileName
[2] == 0xcccc, "info->FileName[2] is %#x, expected 0xcccc.\n", info
->FileName
[2]);
3060 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
3061 "info->FileName[1] is %p, expected %p.\n",
3062 CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
3063 ok(io
.Information
== sizeof(*info
), "io.Information is %lu\n", io
.Information
);
3065 memset( info
, 0xcc, info_size
);
3066 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
3067 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3068 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#x, expected %#x.\n", U(io
).Status
, STATUS_SUCCESS
);
3069 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %u\n", info
->FileNameLength
);
3070 ok(info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] == 0xcccc, "info->FileName[len] is %#x, expected 0xcccc.\n",
3071 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)]);
3072 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
3073 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
3074 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
3075 ok(io
.Information
== FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
,
3076 "io.Information is %lu, expected %u.\n",
3077 io
.Information
, FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
);
3080 HeapFree( GetProcessHeap(), 0, info
);
3081 HeapFree( GetProcessHeap(), 0, expected
);
3082 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3084 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
3086 skip("Not running on WoW64, skipping test.\n");
3087 HeapFree( GetProcessHeap(), 0, file_name
);
3091 h
= CreateFileW( file_name
, GENERIC_READ
,
3092 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3093 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3094 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3095 HeapFree( GetProcessHeap(), 0, file_name
);
3097 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3098 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3099 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3101 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3102 ok(len
== file_name_size
- 1,
3103 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3104 len
, file_name_size
- 1);
3106 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3107 ok(len
, "GetVolumePathNameW failed.\n");
3109 len
= lstrlenW( volume_prefix
);
3110 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3111 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3112 expected
[file_name_size
- len
- 1] = '\0';
3114 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3115 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3117 memset( info
, 0xcc, info_size
);
3118 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
3119 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3120 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
3121 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
3122 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
3125 HeapFree( GetProcessHeap(), 0, info
);
3126 HeapFree( GetProcessHeap(), 0, expected
);
3127 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3128 HeapFree( GetProcessHeap(), 0, file_name
);
3131 static void test_file_all_name_information(void)
3133 WCHAR
*file_name
, *volume_prefix
, *expected
;
3134 FILE_ALL_INFORMATION
*info
;
3135 ULONG old_redir
= 1, tmp
;
3136 UINT file_name_size
;
3143 /* GetVolumePathName is not present before w2k */
3144 if (!pGetVolumePathNameW
) {
3145 win_skip("GetVolumePathNameW not found\n");
3149 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
3150 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3151 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3152 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3154 len
= GetSystemDirectoryW( file_name
, file_name_size
);
3155 ok(len
== file_name_size
- 1,
3156 "GetSystemDirectoryW returned %u, expected %u.\n",
3157 len
, file_name_size
- 1);
3159 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3160 ok(len
, "GetVolumePathNameW failed.\n");
3162 len
= lstrlenW( volume_prefix
);
3163 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3164 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3165 expected
[file_name_size
- len
- 1] = '\0';
3167 /* A bit more than we actually need, but it keeps the calculation simple. */
3168 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3169 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3171 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
3172 h
= CreateFileW( file_name
, GENERIC_READ
,
3173 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3174 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3175 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
3176 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3178 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileAllInformation
);
3179 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3180 hr
, STATUS_INFO_LENGTH_MISMATCH
);
3182 memset( info
, 0xcc, info_size
);
3183 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileAllInformation
);
3184 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3185 hr
, STATUS_BUFFER_OVERFLOW
);
3186 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#x, expected %#x.\n",
3187 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
3188 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3189 "info->NameInformation.FileNameLength is %u\n", info
->NameInformation
.FileNameLength
);
3190 ok(info
->NameInformation
.FileName
[2] == 0xcccc,
3191 "info->NameInformation.FileName[2] is %#x, expected 0xcccc.\n", info
->NameInformation
.FileName
[2]);
3192 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
3193 "info->NameInformation.FileName[1] is %p, expected %p.\n",
3194 CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
3195 ok(io
.Information
== sizeof(*info
), "io.Information is %lu\n", io
.Information
);
3197 memset( info
, 0xcc, info_size
);
3198 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3199 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3200 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#x, expected %#x.\n", U(io
).Status
, STATUS_SUCCESS
);
3201 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3202 "info->NameInformation.FileNameLength is %u\n", info
->NameInformation
.FileNameLength
);
3203 ok(info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] == 0xcccc,
3204 "info->NameInformation.FileName[len] is %#x, expected 0xcccc.\n",
3205 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)]);
3206 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3207 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
),
3208 "info->NameInformation.FileName is %s, expected %s.\n",
3209 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3210 ok(io
.Information
== FIELD_OFFSET(FILE_ALL_INFORMATION
, NameInformation
.FileName
)
3211 + info
->NameInformation
.FileNameLength
,
3212 "io.Information is %lu\n", io
.Information
);
3215 HeapFree( GetProcessHeap(), 0, info
);
3216 HeapFree( GetProcessHeap(), 0, expected
);
3217 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3219 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
3221 skip("Not running on WoW64, skipping test.\n");
3222 HeapFree( GetProcessHeap(), 0, file_name
);
3226 h
= CreateFileW( file_name
, GENERIC_READ
,
3227 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3228 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3229 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3230 HeapFree( GetProcessHeap(), 0, file_name
);
3232 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3233 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3234 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3236 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3237 ok(len
== file_name_size
- 1,
3238 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3239 len
, file_name_size
- 1);
3241 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3242 ok(len
, "GetVolumePathNameW failed.\n");
3244 len
= lstrlenW( volume_prefix
);
3245 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3246 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3247 expected
[file_name_size
- len
- 1] = '\0';
3249 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3250 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3252 memset( info
, 0xcc, info_size
);
3253 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3254 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3255 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3256 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
), "info->NameInformation.FileName is %s, expected %s.\n",
3257 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3260 HeapFree( GetProcessHeap(), 0, info
);
3261 HeapFree( GetProcessHeap(), 0, expected
);
3262 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3263 HeapFree( GetProcessHeap(), 0, file_name
);
3266 static void test_query_volume_information_file(void)
3270 WCHAR path
[MAX_PATH
];
3271 OBJECT_ATTRIBUTES attr
;
3273 UNICODE_STRING nameW
;
3274 FILE_FS_VOLUME_INFORMATION
*ffvi
;
3275 BYTE buf
[sizeof(FILE_FS_VOLUME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
3277 GetWindowsDirectoryW( path
, MAX_PATH
);
3278 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
3279 attr
.Length
= sizeof(attr
);
3280 attr
.RootDirectory
= 0;
3281 attr
.ObjectName
= &nameW
;
3282 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3283 attr
.SecurityDescriptor
= NULL
;
3284 attr
.SecurityQualityOfService
= NULL
;
3286 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
3287 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
3288 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
3289 pRtlFreeUnicodeString( &nameW
);
3291 ZeroMemory( buf
, sizeof(buf
) );
3292 U(io
).Status
= 0xdadadada;
3293 io
.Information
= 0xcacacaca;
3295 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsVolumeInformation
);
3297 ffvi
= (FILE_FS_VOLUME_INFORMATION
*)buf
;
3301 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", status
);
3302 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", U(io
).Status
);
3304 ok(io
.Information
== (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
3305 "expected %d, got %lu\n", (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
3308 ok(ffvi
->VolumeCreationTime
.QuadPart
!= 0, "Missing VolumeCreationTime\n");
3309 ok(ffvi
->VolumeSerialNumber
!= 0, "Missing VolumeSerialNumber\n");
3310 ok(ffvi
->SupportsObjects
== 1,"expected 1, got %d\n", ffvi
->SupportsObjects
);
3312 ok(ffvi
->VolumeLabelLength
== lstrlenW(ffvi
->VolumeLabel
) * sizeof(WCHAR
), "got %d\n", ffvi
->VolumeLabelLength
);
3314 trace("VolumeSerialNumber: %x VolumeLabelName: %s\n", ffvi
->VolumeSerialNumber
, wine_dbgstr_w(ffvi
->VolumeLabel
));
3319 static void test_query_attribute_information_file(void)
3323 WCHAR path
[MAX_PATH
];
3324 OBJECT_ATTRIBUTES attr
;
3326 UNICODE_STRING nameW
;
3327 FILE_FS_ATTRIBUTE_INFORMATION
*ffai
;
3328 BYTE buf
[sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
3330 GetWindowsDirectoryW( path
, MAX_PATH
);
3331 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
3332 attr
.Length
= sizeof(attr
);
3333 attr
.RootDirectory
= 0;
3334 attr
.ObjectName
= &nameW
;
3335 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3336 attr
.SecurityDescriptor
= NULL
;
3337 attr
.SecurityQualityOfService
= NULL
;
3339 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
3340 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
3341 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
3342 pRtlFreeUnicodeString( &nameW
);
3344 ZeroMemory( buf
, sizeof(buf
) );
3345 U(io
).Status
= 0xdadadada;
3346 io
.Information
= 0xcacacaca;
3348 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsAttributeInformation
);
3350 ffai
= (FILE_FS_ATTRIBUTE_INFORMATION
*)buf
;
3352 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", status
);
3353 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", U(io
).Status
);
3354 ok(ffai
->FileSystemAttribute
!= 0, "Missing FileSystemAttribute\n");
3355 ok(ffai
->MaximumComponentNameLength
!= 0, "Missing MaximumComponentNameLength\n");
3356 ok(ffai
->FileSystemNameLength
!= 0, "Missing FileSystemNameLength\n");
3358 trace("FileSystemAttribute: %x MaximumComponentNameLength: %x FileSystemName: %s\n",
3359 ffai
->FileSystemAttribute
, ffai
->MaximumComponentNameLength
,
3360 wine_dbgstr_wn(ffai
->FileSystemName
, ffai
->FileSystemNameLength
/ sizeof(WCHAR
)));
3365 static void test_NtCreateFile(void)
3367 static const struct test_data
3369 DWORD disposition
, attrib_in
, status
, result
, attrib_out
, needs_cleanup
;
3372 /* 0*/{ FILE_CREATE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3373 /* 1*/{ FILE_CREATE
, 0, STATUS_OBJECT_NAME_COLLISION
, 0, 0, TRUE
},
3374 /* 2*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3375 /* 3*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
3376 /* 4*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
3377 /* 5*/{ FILE_OPEN_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3378 /* 6*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
3379 /* 7*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3380 /* 8*/{ FILE_OPEN_IF
, 0, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3381 /* 9*/{ FILE_OVERWRITE
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
3382 /*10*/{ FILE_OVERWRITE
, 0, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
3383 /*11*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3384 /*12*/{ FILE_OVERWRITE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3385 /*13*/{ FILE_OVERWRITE_IF
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
3386 /*14*/{ FILE_OVERWRITE_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3387 /*15*/{ FILE_OVERWRITE_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3388 /*16*/{ FILE_SUPERSEDE
, 0, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3389 /*17*/{ FILE_SUPERSEDE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, TRUE
},
3390 /*18*/{ FILE_SUPERSEDE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
}
3392 static const WCHAR fooW
[] = {'f','o','o',0};
3395 WCHAR path
[MAX_PATH
];
3396 OBJECT_ATTRIBUTES attr
;
3398 UNICODE_STRING nameW
;
3401 GetTempPathW(MAX_PATH
, path
);
3402 GetTempFileNameW(path
, fooW
, 0, path
);
3404 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
3406 attr
.Length
= sizeof(attr
);
3407 attr
.RootDirectory
= NULL
;
3408 attr
.ObjectName
= &nameW
;
3409 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3410 attr
.SecurityDescriptor
= NULL
;
3411 attr
.SecurityQualityOfService
= NULL
;
3413 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3415 status
= pNtCreateFile(&handle
, GENERIC_READ
, &attr
, &io
, NULL
,
3416 td
[i
].attrib_in
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3417 td
[i
].disposition
, 0, NULL
, 0);
3419 ok(status
== td
[i
].status
, "%d: expected %#x got %#x\n", i
, td
[i
].status
, status
);
3423 ok(io
.Information
== td
[i
].result
,"%d: expected %#x got %#lx\n", i
, td
[i
].result
, io
.Information
);
3425 ret
= GetFileAttributesW(path
);
3426 ret
&= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
;
3427 /* FIXME: leave only 'else' case below once Wine is fixed */
3428 if (ret
!= td
[i
].attrib_out
)
3431 ok(ret
== td
[i
].attrib_out
, "%d: expected %#x got %#x\n", i
, td
[i
].attrib_out
, ret
);
3432 SetFileAttributesW(path
, td
[i
].attrib_out
);
3435 ok(ret
== td
[i
].attrib_out
, "%d: expected %#x got %#x\n", i
, td
[i
].attrib_out
, ret
);
3437 CloseHandle(handle
);
3440 if (td
[i
].needs_cleanup
)
3442 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3447 pRtlFreeUnicodeString( &nameW
);
3448 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3449 DeleteFileW( path
);
3452 static void test_read_write(void)
3454 static const char contents
[14] = "1234567890abcd";
3458 IO_STATUS_BLOCK iob
;
3459 DWORD ret
, bytes
, status
, off
;
3460 LARGE_INTEGER offset
;
3464 iob
.Information
= -1;
3465 offset
.QuadPart
= 0;
3466 status
= pNtReadFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3467 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3468 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3469 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3472 iob
.Information
= -1;
3473 offset
.QuadPart
= 0;
3474 status
= pNtWriteFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3475 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3476 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3477 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3479 hfile
= create_temp_file(0);
3483 iob
.Information
= -1;
3484 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3485 ok(status
== STATUS_INVALID_USER_BUFFER
, "expected STATUS_INVALID_USER_BUFFER, got %#x\n", status
);
3486 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3487 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3490 iob
.Information
= -1;
3491 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3492 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3493 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3494 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3497 iob
.Information
= -1;
3498 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, 7, NULL
, NULL
);
3499 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3500 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3501 ok(iob
.Information
== 7, "expected 7, got %lu\n", iob
.Information
);
3503 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3506 iob
.Information
= -1;
3507 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
3508 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
+ 7, sizeof(contents
) - 7, &offset
, NULL
);
3509 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3510 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3511 ok(iob
.Information
== sizeof(contents
) - 7, "expected sizeof(contents)-7, got %lu\n", iob
.Information
);
3513 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3514 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3517 SetLastError(0xdeadbeef);
3518 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
3519 ok(!ret
, "ReadFile should fail\n");
3520 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
3521 ok(bytes
== 0, "bytes %u\n", bytes
);
3524 SetLastError(0xdeadbeef);
3525 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
3526 ok(ret
, "ReadFile error %d\n", GetLastError());
3527 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3528 ok(bytes
== 0, "bytes %u\n", bytes
);
3531 SetLastError(0xdeadbeef);
3532 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3533 ok(ret
, "ReadFile error %d\n", GetLastError());
3534 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3535 ok(bytes
== 0, "bytes %u\n", bytes
);
3537 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3540 SetLastError(0xdeadbeef);
3541 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3542 ok(ret
, "ReadFile error %d\n", GetLastError());
3543 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3544 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3546 for (i
= -20; i
< -1; i
++)
3548 if (i
== -2) continue;
3551 iob
.Information
= -1;
3552 offset
.QuadPart
= (LONGLONG
)i
;
3553 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
3554 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3555 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3556 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3559 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
3562 iob
.Information
= -1;
3563 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3564 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
3565 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3566 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3567 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
3569 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3570 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3573 iob
.Information
= -1;
3574 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3575 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3576 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3577 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3579 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3582 SetLastError(0xdeadbeef);
3583 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3584 ok(ret
, "ReadFile error %d\n", GetLastError());
3585 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3586 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3587 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
3589 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3590 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3592 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3595 SetLastError(0xdeadbeef);
3596 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
3597 ok(ret
, "WriteFile error %d\n", GetLastError());
3598 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3600 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3601 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3603 /* test reading beyond EOF */
3605 SetLastError(0xdeadbeef);
3606 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3607 ok(ret
, "ReadFile error %d\n", GetLastError());
3608 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3609 ok(bytes
== 0, "bytes %u\n", bytes
);
3612 SetLastError(0xdeadbeef);
3613 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
3614 ok(ret
, "ReadFile error %d\n", GetLastError());
3615 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3616 ok(bytes
== 0, "bytes %u\n", bytes
);
3619 SetLastError(0xdeadbeef);
3620 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, NULL
);
3621 ok(ret
, "ReadFile error %d\n", GetLastError());
3622 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3623 ok(bytes
== 0, "bytes %u\n", bytes
);
3625 S(U(ovl
)).Offset
= sizeof(contents
);
3626 S(U(ovl
)).OffsetHigh
= 0;
3628 ovl
.InternalHigh
= -1;
3631 SetLastError(0xdeadbeef);
3632 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
3633 ok(!ret
, "ReadFile should fail\n");
3634 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError());
3635 ok(bytes
== 0, "bytes %u\n", bytes
);
3636 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", ovl
.Internal
);
3637 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3639 S(U(ovl
)).Offset
= sizeof(contents
);
3640 S(U(ovl
)).OffsetHigh
= 0;
3642 ovl
.InternalHigh
= -1;
3645 SetLastError(0xdeadbeef);
3646 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
3647 ok(ret
, "ReadFile error %d\n", GetLastError());
3648 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3649 ok(bytes
== 0, "bytes %u\n", bytes
);
3650 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
3651 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3654 iob
.Information
= -1;
3655 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3656 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3657 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3658 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3661 iob
.Information
= -1;
3662 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, NULL
, NULL
);
3663 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3664 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3665 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3668 iob
.Information
= -1;
3669 offset
.QuadPart
= sizeof(contents
);
3670 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3671 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3672 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3673 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3676 iob
.Information
= -1;
3677 offset
.QuadPart
= sizeof(contents
);
3678 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
3679 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3680 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3681 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3684 iob
.Information
= -1;
3685 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3686 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3687 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3688 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3689 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3692 iob
.Information
= -1;
3693 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3694 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
3695 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3696 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3697 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3699 for (i
= -20; i
< 0; i
++)
3701 if (i
== -2) continue;
3704 iob
.Information
= -1;
3705 offset
.QuadPart
= (LONGLONG
)i
;
3706 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3707 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3708 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3709 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3712 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3715 SetLastError(0xdeadbeef);
3716 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3717 ok(ret
, "ReadFile error %d\n", GetLastError());
3718 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3719 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3721 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3722 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3725 iob
.Information
= -1;
3726 offset
.QuadPart
= 0;
3727 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3728 ok(status
== STATUS_SUCCESS
, "NtReadFile 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
), "expected sizeof(contents), got %lu\n", iob
.Information
);
3731 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3733 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3734 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3737 iob
.Information
= -1;
3738 offset
.QuadPart
= sizeof(contents
) - 4;
3739 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
3740 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3741 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3742 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
3744 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3745 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3748 iob
.Information
= -1;
3749 offset
.QuadPart
= 0;
3750 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3751 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3752 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3753 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
3754 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3755 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
3757 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3758 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3760 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
3761 S(U(ovl
)).OffsetHigh
= 0;
3764 SetLastError(0xdeadbeef);
3765 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
3766 ok(ret
, "WriteFile error %d\n", GetLastError());
3767 ok(bytes
== 4, "bytes %u\n", bytes
);
3769 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3770 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3772 S(U(ovl
)).Offset
= 0;
3773 S(U(ovl
)).OffsetHigh
= 0;
3775 ovl
.InternalHigh
= -1;
3778 SetLastError(0xdeadbeef);
3779 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
3780 ok(ret
, "ReadFile error %d\n", GetLastError());
3781 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3782 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
3783 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
3784 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3785 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
3787 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3788 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3792 hfile
= create_temp_file(FILE_FLAG_OVERLAPPED
);
3796 SetLastError(0xdeadbeef);
3797 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
3798 ok(!ret
, "ReadFile should fail\n");
3799 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
3800 ok(bytes
== 0, "bytes %u\n", bytes
);
3802 S(U(ovl
)).Offset
= 0;
3803 S(U(ovl
)).OffsetHigh
= 0;
3805 ovl
.InternalHigh
= -1;
3808 SetLastError(0xdeadbeef);
3809 /* ReadFile return value depends on Windows version and testing it is not practical */
3810 ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
3811 ok(bytes
== 0, "bytes %u\n", bytes
);
3812 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
3813 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3816 SetLastError(0xdeadbeef);
3817 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
3818 ok(!ret
, "WriteFile should fail\n");
3819 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3820 ok(bytes
== 0, "bytes %u\n", bytes
);
3823 iob
.Information
= -1;
3824 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), NULL
, NULL
);
3825 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#x\n", status
);
3826 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3827 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3829 for (i
= -20; i
< -1; i
++)
3832 iob
.Information
= -1;
3833 offset
.QuadPart
= (LONGLONG
)i
;
3834 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
3835 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3836 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3837 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3841 iob
.Information
= -1;
3842 offset
.QuadPart
= 0;
3843 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
3844 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
/* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
3845 if (status
== STATUS_PENDING
)
3847 ret
= WaitForSingleObject(hfile
, 3000);
3848 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
3850 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3851 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
3853 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3854 ok(off
== 0, "expected 0, got %u\n", off
);
3857 SetLastError(0xdeadbeef);
3858 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3859 ok(!ret
, "ReadFile should fail\n");
3860 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3861 ok(bytes
== 0, "bytes %u\n", bytes
);
3864 iob
.Information
= -1;
3865 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3866 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#x\n", status
);
3867 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3868 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3870 for (i
= -20; i
< 0; i
++)
3873 iob
.Information
= -1;
3874 offset
.QuadPart
= (LONGLONG
)i
;
3875 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3876 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3877 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3878 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3881 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3882 ok(off
== 0, "expected 0, got %u\n", off
);
3884 /* test reading beyond EOF */
3885 offset
.QuadPart
= sizeof(contents
);
3886 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
3887 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
3889 ovl
.InternalHigh
= -1;
3892 SetLastError(0xdeadbeef);
3893 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
3894 ok(!ret
, "ReadFile should fail\n");
3895 ret
= GetLastError();
3896 ok(ret
== ERROR_IO_PENDING
|| ret
== ERROR_HANDLE_EOF
/* before Vista */, "expected ERROR_IO_PENDING or ERROR_HANDLE_EOF, got %d\n", ret
);
3897 ok(bytes
== 0, "bytes %u\n", bytes
);
3899 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3900 ok(off
== 0, "expected 0, got %u\n", off
);
3902 if (ret
== ERROR_IO_PENDING
)
3905 SetLastError(0xdeadbeef);
3906 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
3907 ok(!ret
, "GetOverlappedResult should report FALSE\n");
3908 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError());
3909 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
3910 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", ovl
.Internal
);
3911 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3914 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3915 ok(off
== 0, "expected 0, got %u\n", off
);
3917 offset
.QuadPart
= sizeof(contents
);
3918 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
3919 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
3921 ovl
.InternalHigh
= -1;
3924 SetLastError(0xdeadbeef);
3925 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
3926 /* ReadFile return value depends on Windows version and testing it is not practical */
3928 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
3929 ret
= GetLastError();
3930 ok(bytes
== 0, "bytes %u\n", bytes
);
3932 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3933 ok(off
== 0, "expected 0, got %u\n", off
);
3935 if (ret
== ERROR_IO_PENDING
)
3938 SetLastError(0xdeadbeef);
3939 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
3940 ok(ret
, "GetOverlappedResult should report TRUE\n");
3941 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3942 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
3943 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
3944 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3947 offset
.QuadPart
= sizeof(contents
);
3948 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
3949 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
3951 ovl
.InternalHigh
= -1;
3954 SetLastError(0xdeadbeef);
3955 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, &ovl
);
3956 /* ReadFile return value depends on Windows version and testing it is not practical */
3958 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
3959 ret
= GetLastError();
3960 ok(bytes
== 0, "bytes %u\n", bytes
);
3962 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3963 ok(off
== 0, "expected 0, got %u\n", off
);
3965 if (ret
== ERROR_IO_PENDING
)
3968 SetLastError(0xdeadbeef);
3969 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
3970 ok(ret
, "GetOverlappedResult should report TRUE\n");
3971 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3972 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
3973 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
3974 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3978 iob
.Information
= -1;
3979 offset
.QuadPart
= sizeof(contents
);
3980 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3981 if (status
== STATUS_PENDING
)
3983 ret
= WaitForSingleObject(hfile
, 3000);
3984 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
3985 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3986 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3990 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3991 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3992 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3995 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3996 ok(off
== 0, "expected 0, got %u\n", off
);
3999 iob
.Information
= -1;
4000 offset
.QuadPart
= sizeof(contents
);
4001 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
4002 if (status
== STATUS_PENDING
)
4004 ret
= WaitForSingleObject(hfile
, 3000);
4005 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4006 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4007 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4011 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", status
);
4012 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4013 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4016 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4017 ok(off
== 0, "expected 0, got %u\n", off
);
4019 S(U(ovl
)).Offset
= 0;
4020 S(U(ovl
)).OffsetHigh
= 0;
4022 ovl
.InternalHigh
= -1;
4025 SetLastError(0xdeadbeef);
4026 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4027 /* ReadFile return value depends on Windows version and testing it is not practical */
4030 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4031 ok(bytes
== 0, "bytes %u\n", bytes
);
4033 else ok(bytes
== 14, "bytes %u\n", bytes
);
4034 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4035 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4037 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4038 ok(off
== 0, "expected 0, got %u\n", off
);
4041 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4042 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4043 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4044 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4045 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4046 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4048 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4049 ok(off
== 0, "expected 0, got %u\n", off
);
4051 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
4052 SetEndOfFile(hfile
);
4053 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4056 iob
.Information
= -1;
4057 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
4058 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
4059 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
/* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4060 if (status
== STATUS_PENDING
)
4062 ret
= WaitForSingleObject(hfile
, 3000);
4063 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4065 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4066 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
4068 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4069 ok(off
== 0, "expected 0, got %u\n", off
);
4072 iob
.Information
= -1;
4073 offset
.QuadPart
= 0;
4074 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4075 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4076 if (status
== STATUS_PENDING
)
4078 ret
= WaitForSingleObject(hfile
, 3000);
4079 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4081 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4082 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4084 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4085 ok(off
== 0, "expected 0, got %u\n", off
);
4087 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4088 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
4090 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4091 ok(off
== 0, "expected 0, got %u\n", off
);
4093 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
4094 S(U(ovl
)).OffsetHigh
= 0;
4096 ovl
.InternalHigh
= -1;
4099 SetLastError(0xdeadbeef);
4100 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
4101 /* WriteFile return value depends on Windows version and testing it is not practical */
4104 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4105 ok(bytes
== 0, "bytes %u\n", bytes
);
4106 ret
= WaitForSingleObject(hfile
, 3000);
4107 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4109 else ok(bytes
== 4, "bytes %u\n", bytes
);
4110 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4111 ok(ovl
.InternalHigh
== 4, "expected 4, got %lu\n", ovl
.InternalHigh
);
4113 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4114 ok(off
== 0, "expected 0, got %u\n", off
);
4117 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4118 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4119 ok(bytes
== 4, "bytes %u\n", bytes
);
4120 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4121 ok(ovl
.InternalHigh
== 4, "expected 4, got %lu\n", ovl
.InternalHigh
);
4123 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4124 ok(off
== 0, "expected 0, got %u\n", off
);
4126 S(U(ovl
)).Offset
= 0;
4127 S(U(ovl
)).OffsetHigh
= 0;
4129 ovl
.InternalHigh
= -1;
4132 SetLastError(0xdeadbeef);
4133 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4134 /* ReadFile return value depends on Windows version and testing it is not practical */
4137 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4138 ok(bytes
== 0, "bytes %u\n", bytes
);
4139 ret
= WaitForSingleObject(hfile
, 3000);
4140 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4142 else ok(bytes
== 14, "bytes %u\n", bytes
);
4143 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4144 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4146 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4147 ok(off
== 0, "expected 0, got %u\n", off
);
4150 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4151 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4152 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4153 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4154 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4155 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4156 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
4158 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4159 ok(off
== 0, "expected 0, got %u\n", off
);
4166 HMODULE hkernel32
= GetModuleHandleA("kernel32.dll");
4167 HMODULE hntdll
= GetModuleHandleA("ntdll.dll");
4170 skip("not running on NT, skipping test\n");
4174 pGetVolumePathNameW
= (void *)GetProcAddress(hkernel32
, "GetVolumePathNameW");
4175 pGetSystemWow64DirectoryW
= (void *)GetProcAddress(hkernel32
, "GetSystemWow64DirectoryW");
4177 pRtlFreeUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlFreeUnicodeString");
4178 pRtlInitUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlInitUnicodeString");
4179 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(hntdll
, "RtlDosPathNameToNtPathName_U");
4180 pRtlWow64EnableFsRedirectionEx
= (void *)GetProcAddress(hntdll
, "RtlWow64EnableFsRedirectionEx");
4181 pNtCreateMailslotFile
= (void *)GetProcAddress(hntdll
, "NtCreateMailslotFile");
4182 pNtCreateFile
= (void *)GetProcAddress(hntdll
, "NtCreateFile");
4183 pNtOpenFile
= (void *)GetProcAddress(hntdll
, "NtOpenFile");
4184 pNtDeleteFile
= (void *)GetProcAddress(hntdll
, "NtDeleteFile");
4185 pNtReadFile
= (void *)GetProcAddress(hntdll
, "NtReadFile");
4186 pNtWriteFile
= (void *)GetProcAddress(hntdll
, "NtWriteFile");
4187 pNtCancelIoFile
= (void *)GetProcAddress(hntdll
, "NtCancelIoFile");
4188 pNtCancelIoFileEx
= (void *)GetProcAddress(hntdll
, "NtCancelIoFileEx");
4189 pNtClose
= (void *)GetProcAddress(hntdll
, "NtClose");
4190 pNtCreateIoCompletion
= (void *)GetProcAddress(hntdll
, "NtCreateIoCompletion");
4191 pNtOpenIoCompletion
= (void *)GetProcAddress(hntdll
, "NtOpenIoCompletion");
4192 pNtQueryIoCompletion
= (void *)GetProcAddress(hntdll
, "NtQueryIoCompletion");
4193 pNtRemoveIoCompletion
= (void *)GetProcAddress(hntdll
, "NtRemoveIoCompletion");
4194 pNtSetIoCompletion
= (void *)GetProcAddress(hntdll
, "NtSetIoCompletion");
4195 pNtSetInformationFile
= (void *)GetProcAddress(hntdll
, "NtSetInformationFile");
4196 pNtQueryInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryInformationFile");
4197 pNtQueryDirectoryFile
= (void *)GetProcAddress(hntdll
, "NtQueryDirectoryFile");
4198 pNtQueryVolumeInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryVolumeInformationFile");
4199 pNtQueryFullAttributesFile
= (void *)GetProcAddress(hntdll
, "NtQueryFullAttributesFile");
4202 test_NtCreateFile();
4209 test_iocompletion();
4210 test_file_basic_information();
4211 test_file_all_information();
4212 test_file_both_information();
4213 test_file_name_information();
4214 test_file_full_size_information();
4215 test_file_all_name_information();
4216 test_file_rename_information();
4217 test_file_link_information();
4218 test_file_disposition_information();
4219 test_query_volume_information_file();
4220 test_query_attribute_information_file();