1 /* Unit test suite for Ntdll file functions 2 * 3 * Copyright 2007 Jeff Latimer 4 * Copyright 2007 Andrey Turkin 5 * Copyright 2008 Jeff Zaroyko 6 * Copyright 2011 Dmitry Timoshkov 7 * 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. 12 * 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. 17 * 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 21 * 22 * NOTES 23 * We use function pointers here as there is no import library for NTDLL on 24 * windows. 25 */ 26 27 #include <stdio.h> 28 #include <stdarg.h> 29 30 #include "ntstatus.h" 31 /* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro 32 * definition errors when we get to winnt.h 33 */ 34 #define WIN32_NO_STATUS 35 36 #include "wine/test.h" 37 #include "winternl.h" 38 #include "winuser.h" 39 #include "winioctl.h" 40 #ifndef __REACTOS__ 41 #include "ntifs.h" 42 #else 43 /* FIXME: Inspect */ 44 typedef struct _REPARSE_DATA_BUFFER { 45 ULONG ReparseTag; 46 USHORT ReparseDataLength; 47 USHORT Reserved; 48 _ANONYMOUS_UNION union { 49 struct { 50 USHORT SubstituteNameOffset; 51 USHORT SubstituteNameLength; 52 USHORT PrintNameOffset; 53 USHORT PrintNameLength; 54 ULONG Flags; 55 WCHAR PathBuffer[1]; 56 } SymbolicLinkReparseBuffer; 57 struct { 58 USHORT SubstituteNameOffset; 59 USHORT SubstituteNameLength; 60 USHORT PrintNameOffset; 61 USHORT PrintNameLength; 62 WCHAR PathBuffer[1]; 63 } MountPointReparseBuffer; 64 struct { 65 UCHAR DataBuffer[1]; 66 } GenericReparseBuffer; 67 } DUMMYUNIONNAME; 68 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; 69 #endif 70 71 #ifndef IO_COMPLETION_ALL_ACCESS 72 #define IO_COMPLETION_ALL_ACCESS 0x001F0003 73 #endif 74 75 static BOOL (WINAPI * pGetVolumePathNameW)(LPCWSTR, LPWSTR, DWORD); 76 static UINT (WINAPI *pGetSystemWow64DirectoryW)( LPWSTR, UINT ); 77 78 static VOID (WINAPI *pRtlFreeUnicodeString)( PUNICODE_STRING ); 79 static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR ); 80 static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* ); 81 static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG, ULONG * ); 82 83 static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, 84 ULONG, ULONG, ULONG, PLARGE_INTEGER ); 85 static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG); 86 static NTSTATUS (WINAPI *pNtOpenFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,ULONG,ULONG); 87 static NTSTATUS (WINAPI *pNtDeleteFile)(POBJECT_ATTRIBUTES ObjectAttributes); 88 static NTSTATUS (WINAPI *pNtReadFile)(HANDLE hFile, HANDLE hEvent, 89 PIO_APC_ROUTINE apc, void* apc_user, 90 PIO_STATUS_BLOCK io_status, void* buffer, ULONG length, 91 PLARGE_INTEGER offset, PULONG key); 92 static NTSTATUS (WINAPI *pNtWriteFile)(HANDLE hFile, HANDLE hEvent, 93 PIO_APC_ROUTINE apc, void* apc_user, 94 PIO_STATUS_BLOCK io_status, 95 const void* buffer, ULONG length, 96 PLARGE_INTEGER offset, PULONG key); 97 static NTSTATUS (WINAPI *pNtCancelIoFile)(HANDLE hFile, PIO_STATUS_BLOCK io_status); 98 static NTSTATUS (WINAPI *pNtCancelIoFileEx)(HANDLE hFile, PIO_STATUS_BLOCK iosb, PIO_STATUS_BLOCK io_status); 99 static NTSTATUS (WINAPI *pNtClose)( PHANDLE ); 100 static NTSTATUS (WINAPI *pNtFsControlFile) (HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, PVOID apc_context, PIO_STATUS_BLOCK io, ULONG code, PVOID in_buffer, ULONG in_size, PVOID out_buffer, ULONG out_size); 101 102 static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG); 103 static NTSTATUS (WINAPI *pNtOpenIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); 104 static NTSTATUS (WINAPI *pNtQueryIoCompletion)(HANDLE, IO_COMPLETION_INFORMATION_CLASS, PVOID, ULONG, PULONG); 105 static NTSTATUS (WINAPI *pNtRemoveIoCompletion)(HANDLE, PULONG_PTR, PULONG_PTR, PIO_STATUS_BLOCK, PLARGE_INTEGER); 106 static NTSTATUS (WINAPI *pNtSetIoCompletion)(HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T); 107 static NTSTATUS (WINAPI *pNtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); 108 static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); 109 static NTSTATUS (WINAPI *pNtQueryDirectoryFile)(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK, 110 PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN); 111 static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS); 112 static NTSTATUS (WINAPI *pNtQueryFullAttributesFile)(const OBJECT_ATTRIBUTES*, FILE_NETWORK_OPEN_INFORMATION*); 113 static NTSTATUS (WINAPI *pNtFlushBuffersFile)(HANDLE, IO_STATUS_BLOCK*); 114 static NTSTATUS (WINAPI *pNtQueryEaFile)(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,BOOLEAN,PVOID,ULONG,PULONG,BOOLEAN); 115 116 static inline BOOL is_signaled( HANDLE obj ) 117 { 118 return WaitForSingleObject( obj, 0 ) == WAIT_OBJECT_0; 119 } 120 121 #define TEST_BUF_LEN 3 122 123 static HANDLE create_temp_file( ULONG flags ) 124 { 125 char path[MAX_PATH], buffer[MAX_PATH]; 126 HANDLE handle; 127 128 GetTempPathA( MAX_PATH, path ); 129 GetTempFileNameA( path, "foo", 0, buffer ); 130 handle = CreateFileA(buffer, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 131 flags | FILE_FLAG_DELETE_ON_CLOSE, 0); 132 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 133 return (handle == INVALID_HANDLE_VALUE) ? 0 : handle; 134 } 135 136 #define CVALUE_FIRST 0xfffabbcc 137 #define CKEY_FIRST 0x1030341 138 #define CKEY_SECOND 0x132E46 139 140 static ULONG_PTR completionKey; 141 static IO_STATUS_BLOCK ioSb; 142 static ULONG_PTR completionValue; 143 144 static ULONG get_pending_msgs(HANDLE h) 145 { 146 NTSTATUS res; 147 ULONG a, req; 148 149 res = pNtQueryIoCompletion( h, IoCompletionBasicInformation, &a, sizeof(a), &req ); 150 ok( res == STATUS_SUCCESS, "NtQueryIoCompletion failed: %x\n", res ); 151 if (res != STATUS_SUCCESS) return -1; 152 ok( req == sizeof(a), "Unexpected response size: %x\n", req ); 153 return a; 154 } 155 156 static BOOL get_msg(HANDLE h) 157 { 158 LARGE_INTEGER timeout = {{-10000000*3}}; 159 DWORD res = pNtRemoveIoCompletion( h, &completionKey, &completionValue, &ioSb, &timeout); 160 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %x\n", res ); 161 if (res != STATUS_SUCCESS) 162 { 163 completionKey = completionValue = 0; 164 memset(&ioSb, 0, sizeof(ioSb)); 165 return FALSE; 166 } 167 return TRUE; 168 } 169 170 171 static void WINAPI apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved ) 172 { 173 int *count = arg; 174 175 trace( "apc called block %p iosb.status %x iosb.info %lu\n", 176 iosb, U(*iosb).Status, iosb->Information ); 177 (*count)++; 178 ok( !reserved, "reserved is not 0: %x\n", reserved ); 179 } 180 181 static void create_file_test(void) 182 { 183 static const WCHAR notepadW[] = {'n','o','t','e','p','a','d','.','e','x','e',0}; 184 static const WCHAR systemrootW[] = {'\\','S','y','s','t','e','m','R','o','o','t', 185 '\\','f','a','i','l','i','n','g',0}; 186 static const WCHAR systemrootExplorerW[] = {'\\','S','y','s','t','e','m','R','o','o','t', 187 '\\','e','x','p','l','o','r','e','r','.','e','x','e',0}; 188 static const WCHAR questionmarkInvalidNameW[] = {'a','f','i','l','e','?',0}; 189 static const WCHAR pipeInvalidNameW[] = {'a','|','b',0}; 190 static const WCHAR pathInvalidNtW[] = {'\\','\\','?','\\',0}; 191 static const WCHAR pathInvalidNt2W[] = {'\\','?','?','\\',0}; 192 static const WCHAR pathInvalidDosW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0}; 193 static const char testdata[] = "Hello World"; 194 static const WCHAR sepW[] = {'\\',0}; 195 FILE_NETWORK_OPEN_INFORMATION info; 196 NTSTATUS status; 197 HANDLE dir, file; 198 WCHAR path[MAX_PATH], temp[MAX_PATH]; 199 OBJECT_ATTRIBUTES attr; 200 IO_STATUS_BLOCK io; 201 UNICODE_STRING nameW; 202 LARGE_INTEGER offset; 203 char buf[32]; 204 DWORD ret; 205 206 GetCurrentDirectoryW( MAX_PATH, path ); 207 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL ); 208 attr.Length = sizeof(attr); 209 attr.RootDirectory = 0; 210 attr.ObjectName = &nameW; 211 attr.Attributes = OBJ_CASE_INSENSITIVE; 212 attr.SecurityDescriptor = NULL; 213 attr.SecurityQualityOfService = NULL; 214 215 /* try various open modes and options on directories */ 216 status = pNtCreateFile( &dir, GENERIC_READ|GENERIC_WRITE, &attr, &io, NULL, 0, 217 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE, NULL, 0 ); 218 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 219 220 U(io).Status = 0xdeadbeef; 221 offset.QuadPart = 0; 222 status = pNtReadFile( dir, NULL, NULL, NULL, &io, buf, sizeof(buf), &offset, NULL ); 223 ok( status == STATUS_INVALID_DEVICE_REQUEST || status == STATUS_PENDING, "NtReadFile error %08x\n", status ); 224 if (status == STATUS_PENDING) 225 { 226 ret = WaitForSingleObject( dir, 1000 ); 227 ok( ret == WAIT_OBJECT_0, "WaitForSingleObject error %u\n", ret ); 228 ok( U(io).Status == STATUS_INVALID_DEVICE_REQUEST, 229 "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io).Status ); 230 } 231 232 U(io).Status = 0xdeadbeef; 233 offset.QuadPart = 0; 234 status = pNtWriteFile( dir, NULL, NULL, NULL, &io, testdata, sizeof(testdata), &offset, NULL); 235 todo_wine 236 ok( status == STATUS_INVALID_DEVICE_REQUEST || status == STATUS_PENDING, "NtWriteFile error %08x\n", status ); 237 if (status == STATUS_PENDING) 238 { 239 ret = WaitForSingleObject( dir, 1000 ); 240 ok( ret == WAIT_OBJECT_0, "WaitForSingleObject error %u\n", ret ); 241 ok( U(io).Status == STATUS_INVALID_DEVICE_REQUEST, 242 "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io).Status ); 243 } 244 245 CloseHandle( dir ); 246 247 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 248 FILE_CREATE, FILE_DIRECTORY_FILE, NULL, 0 ); 249 ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_ACCESS_DENIED, 250 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 251 252 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 253 FILE_OPEN_IF, FILE_DIRECTORY_FILE, NULL, 0 ); 254 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 255 CloseHandle( dir ); 256 257 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 258 FILE_SUPERSEDE, FILE_DIRECTORY_FILE, NULL, 0 ); 259 ok( status == STATUS_INVALID_PARAMETER, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 260 261 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 262 FILE_OVERWRITE, FILE_DIRECTORY_FILE, NULL, 0 ); 263 ok( status == STATUS_INVALID_PARAMETER, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 264 265 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 266 FILE_OVERWRITE_IF, FILE_DIRECTORY_FILE, NULL, 0 ); 267 ok( status == STATUS_INVALID_PARAMETER, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 268 269 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 270 FILE_OPEN, 0, NULL, 0 ); 271 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 272 CloseHandle( dir ); 273 274 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 275 FILE_CREATE, 0, NULL, 0 ); 276 ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_ACCESS_DENIED, 277 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 278 279 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 280 FILE_OPEN_IF, 0, NULL, 0 ); 281 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 282 CloseHandle( dir ); 283 284 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 285 FILE_SUPERSEDE, 0, NULL, 0 ); 286 ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_ACCESS_DENIED, 287 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 288 289 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 290 FILE_OVERWRITE, 0, NULL, 0 ); 291 ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_ACCESS_DENIED, 292 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 293 294 status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 295 FILE_OVERWRITE_IF, 0, NULL, 0 ); 296 ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_ACCESS_DENIED, 297 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 298 299 pRtlFreeUnicodeString( &nameW ); 300 301 pRtlInitUnicodeString( &nameW, systemrootW ); 302 attr.Length = sizeof(attr); 303 attr.RootDirectory = NULL; 304 attr.ObjectName = &nameW; 305 attr.Attributes = OBJ_CASE_INSENSITIVE; 306 attr.SecurityDescriptor = NULL; 307 attr.SecurityQualityOfService = NULL; 308 dir = NULL; 309 status = pNtCreateFile( &dir, FILE_APPEND_DATA, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, 0, 310 FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); 311 todo_wine 312 ok( status == STATUS_INVALID_PARAMETER, 313 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 314 315 /* Invalid chars in file/dirnames */ 316 pRtlDosPathNameToNtPathName_U(questionmarkInvalidNameW, &nameW, NULL, NULL); 317 attr.ObjectName = &nameW; 318 status = pNtCreateFile(&dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0, 319 FILE_SHARE_READ, FILE_CREATE, 320 FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); 321 ok(status == STATUS_OBJECT_NAME_INVALID, 322 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status); 323 324 status = pNtCreateFile(&file, GENERIC_WRITE|SYNCHRONIZE, &attr, &io, NULL, 0, 325 0, FILE_CREATE, 326 FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); 327 ok(status == STATUS_OBJECT_NAME_INVALID, 328 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status); 329 pRtlFreeUnicodeString(&nameW); 330 331 pRtlDosPathNameToNtPathName_U(pipeInvalidNameW, &nameW, NULL, NULL); 332 attr.ObjectName = &nameW; 333 status = pNtCreateFile(&dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0, 334 FILE_SHARE_READ, FILE_CREATE, 335 FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); 336 ok(status == STATUS_OBJECT_NAME_INVALID, 337 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status); 338 339 status = pNtCreateFile(&file, GENERIC_WRITE|SYNCHRONIZE, &attr, &io, NULL, 0, 340 0, FILE_CREATE, 341 FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); 342 ok(status == STATUS_OBJECT_NAME_INVALID, 343 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status); 344 pRtlFreeUnicodeString(&nameW); 345 346 pRtlInitUnicodeString( &nameW, pathInvalidNtW ); 347 status = pNtCreateFile( &dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0, 348 FILE_SHARE_READ, FILE_CREATE, 349 FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); 350 ok( status == STATUS_OBJECT_NAME_INVALID, 351 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 352 353 status = pNtQueryFullAttributesFile( &attr, &info ); 354 todo_wine ok( status == STATUS_OBJECT_NAME_INVALID, 355 "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 356 357 pRtlInitUnicodeString( &nameW, pathInvalidNt2W ); 358 status = pNtCreateFile( &dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0, 359 FILE_SHARE_READ, FILE_CREATE, 360 FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); 361 ok( status == STATUS_OBJECT_NAME_INVALID, 362 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 363 364 status = pNtQueryFullAttributesFile( &attr, &info ); 365 ok( status == STATUS_OBJECT_NAME_INVALID, 366 "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 367 368 pRtlInitUnicodeString( &nameW, pathInvalidDosW ); 369 status = pNtCreateFile( &dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0, 370 FILE_SHARE_READ, FILE_CREATE, 371 FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); 372 ok( status == STATUS_OBJECT_NAME_INVALID, 373 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 374 375 status = pNtQueryFullAttributesFile( &attr, &info ); 376 ok( status == STATUS_OBJECT_NAME_INVALID, 377 "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 378 379 GetWindowsDirectoryW( path, MAX_PATH ); 380 path[2] = 0; 381 ok( QueryDosDeviceW( path, temp, MAX_PATH ), 382 "QueryDosDeviceW failed with error %u\n", GetLastError() ); 383 lstrcatW( temp, sepW ); 384 lstrcatW( temp, path+3 ); 385 lstrcatW( temp, sepW ); 386 lstrcatW( temp, notepadW ); 387 388 pRtlInitUnicodeString( &nameW, temp ); 389 status = pNtQueryFullAttributesFile( &attr, &info ); 390 ok( status == STATUS_SUCCESS, 391 "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 392 393 pRtlInitUnicodeString( &nameW, systemrootExplorerW ); 394 status = pNtQueryFullAttributesFile( &attr, &info ); 395 ok( status == STATUS_SUCCESS, 396 "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 397 } 398 399 static void open_file_test(void) 400 { 401 static const char testdata[] = "Hello World"; 402 static WCHAR fooW[] = {'f','o','o',0}; 403 NTSTATUS status; 404 HANDLE dir, root, handle, file; 405 WCHAR path[MAX_PATH], tmpfile[MAX_PATH]; 406 BYTE data[1024]; 407 OBJECT_ATTRIBUTES attr; 408 IO_STATUS_BLOCK io; 409 UNICODE_STRING nameW; 410 UINT i, len; 411 BOOL ret, restart = TRUE; 412 DWORD numbytes; 413 414 len = GetWindowsDirectoryW( path, MAX_PATH ); 415 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL ); 416 attr.Length = sizeof(attr); 417 attr.RootDirectory = 0; 418 attr.ObjectName = &nameW; 419 attr.Attributes = OBJ_CASE_INSENSITIVE; 420 attr.SecurityDescriptor = NULL; 421 attr.SecurityQualityOfService = NULL; 422 status = pNtOpenFile( &dir, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io, 423 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT ); 424 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 425 pRtlFreeUnicodeString( &nameW ); 426 427 path[3] = 0; /* root of the drive */ 428 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL ); 429 status = pNtOpenFile( &root, GENERIC_READ, &attr, &io, 430 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE ); 431 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 432 pRtlFreeUnicodeString( &nameW ); 433 434 /* test opening system dir with RootDirectory set to windows dir */ 435 GetSystemDirectoryW( path, MAX_PATH ); 436 while (path[len] == '\\') len++; 437 nameW.Buffer = path + len; 438 nameW.Length = lstrlenW(path + len) * sizeof(WCHAR); 439 attr.RootDirectory = dir; 440 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io, 441 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE ); 442 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 443 CloseHandle( handle ); 444 445 /* try uppercase name */ 446 for (i = len; path[i]; i++) if (path[i] >= 'a' && path[i] <= 'z') path[i] -= 'a' - 'A'; 447 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io, 448 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE ); 449 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 450 CloseHandle( handle ); 451 452 /* try with leading backslash */ 453 nameW.Buffer--; 454 nameW.Length += sizeof(WCHAR); 455 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io, 456 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE ); 457 ok( status == STATUS_INVALID_PARAMETER || 458 status == STATUS_OBJECT_NAME_INVALID || 459 status == STATUS_OBJECT_PATH_SYNTAX_BAD, 460 "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 461 if (!status) CloseHandle( handle ); 462 463 /* try with empty name */ 464 nameW.Length = 0; 465 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io, 466 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE ); 467 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 468 CloseHandle( handle ); 469 470 /* try open by file id */ 471 472 while (!pNtQueryDirectoryFile( dir, NULL, NULL, NULL, &io, data, sizeof(data), 473 FileIdBothDirectoryInformation, TRUE, NULL, restart )) 474 { 475 FILE_ID_BOTH_DIRECTORY_INFORMATION *info = (FILE_ID_BOTH_DIRECTORY_INFORMATION *)data; 476 477 restart = FALSE; 478 479 if (!info->FileId.QuadPart) continue; 480 481 nameW.Buffer = (WCHAR *)&info->FileId; 482 nameW.Length = sizeof(info->FileId); 483 info->FileName[info->FileNameLength/sizeof(WCHAR)] = 0; 484 attr.RootDirectory = dir; 485 /* We skip 'open' files by not specifying FILE_SHARE_WRITE */ 486 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io, 487 FILE_SHARE_READ, 488 FILE_OPEN_BY_FILE_ID | 489 ((info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_DIRECTORY_FILE : 0) ); 490 ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED || status == STATUS_NOT_IMPLEMENTED || status == STATUS_SHARING_VIOLATION, 491 "open %s failed %x\n", wine_dbgstr_w(info->FileName), status ); 492 if (status == STATUS_NOT_IMPLEMENTED) 493 { 494 win_skip( "FILE_OPEN_BY_FILE_ID not supported\n" ); 495 break; 496 } 497 if (status == STATUS_SHARING_VIOLATION) 498 trace( "%s is currently open\n", wine_dbgstr_w(info->FileName) ); 499 if (!status) 500 { 501 BYTE buf[sizeof(FILE_ALL_INFORMATION) + MAX_PATH * sizeof(WCHAR)]; 502 503 if (!pNtQueryInformationFile( handle, &io, buf, sizeof(buf), FileAllInformation )) 504 { 505 FILE_ALL_INFORMATION *fai = (FILE_ALL_INFORMATION *)buf; 506 507 /* check that it's the same file/directory */ 508 509 /* don't check the size for directories */ 510 if (!(info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 511 ok( info->EndOfFile.QuadPart == fai->StandardInformation.EndOfFile.QuadPart, 512 "mismatched file size for %s\n", wine_dbgstr_w(info->FileName)); 513 514 ok( info->CreationTime.QuadPart == fai->BasicInformation.CreationTime.QuadPart, 515 "mismatched creation time for %s\n", wine_dbgstr_w(info->FileName)); 516 } 517 CloseHandle( handle ); 518 519 /* try same thing from drive root */ 520 attr.RootDirectory = root; 521 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io, 522 FILE_SHARE_READ|FILE_SHARE_WRITE, 523 FILE_OPEN_BY_FILE_ID | 524 ((info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_DIRECTORY_FILE : 0) ); 525 ok( status == STATUS_SUCCESS || status == STATUS_NOT_IMPLEMENTED, 526 "open %s failed %x\n", wine_dbgstr_w(info->FileName), status ); 527 if (!status) CloseHandle( handle ); 528 } 529 } 530 531 CloseHandle( dir ); 532 CloseHandle( root ); 533 534 GetTempPathW( MAX_PATH, path ); 535 GetTempFileNameW( path, fooW, 0, tmpfile ); 536 pRtlDosPathNameToNtPathName_U( tmpfile, &nameW, NULL, NULL ); 537 538 file = CreateFileW( tmpfile, FILE_WRITE_DATA, 0, NULL, CREATE_ALWAYS, 0, 0 ); 539 ok( file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError() ); 540 numbytes = 0xdeadbeef; 541 ret = WriteFile( file, testdata, sizeof(testdata) - 1, &numbytes, NULL ); 542 ok( ret, "WriteFile failed with error %u\n", GetLastError() ); 543 ok( numbytes == sizeof(testdata) - 1, "failed to write all data\n" ); 544 CloseHandle( file ); 545 546 attr.Length = sizeof(attr); 547 attr.RootDirectory = 0; 548 attr.ObjectName = &nameW; 549 attr.Attributes = OBJ_CASE_INSENSITIVE; 550 attr.SecurityDescriptor = NULL; 551 attr.SecurityQualityOfService = NULL; 552 status = pNtOpenFile( &file, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io, 553 FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT ); 554 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 555 pRtlFreeUnicodeString( &nameW ); 556 557 numbytes = 0xdeadbeef; 558 memset( data, 0, sizeof(data) ); 559 ret = ReadFile( file, data, sizeof(data), &numbytes, NULL ); 560 ok( ret, "ReadFile failed with error %u\n", GetLastError() ); 561 ok( numbytes == sizeof(testdata) - 1, "failed to read all data\n" ); 562 ok( !memcmp( data, testdata, sizeof(testdata) - 1 ), "testdata doesn't match\n" ); 563 564 nameW.Length = sizeof(fooW) - sizeof(WCHAR); 565 nameW.Buffer = fooW; 566 attr.RootDirectory = file; 567 attr.ObjectName = &nameW; 568 status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io, 569 FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT ); 570 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, 571 "expected STATUS_OBJECT_PATH_NOT_FOUND, got %08x\n", status ); 572 573 nameW.Length = 0; 574 nameW.Buffer = NULL; 575 attr.RootDirectory = file; 576 attr.ObjectName = &nameW; 577 status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io, 578 FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT ); 579 ok( !status, "open %s failed %x\n", wine_dbgstr_w(tmpfile), status ); 580 581 numbytes = SetFilePointer( file, 0, 0, FILE_CURRENT ); 582 ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes ); 583 numbytes = SetFilePointer( root, 0, 0, FILE_CURRENT ); 584 ok( numbytes == 0, "SetFilePointer returned %u\n", numbytes ); 585 586 numbytes = 0xdeadbeef; 587 memset( data, 0, sizeof(data) ); 588 ret = ReadFile( root, data, sizeof(data), &numbytes, NULL ); 589 ok( ret, "ReadFile failed with error %u\n", GetLastError() ); 590 ok( numbytes == sizeof(testdata) - 1, "failed to read all data\n" ); 591 ok( !memcmp( data, testdata, sizeof(testdata) - 1 ), "testdata doesn't match\n" ); 592 593 numbytes = SetFilePointer( file, 0, 0, FILE_CURRENT ); 594 ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes ); 595 numbytes = SetFilePointer( root, 0, 0, FILE_CURRENT ); 596 ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes ); 597 598 CloseHandle( file ); 599 CloseHandle( root ); 600 DeleteFileW( tmpfile ); 601 } 602 603 static void delete_file_test(void) 604 { 605 NTSTATUS ret; 606 OBJECT_ATTRIBUTES attr; 607 UNICODE_STRING nameW; 608 WCHAR pathW[MAX_PATH]; 609 WCHAR pathsubW[MAX_PATH]; 610 static const WCHAR testdirW[] = {'n','t','d','e','l','e','t','e','f','i','l','e',0}; 611 static const WCHAR subdirW[] = {'\\','s','u','b',0}; 612 613 ret = GetTempPathW(MAX_PATH, pathW); 614 if (!ret) 615 { 616 ok(0, "couldn't get temp dir\n"); 617 return; 618 } 619 if (ret + sizeof(testdirW)/sizeof(WCHAR)-1 + sizeof(subdirW)/sizeof(WCHAR)-1 >= MAX_PATH) 620 { 621 ok(0, "MAX_PATH exceeded in constructing paths\n"); 622 return; 623 } 624 625 lstrcatW(pathW, testdirW); 626 lstrcpyW(pathsubW, pathW); 627 lstrcatW(pathsubW, subdirW); 628 629 ret = CreateDirectoryW(pathW, NULL); 630 ok(ret == TRUE, "couldn't create directory ntdeletefile\n"); 631 if (!pRtlDosPathNameToNtPathName_U(pathW, &nameW, NULL, NULL)) 632 { 633 ok(0,"RtlDosPathNametoNtPathName_U failed\n"); 634 return; 635 } 636 637 attr.Length = sizeof(attr); 638 attr.RootDirectory = 0; 639 attr.Attributes = OBJ_CASE_INSENSITIVE; 640 attr.ObjectName = &nameW; 641 attr.SecurityDescriptor = NULL; 642 attr.SecurityQualityOfService = NULL; 643 644 /* test NtDeleteFile on an empty directory */ 645 ret = pNtDeleteFile(&attr); 646 ok(ret == STATUS_SUCCESS, "NtDeleteFile should succeed in removing an empty directory\n"); 647 ret = RemoveDirectoryW(pathW); 648 ok(ret == FALSE, "expected to fail removing directory, NtDeleteFile should have removed it\n"); 649 650 /* test NtDeleteFile on a non-empty directory */ 651 ret = CreateDirectoryW(pathW, NULL); 652 ok(ret == TRUE, "couldn't create directory ntdeletefile ?!\n"); 653 ret = CreateDirectoryW(pathsubW, NULL); 654 ok(ret == TRUE, "couldn't create directory subdir\n"); 655 ret = pNtDeleteFile(&attr); 656 ok(ret == STATUS_SUCCESS, "expected NtDeleteFile to ret STATUS_SUCCESS\n"); 657 ret = RemoveDirectoryW(pathsubW); 658 ok(ret == TRUE, "expected to remove directory ntdeletefile\\sub\n"); 659 ret = RemoveDirectoryW(pathW); 660 ok(ret == TRUE, "expected to remove directory ntdeletefile, NtDeleteFile failed.\n"); 661 662 pRtlFreeUnicodeString( &nameW ); 663 } 664 665 static void read_file_test(void) 666 { 667 const char text[] = "foobar"; 668 HANDLE handle; 669 IO_STATUS_BLOCK iosb; 670 NTSTATUS status; 671 int apc_count = 0; 672 char buffer[128]; 673 LARGE_INTEGER offset; 674 HANDLE event = CreateEventA( NULL, TRUE, FALSE, NULL ); 675 676 if (!(handle = create_temp_file( FILE_FLAG_OVERLAPPED ))) return; 677 apc_count = 0; 678 U(iosb).Status = 0xdeadbabe; 679 iosb.Information = 0xdeadbeef; 680 offset.QuadPart = 0; 681 ResetEvent( event ); 682 status = pNtWriteFile( handle, event, apc, &apc_count, &iosb, text, strlen(text), &offset, NULL ); 683 ok( status == STATUS_SUCCESS || status == STATUS_PENDING, "wrong status %x\n", status ); 684 if (status == STATUS_PENDING) WaitForSingleObject( event, 1000 ); 685 ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); 686 ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); 687 ok( is_signaled( event ), "event is not signaled\n" ); 688 ok( !apc_count, "apc was called\n" ); 689 SleepEx( 1, TRUE ); /* alertable sleep */ 690 ok( apc_count == 1, "apc was not called\n" ); 691 692 apc_count = 0; 693 U(iosb).Status = 0xdeadbabe; 694 iosb.Information = 0xdeadbeef; 695 offset.QuadPart = 0; 696 ResetEvent( event ); 697 status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, strlen(text) + 10, &offset, NULL ); 698 ok( status == STATUS_SUCCESS || 699 status == STATUS_PENDING, /* vista */ 700 "wrong status %x\n", status ); 701 if (status == STATUS_PENDING) WaitForSingleObject( event, 1000 ); 702 ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); 703 ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); 704 ok( is_signaled( event ), "event is not signaled\n" ); 705 ok( !apc_count, "apc was called\n" ); 706 SleepEx( 1, TRUE ); /* alertable sleep */ 707 ok( apc_count == 1, "apc was not called\n" ); 708 709 /* read beyond eof */ 710 apc_count = 0; 711 U(iosb).Status = 0xdeadbabe; 712 iosb.Information = 0xdeadbeef; 713 offset.QuadPart = strlen(text) + 2; 714 status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, 2, &offset, NULL ); 715 ok(status == STATUS_PENDING || status == STATUS_END_OF_FILE /* before Vista */, "expected STATUS_PENDING or STATUS_END_OF_FILE, got %#x\n", status); 716 if (status == STATUS_PENDING) /* vista */ 717 { 718 WaitForSingleObject( event, 1000 ); 719 ok( U(iosb).Status == STATUS_END_OF_FILE, "wrong status %x\n", U(iosb).Status ); 720 ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); 721 ok( is_signaled( event ), "event is not signaled\n" ); 722 ok( !apc_count, "apc was called\n" ); 723 SleepEx( 1, TRUE ); /* alertable sleep */ 724 ok( apc_count == 1, "apc was not called\n" ); 725 } 726 CloseHandle( handle ); 727 728 /* now a non-overlapped file */ 729 if (!(handle = create_temp_file(0))) return; 730 apc_count = 0; 731 U(iosb).Status = 0xdeadbabe; 732 iosb.Information = 0xdeadbeef; 733 offset.QuadPart = 0; 734 status = pNtWriteFile( handle, event, apc, &apc_count, &iosb, text, strlen(text), &offset, NULL ); 735 ok( status == STATUS_END_OF_FILE || 736 status == STATUS_SUCCESS || 737 status == STATUS_PENDING, /* vista */ 738 "wrong status %x\n", status ); 739 if (status == STATUS_PENDING) WaitForSingleObject( event, 1000 ); 740 ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); 741 ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); 742 ok( is_signaled( event ), "event is not signaled\n" ); 743 ok( !apc_count, "apc was called\n" ); 744 SleepEx( 1, TRUE ); /* alertable sleep */ 745 ok( apc_count == 1, "apc was not called\n" ); 746 747 apc_count = 0; 748 U(iosb).Status = 0xdeadbabe; 749 iosb.Information = 0xdeadbeef; 750 offset.QuadPart = 0; 751 ResetEvent( event ); 752 status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, strlen(text) + 10, &offset, NULL ); 753 ok( status == STATUS_SUCCESS, "wrong status %x\n", status ); 754 ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); 755 ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); 756 ok( is_signaled( event ), "event is not signaled\n" ); 757 ok( !apc_count, "apc was called\n" ); 758 SleepEx( 1, TRUE ); /* alertable sleep */ 759 todo_wine ok( !apc_count, "apc was called\n" ); 760 761 /* read beyond eof */ 762 apc_count = 0; 763 U(iosb).Status = 0xdeadbabe; 764 iosb.Information = 0xdeadbeef; 765 offset.QuadPart = strlen(text) + 2; 766 ResetEvent( event ); 767 status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, 2, &offset, NULL ); 768 ok( status == STATUS_END_OF_FILE, "wrong status %x\n", status ); 769 ok( U(iosb).Status == STATUS_END_OF_FILE, "wrong status %x\n", U(iosb).Status ); 770 ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); 771 ok( is_signaled( event ), "event is not signaled\n" ); 772 ok( !apc_count, "apc was called\n" ); 773 SleepEx( 1, TRUE ); /* alertable sleep */ 774 ok( !apc_count, "apc was called\n" ); 775 776 CloseHandle( handle ); 777 778 CloseHandle( event ); 779 } 780 781 static void append_file_test(void) 782 { 783 static const char text[6] = "foobar"; 784 HANDLE handle; 785 NTSTATUS status; 786 IO_STATUS_BLOCK iosb; 787 LARGE_INTEGER offset; 788 char path[MAX_PATH], buffer[MAX_PATH], buf[16]; 789 DWORD ret; 790 791 GetTempPathA( MAX_PATH, path ); 792 GetTempFileNameA( path, "foo", 0, buffer ); 793 794 handle = CreateFileA(buffer, FILE_WRITE_DATA, 0, NULL, CREATE_ALWAYS, 0, 0); 795 ok(handle != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 796 797 U(iosb).Status = -1; 798 iosb.Information = -1; 799 status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text, 2, NULL, NULL); 800 ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status); 801 ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status); 802 ok(iosb.Information == 2, "expected 2, got %lu\n", iosb.Information); 803 804 CloseHandle(handle); 805 806 /* It is possible to open a file with only FILE_APPEND_DATA access flags. 807 It matches the O_WRONLY|O_APPEND open() posix behavior */ 808 handle = CreateFileA(buffer, FILE_APPEND_DATA, 0, NULL, OPEN_EXISTING, 0, 0); 809 ok(handle != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 810 811 U(iosb).Status = -1; 812 iosb.Information = -1; 813 offset.QuadPart = 1; 814 status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 2, 2, &offset, NULL); 815 ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status); 816 ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status); 817 ok(iosb.Information == 2, "expected 2, got %lu\n", iosb.Information); 818 819 ret = SetFilePointer(handle, 0, NULL, FILE_CURRENT); 820 ok(ret == 4, "expected 4, got %u\n", ret); 821 822 U(iosb).Status = -1; 823 iosb.Information = -1; 824 offset.QuadPart = 3; 825 status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 4, 2, &offset, NULL); 826 ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status); 827 ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status); 828 ok(iosb.Information == 2, "expected 2, got %lu\n", iosb.Information); 829 830 ret = SetFilePointer(handle, 0, NULL, FILE_CURRENT); 831 ok(ret == 6, "expected 6, got %u\n", ret); 832 833 CloseHandle(handle); 834 835 handle = CreateFileA(buffer, FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA, 0, NULL, OPEN_EXISTING, 0, 0); 836 ok(handle != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 837 838 memset(buf, 0, sizeof(buf)); 839 U(iosb).Status = -1; 840 iosb.Information = -1; 841 offset.QuadPart = 0; 842 status = pNtReadFile(handle, 0, NULL, NULL, &iosb, buf, sizeof(buf), &offset, NULL); 843 ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status); 844 ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status); 845 ok(iosb.Information == 6, "expected 6, got %lu\n", iosb.Information); 846 buf[6] = 0; 847 ok(memcmp(buf, text, 6) == 0, "wrong file contents: %s\n", buf); 848 849 U(iosb).Status = -1; 850 iosb.Information = -1; 851 offset.QuadPart = 0; 852 status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 3, 3, &offset, NULL); 853 ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status); 854 ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status); 855 ok(iosb.Information == 3, "expected 3, got %lu\n", iosb.Information); 856 857 memset(buf, 0, sizeof(buf)); 858 U(iosb).Status = -1; 859 iosb.Information = -1; 860 offset.QuadPart = 0; 861 status = pNtReadFile(handle, 0, NULL, NULL, &iosb, buf, sizeof(buf), &offset, NULL); 862 ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status); 863 ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status); 864 ok(iosb.Information == 6, "expected 6, got %lu\n", iosb.Information); 865 buf[6] = 0; 866 ok(memcmp(buf, "barbar", 6) == 0, "wrong file contents: %s\n", buf); 867 868 CloseHandle(handle); 869 DeleteFileA(buffer); 870 } 871 872 static void nt_mailslot_test(void) 873 { 874 HANDLE hslot; 875 ACCESS_MASK DesiredAccess; 876 OBJECT_ATTRIBUTES attr; 877 878 ULONG CreateOptions; 879 ULONG MailslotQuota; 880 ULONG MaxMessageSize; 881 LARGE_INTEGER TimeOut; 882 IO_STATUS_BLOCK IoStatusBlock; 883 NTSTATUS rc; 884 UNICODE_STRING str; 885 WCHAR buffer1[] = { '\\','?','?','\\','M','A','I','L','S','L','O','T','\\', 886 'R',':','\\','F','R','E','D','\0' }; 887 888 TimeOut.QuadPart = -1; 889 890 pRtlInitUnicodeString(&str, buffer1); 891 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); 892 CreateOptions = MailslotQuota = MaxMessageSize = 0; 893 DesiredAccess = GENERIC_READ; 894 895 /* 896 * Check for NULL pointer handling 897 */ 898 rc = pNtCreateMailslotFile(NULL, DesiredAccess, 899 &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize, 900 &TimeOut); 901 ok( rc == STATUS_ACCESS_VIOLATION || 902 rc == STATUS_INVALID_PARAMETER, /* win2k3 */ 903 "rc = %x not STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER\n", rc); 904 905 /* 906 * Test to see if the Timeout can be NULL 907 */ 908 hslot = (HANDLE)0xdeadbeef; 909 rc = pNtCreateMailslotFile(&hslot, DesiredAccess, 910 &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize, 911 NULL); 912 ok( rc == STATUS_SUCCESS || 913 rc == STATUS_INVALID_PARAMETER, /* win2k3 */ 914 "rc = %x not STATUS_SUCCESS or STATUS_INVALID_PARAMETER\n", rc); 915 ok( hslot != 0, "Handle is invalid\n"); 916 917 if ( rc == STATUS_SUCCESS ) pNtClose(hslot); 918 919 /* 920 * Test a valid call 921 */ 922 InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); 923 rc = pNtCreateMailslotFile(&hslot, DesiredAccess, 924 &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize, 925 &TimeOut); 926 ok( rc == STATUS_SUCCESS, "Create MailslotFile failed rc = %x\n", rc); 927 ok( hslot != 0, "Handle is invalid\n"); 928 929 rc = pNtClose(hslot); 930 ok( rc == STATUS_SUCCESS, "NtClose failed\n"); 931 } 932 933 static void test_iocp_setcompletion(HANDLE h) 934 { 935 NTSTATUS res; 936 ULONG count; 937 SIZE_T size = 3; 938 939 if (sizeof(size) > 4) size |= (ULONGLONG)0x12345678 << 32; 940 941 res = pNtSetIoCompletion( h, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size ); 942 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %x\n", res ); 943 944 count = get_pending_msgs(h); 945 ok( count == 1, "Unexpected msg count: %d\n", count ); 946 947 if (get_msg(h)) 948 { 949 ok( completionKey == CKEY_FIRST, "Invalid completion key: %lx\n", completionKey ); 950 ok( ioSb.Information == size, "Invalid ioSb.Information: %lu\n", ioSb.Information ); 951 ok( U(ioSb).Status == STATUS_INVALID_DEVICE_REQUEST, "Invalid ioSb.Status: %x\n", U(ioSb).Status); 952 ok( completionValue == CVALUE_FIRST, "Invalid completion value: %lx\n", completionValue ); 953 } 954 955 count = get_pending_msgs(h); 956 ok( !count, "Unexpected msg count: %d\n", count ); 957 } 958 959 static void test_iocp_fileio(HANDLE h) 960 { 961 static const char pipe_name[] = "\\\\.\\pipe\\iocompletiontestnamedpipe"; 962 963 IO_STATUS_BLOCK iosb; 964 FILE_COMPLETION_INFORMATION fci = {h, CKEY_SECOND}; 965 HANDLE hPipeSrv, hPipeClt; 966 NTSTATUS res; 967 968 hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); 969 ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" ); 970 if (hPipeSrv != INVALID_HANDLE_VALUE ) 971 { 972 hPipeClt = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); 973 ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" ); 974 if (hPipeClt != INVALID_HANDLE_VALUE) 975 { 976 U(iosb).Status = 0xdeadbeef; 977 res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation ); 978 ok( res == STATUS_INVALID_PARAMETER, "Unexpected NtSetInformationFile on non-overlapped handle: %x\n", res ); 979 ok( U(iosb).Status == STATUS_INVALID_PARAMETER /* 98 */ || U(iosb).Status == 0xdeadbeef /* NT4+ */, 980 "Unexpected iosb.Status on non-overlapped handle: %x\n", U(iosb).Status ); 981 CloseHandle(hPipeClt); 982 } 983 CloseHandle( hPipeSrv ); 984 } 985 986 hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); 987 ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" ); 988 if (hPipeSrv == INVALID_HANDLE_VALUE ) 989 return; 990 991 hPipeClt = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); 992 ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" ); 993 if (hPipeClt != INVALID_HANDLE_VALUE) 994 { 995 OVERLAPPED o = {0,}; 996 BYTE send_buf[TEST_BUF_LEN], recv_buf[TEST_BUF_LEN]; 997 DWORD read; 998 long count; 999 1000 U(iosb).Status = 0xdeadbeef; 1001 res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation ); 1002 ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res ); 1003 ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status ); 1004 1005 memset( send_buf, 0, TEST_BUF_LEN ); 1006 memset( recv_buf, 0xde, TEST_BUF_LEN ); 1007 count = get_pending_msgs(h); 1008 ok( !count, "Unexpected msg count: %ld\n", count ); 1009 ReadFile( hPipeSrv, recv_buf, TEST_BUF_LEN, &read, &o); 1010 count = get_pending_msgs(h); 1011 ok( !count, "Unexpected msg count: %ld\n", count ); 1012 WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL ); 1013 1014 if (get_msg(h)) 1015 { 1016 ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); 1017 ok( ioSb.Information == 3, "Invalid ioSb.Information: %ld\n", ioSb.Information ); 1018 ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status); 1019 ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); 1020 ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n", recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] ); 1021 } 1022 count = get_pending_msgs(h); 1023 ok( !count, "Unexpected msg count: %ld\n", count ); 1024 1025 memset( send_buf, 0, TEST_BUF_LEN ); 1026 memset( recv_buf, 0xde, TEST_BUF_LEN ); 1027 WriteFile( hPipeClt, send_buf, 2, &read, NULL ); 1028 count = get_pending_msgs(h); 1029 ok( !count, "Unexpected msg count: %ld\n", count ); 1030 ReadFile( hPipeSrv, recv_buf, 2, &read, &o); 1031 count = get_pending_msgs(h); 1032 ok( count == 1, "Unexpected msg count: %ld\n", count ); 1033 if (get_msg(h)) 1034 { 1035 ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); 1036 ok( ioSb.Information == 2, "Invalid ioSb.Information: %ld\n", ioSb.Information ); 1037 ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status); 1038 ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); 1039 ok( !memcmp( send_buf, recv_buf, 2 ), "Receive buffer (%x %x) did not match send buffer (%x %x)\n", recv_buf[0], recv_buf[1], send_buf[0], send_buf[1] ); 1040 } 1041 1042 ReadFile( hPipeSrv, recv_buf, TEST_BUF_LEN, &read, &o); 1043 CloseHandle( hPipeSrv ); 1044 count = get_pending_msgs(h); 1045 ok( count == 1, "Unexpected msg count: %ld\n", count ); 1046 if (get_msg(h)) 1047 { 1048 ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); 1049 ok( ioSb.Information == 0, "Invalid ioSb.Information: %ld\n", ioSb.Information ); 1050 /* wine sends wrong status here */ 1051 ok( U(ioSb).Status == STATUS_PIPE_BROKEN, "Invalid ioSb.Status: %x\n", U(ioSb).Status); 1052 ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); 1053 } 1054 } 1055 1056 CloseHandle( hPipeClt ); 1057 1058 /* test associating a completion port with a handle after an async is queued */ 1059 hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); 1060 ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" ); 1061 if (hPipeSrv == INVALID_HANDLE_VALUE ) 1062 return; 1063 hPipeClt = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); 1064 ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" ); 1065 if (hPipeClt != INVALID_HANDLE_VALUE) 1066 { 1067 OVERLAPPED o = {0,}; 1068 BYTE send_buf[TEST_BUF_LEN], recv_buf[TEST_BUF_LEN]; 1069 int apc_count = 0; 1070 DWORD read; 1071 long count; 1072 1073 memset( send_buf, 0, TEST_BUF_LEN ); 1074 memset( recv_buf, 0xde, TEST_BUF_LEN ); 1075 count = get_pending_msgs(h); 1076 ok( !count, "Unexpected msg count: %ld\n", count ); 1077 ReadFile( hPipeSrv, recv_buf, TEST_BUF_LEN, &read, &o); 1078 1079 U(iosb).Status = 0xdeadbeef; 1080 res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation ); 1081 ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res ); 1082 ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status ); 1083 count = get_pending_msgs(h); 1084 ok( !count, "Unexpected msg count: %ld\n", count ); 1085 1086 WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL ); 1087 1088 if (get_msg(h)) 1089 { 1090 ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); 1091 ok( ioSb.Information == 3, "Invalid ioSb.Information: %ld\n", ioSb.Information ); 1092 ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status); 1093 ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); 1094 ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n", recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] ); 1095 } 1096 count = get_pending_msgs(h); 1097 ok( !count, "Unexpected msg count: %ld\n", count ); 1098 1099 /* using APCs on handle with associated completion port is not allowed */ 1100 res = NtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL ); 1101 ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %x\n", res); 1102 } 1103 1104 CloseHandle( hPipeSrv ); 1105 CloseHandle( hPipeClt ); 1106 1107 /* test associating a completion port with a handle after an async using APC is queued */ 1108 hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); 1109 ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" ); 1110 if (hPipeSrv == INVALID_HANDLE_VALUE ) 1111 return; 1112 hPipeClt = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); 1113 ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" ); 1114 if (hPipeClt != INVALID_HANDLE_VALUE) 1115 { 1116 BYTE send_buf[TEST_BUF_LEN], recv_buf[TEST_BUF_LEN]; 1117 int apc_count = 0; 1118 DWORD read; 1119 long count; 1120 1121 memset( send_buf, 0, TEST_BUF_LEN ); 1122 memset( recv_buf, 0xde, TEST_BUF_LEN ); 1123 count = get_pending_msgs(h); 1124 ok( !count, "Unexpected msg count: %ld\n", count ); 1125 1126 res = NtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL ); 1127 ok(res == STATUS_PENDING, "NtReadFile returned %x\n", res); 1128 1129 U(iosb).Status = 0xdeadbeef; 1130 res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation ); 1131 ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res ); 1132 ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status ); 1133 count = get_pending_msgs(h); 1134 ok( !count, "Unexpected msg count: %ld\n", count ); 1135 1136 WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL ); 1137 1138 ok(!apc_count, "apc_count = %u\n", apc_count); 1139 count = get_pending_msgs(h); 1140 ok( !count, "Unexpected msg count: %ld\n", count ); 1141 1142 SleepEx(1, TRUE); /* alertable sleep */ 1143 ok(apc_count == 1, "apc was not called\n"); 1144 count = get_pending_msgs(h); 1145 ok( !count, "Unexpected msg count: %ld\n", count ); 1146 1147 /* using APCs on handle with associated completion port is not allowed */ 1148 res = NtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL ); 1149 ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %x\n", res); 1150 } 1151 1152 CloseHandle( hPipeSrv ); 1153 CloseHandle( hPipeClt ); 1154 } 1155 1156 static void test_file_full_size_information(void) 1157 { 1158 IO_STATUS_BLOCK io; 1159 FILE_FS_FULL_SIZE_INFORMATION ffsi; 1160 FILE_FS_SIZE_INFORMATION fsi; 1161 HANDLE h; 1162 NTSTATUS res; 1163 1164 if(!(h = create_temp_file(0))) return ; 1165 1166 memset(&ffsi,0,sizeof(ffsi)); 1167 memset(&fsi,0,sizeof(fsi)); 1168 1169 /* Assume No Quota Settings configured on Wine Testbot */ 1170 res = pNtQueryVolumeInformationFile(h, &io, &ffsi, sizeof ffsi, FileFsFullSizeInformation); 1171 ok(res == STATUS_SUCCESS, "cannot get attributes, res %x\n", res); 1172 res = pNtQueryVolumeInformationFile(h, &io, &fsi, sizeof fsi, FileFsSizeInformation); 1173 ok(res == STATUS_SUCCESS, "cannot get attributes, res %x\n", res); 1174 1175 /* Test for FileFsSizeInformation */ 1176 ok(fsi.TotalAllocationUnits.QuadPart > 0, 1177 "[fsi] TotalAllocationUnits expected positive, got 0x%s\n", 1178 wine_dbgstr_longlong(fsi.TotalAllocationUnits.QuadPart)); 1179 ok(fsi.AvailableAllocationUnits.QuadPart > 0, 1180 "[fsi] AvailableAllocationUnits expected positive, got 0x%s\n", 1181 wine_dbgstr_longlong(fsi.AvailableAllocationUnits.QuadPart)); 1182 1183 /* Assume file system is NTFS */ 1184 ok(fsi.BytesPerSector == 512, "[fsi] BytesPerSector expected 512, got %d\n",fsi.BytesPerSector); 1185 ok(fsi.SectorsPerAllocationUnit == 8, "[fsi] SectorsPerAllocationUnit expected 8, got %d\n",fsi.SectorsPerAllocationUnit); 1186 1187 ok(ffsi.TotalAllocationUnits.QuadPart > 0, 1188 "[ffsi] TotalAllocationUnits expected positive, got negative value 0x%s\n", 1189 wine_dbgstr_longlong(ffsi.TotalAllocationUnits.QuadPart)); 1190 ok(ffsi.CallerAvailableAllocationUnits.QuadPart > 0, 1191 "[ffsi] CallerAvailableAllocationUnits expected positive, got negative value 0x%s\n", 1192 wine_dbgstr_longlong(ffsi.CallerAvailableAllocationUnits.QuadPart)); 1193 ok(ffsi.ActualAvailableAllocationUnits.QuadPart > 0, 1194 "[ffsi] ActualAvailableAllocationUnits expected positive, got negative value 0x%s\n", 1195 wine_dbgstr_longlong(ffsi.ActualAvailableAllocationUnits.QuadPart)); 1196 ok(ffsi.TotalAllocationUnits.QuadPart == fsi.TotalAllocationUnits.QuadPart, 1197 "[ffsi] TotalAllocationUnits error fsi:0x%s, ffsi:0x%s\n", 1198 wine_dbgstr_longlong(fsi.TotalAllocationUnits.QuadPart), 1199 wine_dbgstr_longlong(ffsi.TotalAllocationUnits.QuadPart)); 1200 ok(ffsi.CallerAvailableAllocationUnits.QuadPart == fsi.AvailableAllocationUnits.QuadPart, 1201 "[ffsi] CallerAvailableAllocationUnits error fsi:0x%s, ffsi: 0x%s\n", 1202 wine_dbgstr_longlong(fsi.AvailableAllocationUnits.QuadPart), 1203 wine_dbgstr_longlong(ffsi.CallerAvailableAllocationUnits.QuadPart)); 1204 1205 /* Assume file system is NTFS */ 1206 ok(ffsi.BytesPerSector == 512, "[ffsi] BytesPerSector expected 512, got %d\n",ffsi.BytesPerSector); 1207 ok(ffsi.SectorsPerAllocationUnit == 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %d\n",ffsi.SectorsPerAllocationUnit); 1208 1209 CloseHandle( h ); 1210 } 1211 1212 static void test_file_basic_information(void) 1213 { 1214 IO_STATUS_BLOCK io; 1215 FILE_BASIC_INFORMATION fbi; 1216 HANDLE h; 1217 int res; 1218 int attrib_mask = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NORMAL; 1219 1220 if (!(h = create_temp_file(0))) return; 1221 1222 /* Check default first */ 1223 memset(&fbi, 0, sizeof(fbi)); 1224 res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); 1225 ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res); 1226 ok ( (fbi.FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE, 1227 "attribute %x not expected\n", fbi.FileAttributes ); 1228 1229 /* Then SYSTEM */ 1230 /* Clear fbi to avoid setting times */ 1231 memset(&fbi, 0, sizeof(fbi)); 1232 fbi.FileAttributes = FILE_ATTRIBUTE_SYSTEM; 1233 U(io).Status = 0xdeadbeef; 1234 res = pNtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); 1235 ok ( res == STATUS_SUCCESS, "can't set system attribute, NtSetInformationFile returned %x\n", res ); 1236 ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %x\n", U(io).Status ); 1237 1238 memset(&fbi, 0, sizeof(fbi)); 1239 res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); 1240 ok ( res == STATUS_SUCCESS, "can't get attributes\n"); 1241 ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fbi.FileAttributes ); 1242 1243 /* Then HIDDEN */ 1244 memset(&fbi, 0, sizeof(fbi)); 1245 fbi.FileAttributes = FILE_ATTRIBUTE_HIDDEN; 1246 U(io).Status = 0xdeadbeef; 1247 res = pNtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); 1248 ok ( res == STATUS_SUCCESS, "can't set system attribute, NtSetInformationFile returned %x\n", res ); 1249 ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %x\n", U(io).Status ); 1250 1251 memset(&fbi, 0, sizeof(fbi)); 1252 res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); 1253 ok ( res == STATUS_SUCCESS, "can't get attributes\n"); 1254 ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fbi.FileAttributes ); 1255 1256 /* Check NORMAL last of all (to make sure we can clear attributes) */ 1257 memset(&fbi, 0, sizeof(fbi)); 1258 fbi.FileAttributes = FILE_ATTRIBUTE_NORMAL; 1259 U(io).Status = 0xdeadbeef; 1260 res = pNtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); 1261 ok ( res == STATUS_SUCCESS, "can't set normal attribute, NtSetInformationFile returned %x\n", res ); 1262 ok ( U(io).Status == STATUS_SUCCESS, "can't set normal attribute, io.Status is %x\n", U(io).Status ); 1263 1264 memset(&fbi, 0, sizeof(fbi)); 1265 res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); 1266 ok ( res == STATUS_SUCCESS, "can't get attributes\n"); 1267 todo_wine ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_NORMAL, "attribute %x not 0\n", fbi.FileAttributes ); 1268 1269 CloseHandle( h ); 1270 } 1271 1272 static void test_file_all_information(void) 1273 { 1274 IO_STATUS_BLOCK io; 1275 /* FileAllInformation, like FileNameInformation, has a variable-length pathname 1276 * buffer at the end. Vista objects with STATUS_BUFFER_OVERFLOW if you 1277 * don't leave enough room there. 1278 */ 1279 struct { 1280 FILE_ALL_INFORMATION fai; 1281 WCHAR buf[256]; 1282 } fai_buf; 1283 HANDLE h; 1284 int res; 1285 int attrib_mask = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NORMAL; 1286 1287 if (!(h = create_temp_file(0))) return; 1288 1289 /* Check default first */ 1290 res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation); 1291 ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res); 1292 ok ( (fai_buf.fai.BasicInformation.FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE, 1293 "attribute %x not expected\n", fai_buf.fai.BasicInformation.FileAttributes ); 1294 1295 /* Then SYSTEM */ 1296 /* Clear fbi to avoid setting times */ 1297 memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation)); 1298 fai_buf.fai.BasicInformation.FileAttributes = FILE_ATTRIBUTE_SYSTEM; 1299 U(io).Status = 0xdeadbeef; 1300 res = pNtSetInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation); 1301 ok ( res == STATUS_INVALID_INFO_CLASS || broken(res == STATUS_NOT_IMPLEMENTED), "shouldn't be able to set FileAllInformation, res %x\n", res); 1302 todo_wine ok ( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileAllInformation, io.Status is %x\n", U(io).Status); 1303 U(io).Status = 0xdeadbeef; 1304 res = pNtSetInformationFile(h, &io, &fai_buf.fai.BasicInformation, sizeof fai_buf.fai.BasicInformation, FileBasicInformation); 1305 ok ( res == STATUS_SUCCESS, "can't set system attribute, res: %x\n", res ); 1306 ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status: %x\n", U(io).Status ); 1307 1308 memset(&fai_buf.fai, 0, sizeof(fai_buf.fai)); 1309 res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation); 1310 ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res); 1311 ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fai_buf.fai.BasicInformation.FileAttributes ); 1312 1313 /* Then HIDDEN */ 1314 memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation)); 1315 fai_buf.fai.BasicInformation.FileAttributes = FILE_ATTRIBUTE_HIDDEN; 1316 U(io).Status = 0xdeadbeef; 1317 res = pNtSetInformationFile(h, &io, &fai_buf.fai.BasicInformation, sizeof fai_buf.fai.BasicInformation, FileBasicInformation); 1318 ok ( res == STATUS_SUCCESS, "can't set system attribute, res: %x\n", res ); 1319 ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status: %x\n", U(io).Status ); 1320 1321 memset(&fai_buf.fai, 0, sizeof(fai_buf.fai)); 1322 res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation); 1323 ok ( res == STATUS_SUCCESS, "can't get attributes\n"); 1324 ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fai_buf.fai.BasicInformation.FileAttributes ); 1325 1326 /* Check NORMAL last of all (to make sure we can clear attributes) */ 1327 memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation)); 1328 fai_buf.fai.BasicInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL; 1329 U(io).Status = 0xdeadbeef; 1330 res = pNtSetInformationFile(h, &io, &fai_buf.fai.BasicInformation, sizeof fai_buf.fai.BasicInformation, FileBasicInformation); 1331 ok ( res == STATUS_SUCCESS, "can't set system attribute, res: %x\n", res ); 1332 ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status: %x\n", U(io).Status ); 1333 1334 memset(&fai_buf.fai, 0, sizeof(fai_buf.fai)); 1335 res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation); 1336 ok ( res == STATUS_SUCCESS, "can't get attributes\n"); 1337 todo_wine ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_NORMAL, "attribute %x not FILE_ATTRIBUTE_NORMAL\n", fai_buf.fai.BasicInformation.FileAttributes ); 1338 1339 CloseHandle( h ); 1340 } 1341 1342 static void delete_object( WCHAR *path ) 1343 { 1344 BOOL ret = DeleteFileW( path ); 1345 ok( ret || GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_ACCESS_DENIED, 1346 "DeleteFileW failed with %u\n", GetLastError() ); 1347 if (!ret && GetLastError() == ERROR_ACCESS_DENIED) 1348 { 1349 ret = RemoveDirectoryW( path ); 1350 ok( ret, "RemoveDirectoryW failed with %u\n", GetLastError() ); 1351 } 1352 } 1353 1354 static void test_file_rename_information(void) 1355 { 1356 static const WCHAR foo_txtW[] = {'\\','f','o','o','.','t','x','t',0}; 1357 static const WCHAR fooW[] = {'f','o','o',0}; 1358 WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16], *filename, *p; 1359 FILE_RENAME_INFORMATION *fri; 1360 FILE_NAME_INFORMATION *fni; 1361 BOOL success, fileDeleted; 1362 UNICODE_STRING name_str; 1363 HANDLE handle, handle2; 1364 IO_STATUS_BLOCK io; 1365 NTSTATUS res; 1366 1367 GetTempPathW( MAX_PATH, tmp_path ); 1368 1369 /* oldpath is a file, newpath doesn't exist */ 1370 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1371 ok( res != 0, "failed to create temp file\n" ); 1372 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1373 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1374 1375 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1376 ok( res != 0, "failed to create temp file\n" ); 1377 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1378 DeleteFileW( newpath ); 1379 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1380 fri->Replace = FALSE; 1381 fri->RootDir = NULL; 1382 fri->FileNameLength = name_str.Length; 1383 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1384 pRtlFreeUnicodeString( &name_str ); 1385 1386 U(io).Status = 0xdeadbeef; 1387 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1388 ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status ); 1389 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 1390 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1391 ok( fileDeleted, "file should not exist\n" ); 1392 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1393 ok( !fileDeleted, "file should exist\n" ); 1394 1395 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) ); 1396 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation ); 1397 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 1398 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0; 1399 ok( !lstrcmpiW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n", 1400 wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) ); 1401 HeapFree( GetProcessHeap(), 0, fni ); 1402 1403 CloseHandle( handle ); 1404 HeapFree( GetProcessHeap(), 0, fri ); 1405 delete_object( oldpath ); 1406 delete_object( newpath ); 1407 1408 /* oldpath is a file, newpath is a file, Replace = FALSE */ 1409 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1410 ok( res != 0, "failed to create temp file\n" ); 1411 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1412 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1413 1414 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1415 ok( res != 0, "failed to create temp file\n" ); 1416 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1417 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1418 fri->Replace = FALSE; 1419 fri->RootDir = NULL; 1420 fri->FileNameLength = name_str.Length; 1421 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1422 pRtlFreeUnicodeString( &name_str ); 1423 1424 U(io).Status = 0xdeadbeef; 1425 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1426 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1427 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res ); 1428 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1429 ok( !fileDeleted, "file should exist\n" ); 1430 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1431 ok( !fileDeleted, "file should exist\n" ); 1432 1433 CloseHandle( handle ); 1434 HeapFree( GetProcessHeap(), 0, fri ); 1435 delete_object( oldpath ); 1436 delete_object( newpath ); 1437 1438 /* oldpath is a file, newpath is a file, Replace = TRUE */ 1439 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1440 ok( res != 0, "failed to create temp file\n" ); 1441 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1442 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1443 1444 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1445 ok( res != 0, "failed to create temp file\n" ); 1446 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1447 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1448 fri->Replace = TRUE; 1449 fri->RootDir = NULL; 1450 fri->FileNameLength = name_str.Length; 1451 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1452 pRtlFreeUnicodeString( &name_str ); 1453 1454 U(io).Status = 0xdeadbeef; 1455 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1456 ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status ); 1457 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 1458 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1459 ok( fileDeleted, "file should not exist\n" ); 1460 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1461 ok( !fileDeleted, "file should exist\n" ); 1462 1463 CloseHandle( handle ); 1464 HeapFree( GetProcessHeap(), 0, fri ); 1465 delete_object( oldpath ); 1466 delete_object( newpath ); 1467 1468 /* oldpath is a file, newpath is a file, Replace = FALSE, target file opened */ 1469 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1470 ok( res != 0, "failed to create temp file\n" ); 1471 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1472 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1473 1474 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1475 ok( res != 0, "failed to create temp file\n" ); 1476 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1477 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1478 1479 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1480 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1481 fri->Replace = FALSE; 1482 fri->RootDir = NULL; 1483 fri->FileNameLength = name_str.Length; 1484 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1485 pRtlFreeUnicodeString( &name_str ); 1486 1487 U(io).Status = 0xdeadbeef; 1488 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1489 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1490 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res ); 1491 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1492 ok( !fileDeleted, "file should exist\n" ); 1493 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1494 ok( !fileDeleted, "file should exist\n" ); 1495 1496 CloseHandle( handle ); 1497 CloseHandle( handle2 ); 1498 HeapFree( GetProcessHeap(), 0, fri ); 1499 delete_object( oldpath ); 1500 delete_object( newpath ); 1501 1502 /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened */ 1503 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1504 ok( res != 0, "failed to create temp file\n" ); 1505 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1506 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1507 1508 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1509 ok( res != 0, "failed to create temp file\n" ); 1510 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1511 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1512 1513 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1514 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1515 fri->Replace = TRUE; 1516 fri->RootDir = NULL; 1517 fri->FileNameLength = name_str.Length; 1518 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1519 pRtlFreeUnicodeString( &name_str ); 1520 1521 U(io).Status = 0xdeadbeef; 1522 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1523 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1524 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res ); 1525 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1526 ok( !fileDeleted, "file should exist\n" ); 1527 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1528 ok( !fileDeleted, "file should exist\n" ); 1529 1530 CloseHandle( handle ); 1531 CloseHandle( handle2 ); 1532 HeapFree( GetProcessHeap(), 0, fri ); 1533 delete_object( oldpath ); 1534 delete_object( newpath ); 1535 1536 /* oldpath is a directory, newpath doesn't exist, Replace = FALSE */ 1537 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1538 ok( res != 0, "failed to create temp file\n" ); 1539 DeleteFileW( oldpath ); 1540 success = CreateDirectoryW( oldpath, NULL ); 1541 ok( success != 0, "failed to create temp directory\n" ); 1542 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1543 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1544 1545 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1546 ok( res != 0, "failed to create temp file\n" ); 1547 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1548 DeleteFileW( newpath ); 1549 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1550 fri->Replace = FALSE; 1551 fri->RootDir = NULL; 1552 fri->FileNameLength = name_str.Length; 1553 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1554 pRtlFreeUnicodeString( &name_str ); 1555 1556 U(io).Status = 0xdeadbeef; 1557 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1558 ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status ); 1559 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 1560 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1561 ok( fileDeleted, "file should not exist\n" ); 1562 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1563 ok( !fileDeleted, "file should exist\n" ); 1564 1565 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) ); 1566 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation ); 1567 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 1568 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0; 1569 ok( !lstrcmpiW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n", 1570 wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) ); 1571 HeapFree( GetProcessHeap(), 0, fni ); 1572 1573 CloseHandle( handle ); 1574 HeapFree( GetProcessHeap(), 0, fri ); 1575 delete_object( oldpath ); 1576 delete_object( newpath ); 1577 1578 /* oldpath is a directory (but child object opened), newpath doesn't exist, Replace = FALSE */ 1579 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1580 ok( res != 0, "failed to create temp file\n" ); 1581 DeleteFileW( oldpath ); 1582 success = CreateDirectoryW( oldpath, NULL ); 1583 ok( success != 0, "failed to create temp directory\n" ); 1584 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1585 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1586 1587 lstrcpyW( newpath, oldpath ); 1588 lstrcatW( newpath, foo_txtW ); 1589 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0 ); 1590 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1591 1592 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1593 ok( res != 0, "failed to create temp file\n" ); 1594 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1595 DeleteFileW( newpath ); 1596 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1597 fri->Replace = FALSE; 1598 fri->RootDir = NULL; 1599 fri->FileNameLength = name_str.Length; 1600 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1601 pRtlFreeUnicodeString( &name_str ); 1602 1603 U(io).Status = 0xdeadbeef; 1604 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1605 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1606 todo_wine ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res ); 1607 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1608 todo_wine ok( !fileDeleted, "file should exist\n" ); 1609 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1610 todo_wine ok( fileDeleted, "file should not exist\n" ); 1611 1612 CloseHandle( handle ); 1613 CloseHandle( handle2 ); 1614 HeapFree( GetProcessHeap(), 0, fri ); 1615 delete_object( oldpath ); 1616 if (res == STATUS_SUCCESS) /* remove when Wine is fixed */ 1617 { 1618 lstrcpyW( oldpath, newpath ); 1619 lstrcatW( oldpath, foo_txtW ); 1620 delete_object( oldpath ); 1621 } 1622 delete_object( newpath ); 1623 1624 /* oldpath is a directory, newpath is a file, Replace = FALSE */ 1625 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1626 ok( res != 0, "failed to create temp file\n" ); 1627 DeleteFileW( oldpath ); 1628 success = CreateDirectoryW( oldpath, NULL ); 1629 ok( success != 0, "failed to create temp directory\n" ); 1630 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1631 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1632 1633 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1634 ok( res != 0, "failed to create temp file\n" ); 1635 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1636 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1637 fri->Replace = FALSE; 1638 fri->RootDir = NULL; 1639 fri->FileNameLength = name_str.Length; 1640 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1641 pRtlFreeUnicodeString( &name_str ); 1642 1643 U(io).Status = 0xdeadbeef; 1644 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1645 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1646 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res ); 1647 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1648 ok( !fileDeleted, "file should exist\n" ); 1649 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1650 ok( !fileDeleted, "file should exist\n" ); 1651 1652 CloseHandle( handle ); 1653 HeapFree( GetProcessHeap(), 0, fri ); 1654 delete_object( oldpath ); 1655 delete_object( newpath ); 1656 1657 /* oldpath is a directory, newpath is a file, Replace = FALSE, target file opened */ 1658 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1659 ok( res != 0, "failed to create temp file\n" ); 1660 DeleteFileW( oldpath ); 1661 success = CreateDirectoryW( oldpath, NULL ); 1662 ok( success != 0, "failed to create temp directory\n" ); 1663 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1664 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1665 1666 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1667 ok( res != 0, "failed to create temp file\n" ); 1668 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1669 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1670 1671 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1672 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1673 fri->Replace = FALSE; 1674 fri->RootDir = NULL; 1675 fri->FileNameLength = name_str.Length; 1676 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1677 pRtlFreeUnicodeString( &name_str ); 1678 1679 U(io).Status = 0xdeadbeef; 1680 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1681 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1682 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res ); 1683 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1684 ok( !fileDeleted, "file should exist\n" ); 1685 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1686 ok( !fileDeleted, "file should exist\n" ); 1687 1688 CloseHandle( handle ); 1689 CloseHandle( handle2 ); 1690 HeapFree( GetProcessHeap(), 0, fri ); 1691 delete_object( oldpath ); 1692 delete_object( newpath ); 1693 1694 /* oldpath is a directory, newpath is a file, Replace = TRUE */ 1695 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1696 ok( res != 0, "failed to create temp file\n" ); 1697 DeleteFileW( oldpath ); 1698 success = CreateDirectoryW( oldpath, NULL ); 1699 ok( success != 0, "failed to create temp directory\n" ); 1700 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1701 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1702 1703 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1704 ok( res != 0, "failed to create temp file\n" ); 1705 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1706 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1707 fri->Replace = TRUE; 1708 fri->RootDir = NULL; 1709 fri->FileNameLength = name_str.Length; 1710 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1711 pRtlFreeUnicodeString( &name_str ); 1712 1713 U(io).Status = 0xdeadbeef; 1714 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1715 ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status ); 1716 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 1717 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1718 ok( fileDeleted, "file should not exist\n" ); 1719 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1720 ok( !fileDeleted, "file should exist\n" ); 1721 1722 CloseHandle( handle ); 1723 HeapFree( GetProcessHeap(), 0, fri ); 1724 delete_object( oldpath ); 1725 delete_object( newpath ); 1726 1727 /* oldpath is a directory, newpath is a file, Replace = TRUE, target file opened */ 1728 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1729 ok( res != 0, "failed to create temp file\n" ); 1730 DeleteFileW( oldpath ); 1731 success = CreateDirectoryW( oldpath, NULL ); 1732 ok( success != 0, "failed to create temp directory\n" ); 1733 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1734 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1735 1736 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1737 ok( res != 0, "failed to create temp file\n" ); 1738 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1739 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1740 1741 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1742 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1743 fri->Replace = TRUE; 1744 fri->RootDir = NULL; 1745 fri->FileNameLength = name_str.Length; 1746 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1747 pRtlFreeUnicodeString( &name_str ); 1748 1749 U(io).Status = 0xdeadbeef; 1750 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1751 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1752 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res ); 1753 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1754 ok( !fileDeleted, "file should exist\n" ); 1755 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1756 ok( !fileDeleted, "file should exist\n" ); 1757 1758 CloseHandle( handle ); 1759 CloseHandle( handle2 ); 1760 HeapFree( GetProcessHeap(), 0, fri ); 1761 delete_object( oldpath ); 1762 delete_object( newpath ); 1763 1764 /* oldpath is a directory, newpath is a directory, Replace = FALSE */ 1765 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1766 ok( res != 0, "failed to create temp file\n" ); 1767 DeleteFileW( oldpath ); 1768 success = CreateDirectoryW( oldpath, NULL ); 1769 ok( success != 0, "failed to create temp directory\n" ); 1770 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1771 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1772 1773 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1774 ok( res != 0, "failed to create temp file\n" ); 1775 DeleteFileW( newpath ); 1776 success = CreateDirectoryW( newpath, NULL ); 1777 ok( success != 0, "failed to create temp directory\n" ); 1778 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1779 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1780 fri->Replace = FALSE; 1781 fri->RootDir = NULL; 1782 fri->FileNameLength = name_str.Length; 1783 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1784 pRtlFreeUnicodeString( &name_str ); 1785 1786 U(io).Status = 0xdeadbeef; 1787 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1788 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1789 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res ); 1790 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1791 ok( !fileDeleted, "file should exist\n" ); 1792 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1793 ok( !fileDeleted, "file should exist\n" ); 1794 1795 CloseHandle( handle ); 1796 HeapFree( GetProcessHeap(), 0, fri ); 1797 delete_object( oldpath ); 1798 delete_object( newpath ); 1799 1800 /* oldpath is a directory, newpath is a directory, Replace = TRUE */ 1801 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1802 ok( res != 0, "failed to create temp file\n" ); 1803 DeleteFileW( oldpath ); 1804 success = CreateDirectoryW( oldpath, NULL ); 1805 ok( success != 0, "failed to create temp directory\n" ); 1806 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1807 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1808 1809 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1810 ok( res != 0, "failed to create temp file\n" ); 1811 DeleteFileW( newpath ); 1812 success = CreateDirectoryW( newpath, NULL ); 1813 ok( success != 0, "failed to create temp directory\n" ); 1814 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1815 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1816 fri->Replace = TRUE; 1817 fri->RootDir = NULL; 1818 fri->FileNameLength = name_str.Length; 1819 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1820 pRtlFreeUnicodeString( &name_str ); 1821 1822 U(io).Status = 0xdeadbeef; 1823 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1824 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1825 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res ); 1826 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1827 ok( !fileDeleted, "file should exist\n" ); 1828 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1829 ok( !fileDeleted, "file should exist\n" ); 1830 1831 CloseHandle( handle ); 1832 HeapFree( GetProcessHeap(), 0, fri ); 1833 delete_object( oldpath ); 1834 delete_object( newpath ); 1835 1836 /* oldpath is a directory, newpath is a directory, Replace = TRUE, target file opened */ 1837 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1838 ok( res != 0, "failed to create temp file\n" ); 1839 DeleteFileW( oldpath ); 1840 success = CreateDirectoryW( oldpath, NULL ); 1841 ok( success != 0, "failed to create temp directory\n" ); 1842 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1843 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1844 1845 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1846 ok( res != 0, "failed to create temp file\n" ); 1847 DeleteFileW( newpath ); 1848 success = CreateDirectoryW( newpath, NULL ); 1849 ok( success != 0, "failed to create temp directory\n" ); 1850 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1851 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1852 1853 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1854 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1855 fri->Replace = TRUE; 1856 fri->RootDir = NULL; 1857 fri->FileNameLength = name_str.Length; 1858 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1859 pRtlFreeUnicodeString( &name_str ); 1860 1861 U(io).Status = 0xdeadbeef; 1862 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1863 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1864 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res ); 1865 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1866 ok( !fileDeleted, "file should exist\n" ); 1867 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1868 ok( !fileDeleted, "file should exist\n" ); 1869 1870 CloseHandle( handle ); 1871 CloseHandle( handle2 ); 1872 HeapFree( GetProcessHeap(), 0, fri ); 1873 delete_object( oldpath ); 1874 delete_object( newpath ); 1875 1876 /* oldpath is a file, newpath is a directory, Replace = FALSE */ 1877 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1878 ok( res != 0, "failed to create temp file\n" ); 1879 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1880 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1881 1882 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1883 ok( res != 0, "failed to create temp file\n" ); 1884 DeleteFileW( newpath ); 1885 success = CreateDirectoryW( newpath, NULL ); 1886 ok( success != 0, "failed to create temp directory\n" ); 1887 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1888 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1889 fri->Replace = FALSE; 1890 fri->RootDir = NULL; 1891 fri->FileNameLength = name_str.Length; 1892 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1893 pRtlFreeUnicodeString( &name_str ); 1894 1895 U(io).Status = 0xdeadbeef; 1896 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1897 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1898 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res ); 1899 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1900 ok( !fileDeleted, "file should exist\n" ); 1901 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1902 ok( !fileDeleted, "file should exist\n" ); 1903 1904 CloseHandle( handle ); 1905 HeapFree( GetProcessHeap(), 0, fri ); 1906 delete_object( oldpath ); 1907 delete_object( newpath ); 1908 1909 /* oldpath is a file, newpath is a directory, Replace = TRUE */ 1910 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1911 ok( res != 0, "failed to create temp file\n" ); 1912 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1913 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1914 1915 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1916 ok( res != 0, "failed to create temp file\n" ); 1917 DeleteFileW( newpath ); 1918 success = CreateDirectoryW( newpath, NULL ); 1919 ok( success != 0, "failed to create temp directory\n" ); 1920 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 1921 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length ); 1922 fri->Replace = TRUE; 1923 fri->RootDir = NULL; 1924 fri->FileNameLength = name_str.Length; 1925 memcpy( fri->FileName, name_str.Buffer, name_str.Length ); 1926 pRtlFreeUnicodeString( &name_str ); 1927 1928 U(io).Status = 0xdeadbeef; 1929 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1930 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 1931 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res ); 1932 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1933 ok( !fileDeleted, "file should exist\n" ); 1934 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1935 ok( !fileDeleted, "file should exist\n" ); 1936 1937 CloseHandle( handle ); 1938 HeapFree( GetProcessHeap(), 0, fri ); 1939 delete_object( oldpath ); 1940 delete_object( newpath ); 1941 1942 /* oldpath is a file, newpath doesn't exist, test with RootDir != NULL */ 1943 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 1944 ok( res != 0, "failed to create temp file\n" ); 1945 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 1946 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1947 1948 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 1949 ok( res != 0, "failed to create temp file\n" ); 1950 DeleteFileW( newpath ); 1951 for (filename = newpath, p = newpath; *p; p++) 1952 if (*p == '\\') filename = p + 1; 1953 handle2 = CreateFileW( tmp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 1954 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 1955 1956 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + lstrlenW(filename) * sizeof(WCHAR) ); 1957 fri->Replace = FALSE; 1958 fri->RootDir = handle2; 1959 fri->FileNameLength = lstrlenW(filename) * sizeof(WCHAR); 1960 memcpy( fri->FileName, filename, fri->FileNameLength ); 1961 1962 U(io).Status = 0xdeadbeef; 1963 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation ); 1964 ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status ); 1965 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 1966 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1967 ok( fileDeleted, "file should not exist\n" ); 1968 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 1969 ok( !fileDeleted, "file should exist\n" ); 1970 1971 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) ); 1972 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation ); 1973 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 1974 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0; 1975 ok( !lstrcmpiW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n", 1976 wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) ); 1977 HeapFree( GetProcessHeap(), 0, fni ); 1978 1979 CloseHandle( handle ); 1980 CloseHandle( handle2 ); 1981 HeapFree( GetProcessHeap(), 0, fri ); 1982 delete_object( oldpath ); 1983 delete_object( newpath ); 1984 } 1985 1986 static void test_file_link_information(void) 1987 { 1988 static const WCHAR foo_txtW[] = {'\\','f','o','o','.','t','x','t',0}; 1989 static const WCHAR fooW[] = {'f','o','o',0}; 1990 WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16], *filename, *p; 1991 FILE_LINK_INFORMATION *fli; 1992 FILE_NAME_INFORMATION *fni; 1993 BOOL success, fileDeleted; 1994 UNICODE_STRING name_str; 1995 HANDLE handle, handle2; 1996 IO_STATUS_BLOCK io; 1997 NTSTATUS res; 1998 1999 GetTempPathW( MAX_PATH, tmp_path ); 2000 2001 /* oldpath is a file, newpath doesn't exist */ 2002 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2003 ok( res != 0, "failed to create temp file\n" ); 2004 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2005 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2006 2007 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2008 ok( res != 0, "failed to create temp file\n" ); 2009 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2010 DeleteFileW( newpath ); 2011 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2012 fli->ReplaceIfExists = FALSE; 2013 fli->RootDirectory = NULL; 2014 fli->FileNameLength = name_str.Length; 2015 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2016 pRtlFreeUnicodeString( &name_str ); 2017 2018 U(io).Status = 0xdeadbeef; 2019 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2020 ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status ); 2021 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 2022 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2023 ok( !fileDeleted, "file should exist\n" ); 2024 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2025 ok( !fileDeleted, "file should exist\n" ); 2026 2027 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) ); 2028 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation ); 2029 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 2030 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0; 2031 ok( !lstrcmpiW(fni->FileName, oldpath + 2), "FileName expected %s, got %s\n", 2032 wine_dbgstr_w(oldpath + 2), wine_dbgstr_w(fni->FileName) ); 2033 HeapFree( GetProcessHeap(), 0, fni ); 2034 2035 CloseHandle( handle ); 2036 HeapFree( GetProcessHeap(), 0, fli ); 2037 delete_object( oldpath ); 2038 delete_object( newpath ); 2039 2040 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE */ 2041 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2042 ok( res != 0, "failed to create temp file\n" ); 2043 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2044 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2045 2046 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2047 ok( res != 0, "failed to create temp file\n" ); 2048 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2049 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2050 fli->ReplaceIfExists = FALSE; 2051 fli->RootDirectory = NULL; 2052 fli->FileNameLength = name_str.Length; 2053 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2054 pRtlFreeUnicodeString( &name_str ); 2055 2056 U(io).Status = 0xdeadbeef; 2057 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2058 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2059 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res ); 2060 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2061 ok( !fileDeleted, "file should exist\n" ); 2062 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2063 ok( !fileDeleted, "file should exist\n" ); 2064 2065 CloseHandle( handle ); 2066 HeapFree( GetProcessHeap(), 0, fli ); 2067 delete_object( oldpath ); 2068 delete_object( newpath ); 2069 2070 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE */ 2071 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2072 ok( res != 0, "failed to create temp file\n" ); 2073 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2074 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2075 2076 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2077 ok( res != 0, "failed to create temp file\n" ); 2078 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2079 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2080 fli->ReplaceIfExists = TRUE; 2081 fli->RootDirectory = NULL; 2082 fli->FileNameLength = name_str.Length; 2083 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2084 pRtlFreeUnicodeString( &name_str ); 2085 2086 U(io).Status = 0xdeadbeef; 2087 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2088 ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status ); 2089 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 2090 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2091 ok( !fileDeleted, "file should exist\n" ); 2092 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2093 ok( !fileDeleted, "file should exist\n" ); 2094 2095 CloseHandle( handle ); 2096 HeapFree( GetProcessHeap(), 0, fli ); 2097 delete_object( oldpath ); 2098 delete_object( newpath ); 2099 2100 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE, target file opened */ 2101 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2102 ok( res != 0, "failed to create temp file\n" ); 2103 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2104 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2105 2106 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2107 ok( res != 0, "failed to create temp file\n" ); 2108 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2109 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2110 2111 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2112 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2113 fli->ReplaceIfExists = FALSE; 2114 fli->RootDirectory = NULL; 2115 fli->FileNameLength = name_str.Length; 2116 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2117 pRtlFreeUnicodeString( &name_str ); 2118 2119 U(io).Status = 0xdeadbeef; 2120 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2121 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2122 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res ); 2123 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2124 ok( !fileDeleted, "file should exist\n" ); 2125 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2126 ok( !fileDeleted, "file should exist\n" ); 2127 2128 CloseHandle( handle ); 2129 CloseHandle( handle2 ); 2130 HeapFree( GetProcessHeap(), 0, fli ); 2131 delete_object( oldpath ); 2132 delete_object( newpath ); 2133 2134 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, target file opened */ 2135 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2136 ok( res != 0, "failed to create temp file\n" ); 2137 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2138 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2139 2140 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2141 ok( res != 0, "failed to create temp file\n" ); 2142 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2143 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2144 2145 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2146 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2147 fli->ReplaceIfExists = TRUE; 2148 fli->RootDirectory = NULL; 2149 fli->FileNameLength = name_str.Length; 2150 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2151 pRtlFreeUnicodeString( &name_str ); 2152 2153 U(io).Status = 0xdeadbeef; 2154 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2155 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2156 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res ); 2157 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2158 ok( !fileDeleted, "file should exist\n" ); 2159 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2160 ok( !fileDeleted, "file should exist\n" ); 2161 2162 CloseHandle( handle ); 2163 CloseHandle( handle2 ); 2164 HeapFree( GetProcessHeap(), 0, fli ); 2165 delete_object( oldpath ); 2166 delete_object( newpath ); 2167 2168 /* oldpath is a directory, newpath doesn't exist, ReplaceIfExists = FALSE */ 2169 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2170 ok( res != 0, "failed to create temp file\n" ); 2171 DeleteFileW( oldpath ); 2172 success = CreateDirectoryW( oldpath, NULL ); 2173 ok( success != 0, "failed to create temp directory\n" ); 2174 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2175 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2176 2177 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2178 ok( res != 0, "failed to create temp file\n" ); 2179 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2180 DeleteFileW( newpath ); 2181 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2182 fli->ReplaceIfExists = FALSE; 2183 fli->RootDirectory = NULL; 2184 fli->FileNameLength = name_str.Length; 2185 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2186 pRtlFreeUnicodeString( &name_str ); 2187 2188 U(io).Status = 0xdeadbeef; 2189 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2190 todo_wine ok( U(io).Status == 0xdeadbeef , "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2191 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res ); 2192 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2193 ok( !fileDeleted, "file should exist\n" ); 2194 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2195 ok( fileDeleted, "file should not exist\n" ); 2196 2197 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) ); 2198 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation ); 2199 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 2200 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0; 2201 ok( !lstrcmpiW(fni->FileName, oldpath + 2), "FileName expected %s, got %s\n", 2202 wine_dbgstr_w(oldpath + 2), wine_dbgstr_w(fni->FileName) ); 2203 HeapFree( GetProcessHeap(), 0, fni ); 2204 2205 CloseHandle( handle ); 2206 HeapFree( GetProcessHeap(), 0, fli ); 2207 delete_object( oldpath ); 2208 delete_object( newpath ); 2209 2210 /* oldpath is a directory (but child object opened), newpath doesn't exist, ReplaceIfExists = FALSE */ 2211 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2212 ok( res != 0, "failed to create temp file\n" ); 2213 DeleteFileW( oldpath ); 2214 success = CreateDirectoryW( oldpath, NULL ); 2215 ok( success != 0, "failed to create temp directory\n" ); 2216 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2217 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2218 2219 lstrcpyW( newpath, oldpath ); 2220 lstrcatW( newpath, foo_txtW ); 2221 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0 ); 2222 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2223 2224 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2225 ok( res != 0, "failed to create temp file\n" ); 2226 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2227 DeleteFileW( newpath ); 2228 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2229 fli->ReplaceIfExists = FALSE; 2230 fli->RootDirectory = NULL; 2231 fli->FileNameLength = name_str.Length; 2232 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2233 pRtlFreeUnicodeString( &name_str ); 2234 2235 U(io).Status = 0xdeadbeef; 2236 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2237 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2238 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res ); 2239 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2240 ok( !fileDeleted, "file should exist\n" ); 2241 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2242 ok( fileDeleted, "file should not exist\n" ); 2243 2244 CloseHandle( handle ); 2245 CloseHandle( handle2 ); 2246 HeapFree( GetProcessHeap(), 0, fli ); 2247 delete_object( oldpath ); 2248 delete_object( newpath ); 2249 2250 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE */ 2251 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2252 ok( res != 0, "failed to create temp file\n" ); 2253 DeleteFileW( oldpath ); 2254 success = CreateDirectoryW( oldpath, NULL ); 2255 ok( success != 0, "failed to create temp directory\n" ); 2256 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2257 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2258 2259 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2260 ok( res != 0, "failed to create temp file\n" ); 2261 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2262 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2263 fli->ReplaceIfExists = FALSE; 2264 fli->RootDirectory = NULL; 2265 fli->FileNameLength = name_str.Length; 2266 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2267 pRtlFreeUnicodeString( &name_str ); 2268 2269 U(io).Status = 0xdeadbeef; 2270 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2271 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2272 ok( res == STATUS_OBJECT_NAME_COLLISION || res == STATUS_FILE_IS_A_DIRECTORY /* > Win XP */, 2273 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res ); 2274 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2275 ok( !fileDeleted, "file should exist\n" ); 2276 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2277 ok( !fileDeleted, "file should exist\n" ); 2278 2279 CloseHandle( handle ); 2280 HeapFree( GetProcessHeap(), 0, fli ); 2281 delete_object( oldpath ); 2282 delete_object( newpath ); 2283 2284 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE, target file opened */ 2285 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2286 ok( res != 0, "failed to create temp file\n" ); 2287 DeleteFileW( oldpath ); 2288 success = CreateDirectoryW( oldpath, NULL ); 2289 ok( success != 0, "failed to create temp directory\n" ); 2290 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2291 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2292 2293 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2294 ok( res != 0, "failed to create temp file\n" ); 2295 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2296 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2297 2298 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2299 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2300 fli->ReplaceIfExists = FALSE; 2301 fli->RootDirectory = NULL; 2302 fli->FileNameLength = name_str.Length; 2303 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2304 pRtlFreeUnicodeString( &name_str ); 2305 2306 U(io).Status = 0xdeadbeef; 2307 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2308 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2309 ok( res == STATUS_OBJECT_NAME_COLLISION || res == STATUS_FILE_IS_A_DIRECTORY /* > Win XP */, 2310 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res ); 2311 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2312 ok( !fileDeleted, "file should exist\n" ); 2313 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2314 ok( !fileDeleted, "file should exist\n" ); 2315 2316 CloseHandle( handle ); 2317 CloseHandle( handle2 ); 2318 HeapFree( GetProcessHeap(), 0, fli ); 2319 delete_object( oldpath ); 2320 delete_object( newpath ); 2321 2322 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE */ 2323 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2324 ok( res != 0, "failed to create temp file\n" ); 2325 DeleteFileW( oldpath ); 2326 success = CreateDirectoryW( oldpath, NULL ); 2327 ok( success != 0, "failed to create temp directory\n" ); 2328 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2329 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2330 2331 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2332 ok( res != 0, "failed to create temp file\n" ); 2333 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2334 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2335 fli->ReplaceIfExists = TRUE; 2336 fli->RootDirectory = NULL; 2337 fli->FileNameLength = name_str.Length; 2338 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2339 pRtlFreeUnicodeString( &name_str ); 2340 2341 U(io).Status = 0xdeadbeef; 2342 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2343 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2344 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res ); 2345 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2346 ok( !fileDeleted, "file should exist\n" ); 2347 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2348 ok( !fileDeleted, "file should exist\n" ); 2349 2350 CloseHandle( handle ); 2351 HeapFree( GetProcessHeap(), 0, fli ); 2352 delete_object( oldpath ); 2353 delete_object( newpath ); 2354 2355 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE, target file opened */ 2356 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2357 ok( res != 0, "failed to create temp file\n" ); 2358 DeleteFileW( oldpath ); 2359 success = CreateDirectoryW( oldpath, NULL ); 2360 ok( success != 0, "failed to create temp directory\n" ); 2361 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2362 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2363 2364 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2365 ok( res != 0, "failed to create temp file\n" ); 2366 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2367 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2368 2369 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2370 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2371 fli->ReplaceIfExists = TRUE; 2372 fli->RootDirectory = NULL; 2373 fli->FileNameLength = name_str.Length; 2374 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2375 pRtlFreeUnicodeString( &name_str ); 2376 2377 U(io).Status = 0xdeadbeef; 2378 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2379 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2380 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res ); 2381 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2382 ok( !fileDeleted, "file should exist\n" ); 2383 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2384 ok( !fileDeleted, "file should exist\n" ); 2385 2386 CloseHandle( handle ); 2387 CloseHandle( handle2 ); 2388 HeapFree( GetProcessHeap(), 0, fli ); 2389 delete_object( oldpath ); 2390 delete_object( newpath ); 2391 2392 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = FALSE */ 2393 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2394 ok( res != 0, "failed to create temp file\n" ); 2395 DeleteFileW( oldpath ); 2396 success = CreateDirectoryW( oldpath, NULL ); 2397 ok( success != 0, "failed to create temp directory\n" ); 2398 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2399 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2400 2401 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2402 ok( res != 0, "failed to create temp file\n" ); 2403 DeleteFileW( newpath ); 2404 success = CreateDirectoryW( newpath, NULL ); 2405 ok( success != 0, "failed to create temp directory\n" ); 2406 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2407 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2408 fli->ReplaceIfExists = FALSE; 2409 fli->RootDirectory = NULL; 2410 fli->FileNameLength = name_str.Length; 2411 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2412 pRtlFreeUnicodeString( &name_str ); 2413 2414 U(io).Status = 0xdeadbeef; 2415 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2416 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2417 ok( res == STATUS_OBJECT_NAME_COLLISION || res == STATUS_FILE_IS_A_DIRECTORY /* > Win XP */, 2418 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res ); 2419 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2420 ok( !fileDeleted, "file should exist\n" ); 2421 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2422 ok( !fileDeleted, "file should exist\n" ); 2423 2424 CloseHandle( handle ); 2425 HeapFree( GetProcessHeap(), 0, fli ); 2426 delete_object( oldpath ); 2427 delete_object( newpath ); 2428 2429 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE */ 2430 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2431 ok( res != 0, "failed to create temp file\n" ); 2432 DeleteFileW( oldpath ); 2433 success = CreateDirectoryW( oldpath, NULL ); 2434 ok( success != 0, "failed to create temp directory\n" ); 2435 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2436 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2437 2438 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2439 ok( res != 0, "failed to create temp file\n" ); 2440 DeleteFileW( newpath ); 2441 success = CreateDirectoryW( newpath, NULL ); 2442 ok( success != 0, "failed to create temp directory\n" ); 2443 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2444 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2445 fli->ReplaceIfExists = TRUE; 2446 fli->RootDirectory = NULL; 2447 fli->FileNameLength = name_str.Length; 2448 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2449 pRtlFreeUnicodeString( &name_str ); 2450 2451 U(io).Status = 0xdeadbeef; 2452 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2453 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2454 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res ); 2455 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2456 ok( !fileDeleted, "file should exist\n" ); 2457 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2458 ok( !fileDeleted, "file should exist\n" ); 2459 2460 CloseHandle( handle ); 2461 HeapFree( GetProcessHeap(), 0, fli ); 2462 delete_object( oldpath ); 2463 delete_object( newpath ); 2464 2465 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE, target file opened */ 2466 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2467 ok( res != 0, "failed to create temp file\n" ); 2468 DeleteFileW( oldpath ); 2469 success = CreateDirectoryW( oldpath, NULL ); 2470 ok( success != 0, "failed to create temp directory\n" ); 2471 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2472 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2473 2474 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2475 ok( res != 0, "failed to create temp file\n" ); 2476 DeleteFileW( newpath ); 2477 success = CreateDirectoryW( newpath, NULL ); 2478 ok( success != 0, "failed to create temp directory\n" ); 2479 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2480 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2481 2482 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2483 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2484 fli->ReplaceIfExists = TRUE; 2485 fli->RootDirectory = NULL; 2486 fli->FileNameLength = name_str.Length; 2487 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2488 pRtlFreeUnicodeString( &name_str ); 2489 2490 U(io).Status = 0xdeadbeef; 2491 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2492 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2493 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res ); 2494 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2495 ok( !fileDeleted, "file should exist\n" ); 2496 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2497 ok( !fileDeleted, "file should exist\n" ); 2498 2499 CloseHandle( handle ); 2500 CloseHandle( handle2 ); 2501 HeapFree( GetProcessHeap(), 0, fli ); 2502 delete_object( oldpath ); 2503 delete_object( newpath ); 2504 2505 /* oldpath is a file, newpath is a directory, ReplaceIfExists = FALSE */ 2506 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2507 ok( res != 0, "failed to create temp file\n" ); 2508 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2509 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2510 2511 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2512 ok( res != 0, "failed to create temp file\n" ); 2513 DeleteFileW( newpath ); 2514 success = CreateDirectoryW( newpath, NULL ); 2515 ok( success != 0, "failed to create temp directory\n" ); 2516 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2517 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2518 fli->ReplaceIfExists = FALSE; 2519 fli->RootDirectory = NULL; 2520 fli->FileNameLength = name_str.Length; 2521 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2522 pRtlFreeUnicodeString( &name_str ); 2523 2524 U(io).Status = 0xdeadbeef; 2525 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2526 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2527 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res ); 2528 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2529 ok( !fileDeleted, "file should exist\n" ); 2530 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2531 ok( !fileDeleted, "file should exist\n" ); 2532 2533 CloseHandle( handle ); 2534 HeapFree( GetProcessHeap(), 0, fli ); 2535 delete_object( oldpath ); 2536 delete_object( newpath ); 2537 2538 /* oldpath is a file, newpath is a directory, ReplaceIfExists = TRUE */ 2539 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2540 ok( res != 0, "failed to create temp file\n" ); 2541 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2542 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2543 2544 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2545 ok( res != 0, "failed to create temp file\n" ); 2546 DeleteFileW( newpath ); 2547 success = CreateDirectoryW( newpath, NULL ); 2548 ok( success != 0, "failed to create temp directory\n" ); 2549 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL ); 2550 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length ); 2551 fli->ReplaceIfExists = TRUE; 2552 fli->RootDirectory = NULL; 2553 fli->FileNameLength = name_str.Length; 2554 memcpy( fli->FileName, name_str.Buffer, name_str.Length ); 2555 pRtlFreeUnicodeString( &name_str ); 2556 2557 U(io).Status = 0xdeadbeef; 2558 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2559 todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status ); 2560 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res ); 2561 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2562 ok( !fileDeleted, "file should exist\n" ); 2563 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2564 ok( !fileDeleted, "file should exist\n" ); 2565 2566 CloseHandle( handle ); 2567 HeapFree( GetProcessHeap(), 0, fli ); 2568 delete_object( oldpath ); 2569 delete_object( newpath ); 2570 2571 /* oldpath is a file, newpath doesn't exist, test with RootDirectory != NULL */ 2572 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath ); 2573 ok( res != 0, "failed to create temp file\n" ); 2574 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2575 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2576 2577 res = GetTempFileNameW( tmp_path, fooW, 0, newpath ); 2578 ok( res != 0, "failed to create temp file\n" ); 2579 DeleteFileW( newpath ); 2580 for (filename = newpath, p = newpath; *p; p++) 2581 if (*p == '\\') filename = p + 1; 2582 handle2 = CreateFileW( tmp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2583 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" ); 2584 2585 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + lstrlenW(filename) * sizeof(WCHAR) ); 2586 fli->ReplaceIfExists = FALSE; 2587 fli->RootDirectory = handle2; 2588 fli->FileNameLength = lstrlenW(filename) * sizeof(WCHAR); 2589 memcpy( fli->FileName, filename, fli->FileNameLength ); 2590 2591 U(io).Status = 0xdeadbeef; 2592 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation ); 2593 ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status ); 2594 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 2595 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2596 ok( !fileDeleted, "file should exist\n" ); 2597 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2598 ok( !fileDeleted, "file should exist\n" ); 2599 2600 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) ); 2601 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation ); 2602 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); 2603 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0; 2604 ok( !lstrcmpiW(fni->FileName, oldpath + 2), "FileName expected %s, got %s\n", 2605 wine_dbgstr_w(oldpath + 2), wine_dbgstr_w(fni->FileName) ); 2606 HeapFree( GetProcessHeap(), 0, fni ); 2607 2608 CloseHandle( handle ); 2609 CloseHandle( handle2 ); 2610 HeapFree( GetProcessHeap(), 0, fli ); 2611 delete_object( oldpath ); 2612 delete_object( newpath ); 2613 } 2614 2615 static void test_file_both_information(void) 2616 { 2617 IO_STATUS_BLOCK io; 2618 FILE_BOTH_DIR_INFORMATION fbi; 2619 HANDLE h; 2620 int res; 2621 2622 if (!(h = create_temp_file(0))) return; 2623 2624 memset(&fbi, 0, sizeof(fbi)); 2625 res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBothDirectoryInformation); 2626 ok ( res == STATUS_INVALID_INFO_CLASS || res == STATUS_NOT_IMPLEMENTED, "shouldn't be able to query FileBothDirectoryInformation, res %x\n", res); 2627 2628 CloseHandle( h ); 2629 } 2630 2631 static void test_file_disposition_information(void) 2632 { 2633 char tmp_path[MAX_PATH], buffer[MAX_PATH + 16]; 2634 DWORD dirpos; 2635 HANDLE handle, handle2, mapping; 2636 NTSTATUS res; 2637 IO_STATUS_BLOCK io; 2638 FILE_DISPOSITION_INFORMATION fdi; 2639 BOOL fileDeleted; 2640 DWORD fdi2; 2641 void *ptr; 2642 2643 GetTempPathA( MAX_PATH, tmp_path ); 2644 2645 /* tests for info struct size */ 2646 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2647 handle = CreateFileA( buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2648 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2649 res = pNtSetInformationFile( handle, &io, &fdi, 0, FileDispositionInformation ); 2650 todo_wine 2651 ok( res == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %x\n", res ); 2652 fdi2 = 0x100; 2653 res = pNtSetInformationFile( handle, &io, &fdi2, sizeof(fdi2), FileDispositionInformation ); 2654 ok( res == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %x\n", res ); 2655 CloseHandle( handle ); 2656 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2657 ok( !fileDeleted, "File shouldn't have been deleted\n" ); 2658 DeleteFileA( buffer ); 2659 2660 /* cannot set disposition on file not opened with delete access */ 2661 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2662 handle = CreateFileA(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); 2663 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2664 res = pNtQueryInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2665 ok( res == STATUS_INVALID_INFO_CLASS || res == STATUS_NOT_IMPLEMENTED, "Unexpected NtQueryInformationFile result (expected STATUS_INVALID_INFO_CLASS, got %x)\n", res ); 2666 fdi.DoDeleteFile = TRUE; 2667 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2668 ok( res == STATUS_ACCESS_DENIED, "unexpected FileDispositionInformation result (expected STATUS_ACCESS_DENIED, got %x)\n", res ); 2669 CloseHandle( handle ); 2670 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2671 ok( !fileDeleted, "File shouldn't have been deleted\n" ); 2672 DeleteFileA( buffer ); 2673 2674 /* can set disposition on file opened with proper access */ 2675 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2676 handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0); 2677 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2678 fdi.DoDeleteFile = TRUE; 2679 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2680 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); 2681 CloseHandle( handle ); 2682 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2683 ok( fileDeleted, "File should have been deleted\n" ); 2684 DeleteFileA( buffer ); 2685 2686 /* cannot set disposition on readonly file */ 2687 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2688 DeleteFileA( buffer ); 2689 handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0); 2690 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2691 fdi.DoDeleteFile = TRUE; 2692 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2693 ok( res == STATUS_CANNOT_DELETE, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res ); 2694 CloseHandle( handle ); 2695 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2696 ok( !fileDeleted, "File shouldn't have been deleted\n" ); 2697 SetFileAttributesA( buffer, FILE_ATTRIBUTE_NORMAL ); 2698 DeleteFileA( buffer ); 2699 2700 /* cannot set disposition on readonly file */ 2701 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2702 handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0); 2703 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2704 fdi.DoDeleteFile = TRUE; 2705 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2706 todo_wine 2707 ok( res == STATUS_CANNOT_DELETE, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res ); 2708 CloseHandle( handle ); 2709 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2710 todo_wine 2711 ok( !fileDeleted, "File shouldn't have been deleted\n" ); 2712 SetFileAttributesA( buffer, FILE_ATTRIBUTE_NORMAL ); 2713 DeleteFileA( buffer ); 2714 2715 /* can set disposition on file and then reset it */ 2716 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2717 handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0); 2718 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2719 fdi.DoDeleteFile = TRUE; 2720 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2721 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); 2722 fdi.DoDeleteFile = FALSE; 2723 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2724 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); 2725 CloseHandle( handle ); 2726 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2727 ok( !fileDeleted, "File shouldn't have been deleted\n" ); 2728 DeleteFileA( buffer ); 2729 2730 /* Delete-on-close flag doesn't change file disposition until a handle is closed */ 2731 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2732 handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0); 2733 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2734 fdi.DoDeleteFile = FALSE; 2735 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2736 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); 2737 CloseHandle( handle ); 2738 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2739 ok( fileDeleted, "File should have been deleted\n" ); 2740 DeleteFileA( buffer ); 2741 2742 /* Delete-on-close flag sets disposition when a handle is closed and then it could be changed back */ 2743 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2744 handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0); 2745 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2746 ok( DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &handle2, 0, FALSE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); 2747 CloseHandle( handle ); 2748 fdi.DoDeleteFile = FALSE; 2749 res = pNtSetInformationFile( handle2, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2750 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); 2751 CloseHandle( handle2 ); 2752 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2753 ok( fileDeleted, "File should have been deleted\n" ); 2754 DeleteFileA( buffer ); 2755 2756 /* can set disposition on a directory opened with proper access */ 2757 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2758 DeleteFileA( buffer ); 2759 ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" ); 2760 handle = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); 2761 ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" ); 2762 fdi.DoDeleteFile = TRUE; 2763 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2764 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); 2765 CloseHandle( handle ); 2766 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2767 ok( fileDeleted, "Directory should have been deleted\n" ); 2768 RemoveDirectoryA( buffer ); 2769 2770 /* RemoveDirectory sets directory disposition and it can be undone */ 2771 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2772 DeleteFileA( buffer ); 2773 ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" ); 2774 handle = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); 2775 ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" ); 2776 RemoveDirectoryA( buffer ); 2777 fdi.DoDeleteFile = FALSE; 2778 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2779 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); 2780 CloseHandle( handle ); 2781 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2782 ok( !fileDeleted, "Directory shouldn't have been deleted\n" ); 2783 RemoveDirectoryA( buffer ); 2784 2785 /* cannot set disposition on a non-empty directory */ 2786 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2787 DeleteFileA( buffer ); 2788 ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" ); 2789 handle = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); 2790 ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" ); 2791 dirpos = lstrlenA( buffer ); 2792 lstrcpyA( buffer + dirpos, "\\tst" ); 2793 handle2 = CreateFileA(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); 2794 CloseHandle( handle2 ); 2795 fdi.DoDeleteFile = TRUE; 2796 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2797 todo_wine 2798 ok( res == STATUS_DIRECTORY_NOT_EMPTY, "unexpected FileDispositionInformation result (expected STATUS_DIRECTORY_NOT_EMPTY, got %x)\n", res ); 2799 DeleteFileA( buffer ); 2800 buffer[dirpos] = '\0'; 2801 CloseHandle( handle ); 2802 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2803 todo_wine 2804 ok( !fileDeleted, "Directory shouldn't have been deleted\n" ); 2805 RemoveDirectoryA( buffer ); 2806 2807 /* cannot set disposition on file with file mapping opened */ 2808 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2809 handle = CreateFileA(buffer, GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0); 2810 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2811 mapping = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 64 * 1024, "DelFileTest" ); 2812 ok( mapping != NULL, "failed to create file mapping\n"); 2813 fdi.DoDeleteFile = TRUE; 2814 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2815 ok( res == STATUS_CANNOT_DELETE, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res ); 2816 CloseHandle( handle ); 2817 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2818 ok( !fileDeleted, "File shouldn't have been deleted\n" ); 2819 CloseHandle( mapping ); 2820 DeleteFileA( buffer ); 2821 2822 /* can set disposition on file with file mapping closed */ 2823 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2824 handle = CreateFileA(buffer, GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0); 2825 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2826 mapping = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 64 * 1024, "DelFileTest" ); 2827 ok( mapping != NULL, "failed to create file mapping\n"); 2828 CloseHandle( mapping ); 2829 fdi.DoDeleteFile = TRUE; 2830 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2831 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); 2832 CloseHandle( handle ); 2833 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2834 ok( fileDeleted, "File should have been deleted\n" ); 2835 DeleteFileA( buffer ); 2836 2837 /* cannot set disposition on file which is mapped to memory */ 2838 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2839 handle = CreateFileA(buffer, GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0); 2840 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2841 mapping = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 64 * 1024, "DelFileTest" ); 2842 ok( mapping != NULL, "failed to create file mapping\n"); 2843 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 ); 2844 ok( ptr != NULL, "MapViewOfFile failed\n"); 2845 CloseHandle( mapping ); 2846 fdi.DoDeleteFile = TRUE; 2847 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2848 ok( res == STATUS_CANNOT_DELETE, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res ); 2849 CloseHandle( handle ); 2850 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2851 ok( !fileDeleted, "File shouldn't have been deleted\n" ); 2852 UnmapViewOfFile( ptr ); 2853 DeleteFileA( buffer ); 2854 2855 /* can set disposition on file which is mapped to memory and unmapped again */ 2856 GetTempFileNameA( tmp_path, "dis", 0, buffer ); 2857 handle = CreateFileA(buffer, GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0); 2858 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); 2859 mapping = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 64 * 1024, "DelFileTest" ); 2860 ok( mapping != NULL, "failed to create file mapping\n"); 2861 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 ); 2862 ok( ptr != NULL, "MapViewOfFile failed\n"); 2863 CloseHandle( mapping ); 2864 UnmapViewOfFile( ptr ); 2865 fdi.DoDeleteFile = TRUE; 2866 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); 2867 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); 2868 CloseHandle( handle ); 2869 fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; 2870 ok( fileDeleted, "File should have been deleted\n" ); 2871 DeleteFileA( buffer ); 2872 } 2873 2874 static void test_iocompletion(void) 2875 { 2876 HANDLE h = INVALID_HANDLE_VALUE; 2877 NTSTATUS res; 2878 2879 res = pNtCreateIoCompletion( &h, IO_COMPLETION_ALL_ACCESS, NULL, 0); 2880 2881 ok( res == 0, "NtCreateIoCompletion anonymous failed: %x\n", res ); 2882 ok( h && h != INVALID_HANDLE_VALUE, "Invalid handle returned\n" ); 2883 2884 if ( h && h != INVALID_HANDLE_VALUE) 2885 { 2886 test_iocp_setcompletion(h); 2887 test_iocp_fileio(h); 2888 pNtClose(h); 2889 } 2890 } 2891 2892 static void test_file_name_information(void) 2893 { 2894 WCHAR *file_name, *volume_prefix, *expected; 2895 FILE_NAME_INFORMATION *info; 2896 ULONG old_redir = 1, tmp; 2897 UINT file_name_size; 2898 IO_STATUS_BLOCK io; 2899 UINT info_size; 2900 HRESULT hr; 2901 HANDLE h; 2902 UINT len; 2903 2904 /* GetVolumePathName is not present before w2k */ 2905 if (!pGetVolumePathNameW) { 2906 win_skip("GetVolumePathNameW not found\n"); 2907 return; 2908 } 2909 2910 file_name_size = GetSystemDirectoryW( NULL, 0 ); 2911 file_name = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*file_name) ); 2912 volume_prefix = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) ); 2913 expected = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) ); 2914 2915 len = GetSystemDirectoryW( file_name, file_name_size ); 2916 ok(len == file_name_size - 1, 2917 "GetSystemDirectoryW returned %u, expected %u.\n", 2918 len, file_name_size - 1); 2919 2920 len = pGetVolumePathNameW( file_name, volume_prefix, file_name_size ); 2921 ok(len, "GetVolumePathNameW failed.\n"); 2922 2923 len = lstrlenW( volume_prefix ); 2924 if (len && volume_prefix[len - 1] == '\\') --len; 2925 memcpy( expected, file_name + len, (file_name_size - len - 1) * sizeof(WCHAR) ); 2926 expected[file_name_size - len - 1] = '\0'; 2927 2928 /* A bit more than we actually need, but it keeps the calculation simple. */ 2929 info_size = sizeof(*info) + (file_name_size * sizeof(WCHAR)); 2930 info = HeapAlloc( GetProcessHeap(), 0, info_size ); 2931 2932 if (pRtlWow64EnableFsRedirectionEx) pRtlWow64EnableFsRedirectionEx( TRUE, &old_redir ); 2933 h = CreateFileW( file_name, GENERIC_READ, 2934 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 2935 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2936 if (pRtlWow64EnableFsRedirectionEx) pRtlWow64EnableFsRedirectionEx( old_redir, &tmp ); 2937 ok(h != INVALID_HANDLE_VALUE, "Failed to open file.\n"); 2938 2939 hr = pNtQueryInformationFile( h, &io, info, sizeof(*info) - 1, FileNameInformation ); 2940 ok(hr == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationFile returned %#x.\n", hr); 2941 2942 memset( info, 0xcc, info_size ); 2943 hr = pNtQueryInformationFile( h, &io, info, sizeof(*info), FileNameInformation ); 2944 ok(hr == STATUS_BUFFER_OVERFLOW, "NtQueryInformationFile returned %#x, expected %#x.\n", 2945 hr, STATUS_BUFFER_OVERFLOW); 2946 ok(U(io).Status == STATUS_BUFFER_OVERFLOW, "io.Status is %#x, expected %#x.\n", 2947 U(io).Status, STATUS_BUFFER_OVERFLOW); 2948 ok(info->FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), "info->FileNameLength is %u\n", info->FileNameLength); 2949 ok(info->FileName[2] == 0xcccc, "info->FileName[2] is %#x, expected 0xcccc.\n", info->FileName[2]); 2950 ok(CharLowerW((LPWSTR)(UINT_PTR)info->FileName[1]) == CharLowerW((LPWSTR)(UINT_PTR)expected[1]), 2951 "info->FileName[1] is %p, expected %p.\n", 2952 CharLowerW((LPWSTR)(UINT_PTR)info->FileName[1]), CharLowerW((LPWSTR)(UINT_PTR)expected[1])); 2953 ok(io.Information == sizeof(*info), "io.Information is %lu\n", io.Information); 2954 2955 memset( info, 0xcc, info_size ); 2956 hr = pNtQueryInformationFile( h, &io, info, info_size, FileNameInformation ); 2957 ok(hr == STATUS_SUCCESS, "NtQueryInformationFile returned %#x, expected %#x.\n", hr, STATUS_SUCCESS); 2958 ok(U(io).Status == STATUS_SUCCESS, "io.Status is %#x, expected %#x.\n", U(io).Status, STATUS_SUCCESS); 2959 ok(info->FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), "info->FileNameLength is %u\n", info->FileNameLength); 2960 ok(info->FileName[info->FileNameLength / sizeof(WCHAR)] == 0xcccc, "info->FileName[len] is %#x, expected 0xcccc.\n", 2961 info->FileName[info->FileNameLength / sizeof(WCHAR)]); 2962 info->FileName[info->FileNameLength / sizeof(WCHAR)] = '\0'; 2963 ok(!lstrcmpiW( info->FileName, expected ), "info->FileName is %s, expected %s.\n", 2964 wine_dbgstr_w( info->FileName ), wine_dbgstr_w( expected )); 2965 ok(io.Information == FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + info->FileNameLength, 2966 "io.Information is %lu, expected %u.\n", 2967 io.Information, FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + info->FileNameLength); 2968 2969 CloseHandle( h ); 2970 HeapFree( GetProcessHeap(), 0, info ); 2971 HeapFree( GetProcessHeap(), 0, expected ); 2972 HeapFree( GetProcessHeap(), 0, volume_prefix ); 2973 2974 if (old_redir || !pGetSystemWow64DirectoryW || !(file_name_size = pGetSystemWow64DirectoryW( NULL, 0 ))) 2975 { 2976 skip("Not running on WoW64, skipping test.\n"); 2977 HeapFree( GetProcessHeap(), 0, file_name ); 2978 return; 2979 } 2980 2981 h = CreateFileW( file_name, GENERIC_READ, 2982 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 2983 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 2984 ok(h != INVALID_HANDLE_VALUE, "Failed to open file.\n"); 2985 HeapFree( GetProcessHeap(), 0, file_name ); 2986 2987 file_name = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*file_name) ); 2988 volume_prefix = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) ); 2989 expected = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*expected) ); 2990 2991 len = pGetSystemWow64DirectoryW( file_name, file_name_size ); 2992 ok(len == file_name_size - 1, 2993 "GetSystemWow64DirectoryW returned %u, expected %u.\n", 2994 len, file_name_size - 1); 2995 2996 len = pGetVolumePathNameW( file_name, volume_prefix, file_name_size ); 2997 ok(len, "GetVolumePathNameW failed.\n"); 2998 2999 len = lstrlenW( volume_prefix ); 3000 if (len && volume_prefix[len - 1] == '\\') --len; 3001 memcpy( expected, file_name + len, (file_name_size - len - 1) * sizeof(WCHAR) ); 3002 expected[file_name_size - len - 1] = '\0'; 3003 3004 info_size = sizeof(*info) + (file_name_size * sizeof(WCHAR)); 3005 info = HeapAlloc( GetProcessHeap(), 0, info_size ); 3006 3007 memset( info, 0xcc, info_size ); 3008 hr = pNtQueryInformationFile( h, &io, info, info_size, FileNameInformation ); 3009 ok(hr == STATUS_SUCCESS, "NtQueryInformationFile returned %#x, expected %#x.\n", hr, STATUS_SUCCESS); 3010 info->FileName[info->FileNameLength / sizeof(WCHAR)] = '\0'; 3011 ok(!lstrcmpiW( info->FileName, expected ), "info->FileName is %s, expected %s.\n", 3012 wine_dbgstr_w( info->FileName ), wine_dbgstr_w( expected )); 3013 3014 CloseHandle( h ); 3015 HeapFree( GetProcessHeap(), 0, info ); 3016 HeapFree( GetProcessHeap(), 0, expected ); 3017 HeapFree( GetProcessHeap(), 0, volume_prefix ); 3018 HeapFree( GetProcessHeap(), 0, file_name ); 3019 } 3020 3021 static void test_file_all_name_information(void) 3022 { 3023 WCHAR *file_name, *volume_prefix, *expected; 3024 FILE_ALL_INFORMATION *info; 3025 ULONG old_redir = 1, tmp; 3026 UINT file_name_size; 3027 IO_STATUS_BLOCK io; 3028 UINT info_size; 3029 HRESULT hr; 3030 HANDLE h; 3031 UINT len; 3032 3033 /* GetVolumePathName is not present before w2k */ 3034 if (!pGetVolumePathNameW) { 3035 win_skip("GetVolumePathNameW not found\n"); 3036 return; 3037 } 3038 3039 file_name_size = GetSystemDirectoryW( NULL, 0 ); 3040 file_name = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*file_name) ); 3041 volume_prefix = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) ); 3042 expected = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) ); 3043 3044 len = GetSystemDirectoryW( file_name, file_name_size ); 3045 ok(len == file_name_size - 1, 3046 "GetSystemDirectoryW returned %u, expected %u.\n", 3047 len, file_name_size - 1); 3048 3049 len = pGetVolumePathNameW( file_name, volume_prefix, file_name_size ); 3050 ok(len, "GetVolumePathNameW failed.\n"); 3051 3052 len = lstrlenW( volume_prefix ); 3053 if (len && volume_prefix[len - 1] == '\\') --len; 3054 memcpy( expected, file_name + len, (file_name_size - len - 1) * sizeof(WCHAR) ); 3055 expected[file_name_size - len - 1] = '\0'; 3056 3057 /* A bit more than we actually need, but it keeps the calculation simple. */ 3058 info_size = sizeof(*info) + (file_name_size * sizeof(WCHAR)); 3059 info = HeapAlloc( GetProcessHeap(), 0, info_size ); 3060 3061 if (pRtlWow64EnableFsRedirectionEx) pRtlWow64EnableFsRedirectionEx( TRUE, &old_redir ); 3062 h = CreateFileW( file_name, GENERIC_READ, 3063 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 3064 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 3065 if (pRtlWow64EnableFsRedirectionEx) pRtlWow64EnableFsRedirectionEx( old_redir, &tmp ); 3066 ok(h != INVALID_HANDLE_VALUE, "Failed to open file.\n"); 3067 3068 hr = pNtQueryInformationFile( h, &io, info, sizeof(*info) - 1, FileAllInformation ); 3069 ok(hr == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationFile returned %#x, expected %#x.\n", 3070 hr, STATUS_INFO_LENGTH_MISMATCH); 3071 3072 memset( info, 0xcc, info_size ); 3073 hr = pNtQueryInformationFile( h, &io, info, sizeof(*info), FileAllInformation ); 3074 ok(hr == STATUS_BUFFER_OVERFLOW, "NtQueryInformationFile returned %#x, expected %#x.\n", 3075 hr, STATUS_BUFFER_OVERFLOW); 3076 ok(U(io).Status == STATUS_BUFFER_OVERFLOW, "io.Status is %#x, expected %#x.\n", 3077 U(io).Status, STATUS_BUFFER_OVERFLOW); 3078 ok(info->NameInformation.FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), 3079 "info->NameInformation.FileNameLength is %u\n", info->NameInformation.FileNameLength ); 3080 ok(info->NameInformation.FileName[2] == 0xcccc, 3081 "info->NameInformation.FileName[2] is %#x, expected 0xcccc.\n", info->NameInformation.FileName[2]); 3082 ok(CharLowerW((LPWSTR)(UINT_PTR)info->NameInformation.FileName[1]) == CharLowerW((LPWSTR)(UINT_PTR)expected[1]), 3083 "info->NameInformation.FileName[1] is %p, expected %p.\n", 3084 CharLowerW((LPWSTR)(UINT_PTR)info->NameInformation.FileName[1]), CharLowerW((LPWSTR)(UINT_PTR)expected[1])); 3085 ok(io.Information == sizeof(*info), "io.Information is %lu\n", io.Information); 3086 3087 memset( info, 0xcc, info_size ); 3088 hr = pNtQueryInformationFile( h, &io, info, info_size, FileAllInformation ); 3089 ok(hr == STATUS_SUCCESS, "NtQueryInformationFile returned %#x, expected %#x.\n", hr, STATUS_SUCCESS); 3090 ok(U(io).Status == STATUS_SUCCESS, "io.Status is %#x, expected %#x.\n", U(io).Status, STATUS_SUCCESS); 3091 ok(info->NameInformation.FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), 3092 "info->NameInformation.FileNameLength is %u\n", info->NameInformation.FileNameLength ); 3093 ok(info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)] == 0xcccc, 3094 "info->NameInformation.FileName[len] is %#x, expected 0xcccc.\n", 3095 info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)]); 3096 info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)] = '\0'; 3097 ok(!lstrcmpiW( info->NameInformation.FileName, expected ), 3098 "info->NameInformation.FileName is %s, expected %s.\n", 3099 wine_dbgstr_w( info->NameInformation.FileName ), wine_dbgstr_w( expected )); 3100 ok(io.Information == FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) 3101 + info->NameInformation.FileNameLength, 3102 "io.Information is %lu\n", io.Information ); 3103 3104 CloseHandle( h ); 3105 HeapFree( GetProcessHeap(), 0, info ); 3106 HeapFree( GetProcessHeap(), 0, expected ); 3107 HeapFree( GetProcessHeap(), 0, volume_prefix ); 3108 3109 if (old_redir || !pGetSystemWow64DirectoryW || !(file_name_size = pGetSystemWow64DirectoryW( NULL, 0 ))) 3110 { 3111 skip("Not running on WoW64, skipping test.\n"); 3112 HeapFree( GetProcessHeap(), 0, file_name ); 3113 return; 3114 } 3115 3116 h = CreateFileW( file_name, GENERIC_READ, 3117 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 3118 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ); 3119 ok(h != INVALID_HANDLE_VALUE, "Failed to open file.\n"); 3120 HeapFree( GetProcessHeap(), 0, file_name ); 3121 3122 file_name = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*file_name) ); 3123 volume_prefix = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) ); 3124 expected = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*expected) ); 3125 3126 len = pGetSystemWow64DirectoryW( file_name, file_name_size ); 3127 ok(len == file_name_size - 1, 3128 "GetSystemWow64DirectoryW returned %u, expected %u.\n", 3129 len, file_name_size - 1); 3130 3131 len = pGetVolumePathNameW( file_name, volume_prefix, file_name_size ); 3132 ok(len, "GetVolumePathNameW failed.\n"); 3133 3134 len = lstrlenW( volume_prefix ); 3135 if (len && volume_prefix[len - 1] == '\\') --len; 3136 memcpy( expected, file_name + len, (file_name_size - len - 1) * sizeof(WCHAR) ); 3137 expected[file_name_size - len - 1] = '\0'; 3138 3139 info_size = sizeof(*info) + (file_name_size * sizeof(WCHAR)); 3140 info = HeapAlloc( GetProcessHeap(), 0, info_size ); 3141 3142 memset( info, 0xcc, info_size ); 3143 hr = pNtQueryInformationFile( h, &io, info, info_size, FileAllInformation ); 3144 ok(hr == STATUS_SUCCESS, "NtQueryInformationFile returned %#x, expected %#x.\n", hr, STATUS_SUCCESS); 3145 info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)] = '\0'; 3146 ok(!lstrcmpiW( info->NameInformation.FileName, expected ), "info->NameInformation.FileName is %s, expected %s.\n", 3147 wine_dbgstr_w( info->NameInformation.FileName ), wine_dbgstr_w( expected )); 3148 3149 CloseHandle( h ); 3150 HeapFree( GetProcessHeap(), 0, info ); 3151 HeapFree( GetProcessHeap(), 0, expected ); 3152 HeapFree( GetProcessHeap(), 0, volume_prefix ); 3153 HeapFree( GetProcessHeap(), 0, file_name ); 3154 } 3155 3156 static void test_file_completion_information(void) 3157 { 3158 static const char buf[] = "testdata"; 3159 FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info; 3160 OVERLAPPED ov, *pov; 3161 IO_STATUS_BLOCK io; 3162 NTSTATUS status; 3163 DWORD num_bytes; 3164 HANDLE port, h; 3165 ULONG_PTR key; 3166 BOOL ret; 3167 int i; 3168 3169 if (!(h = create_temp_file(0))) return; 3170 3171 status = pNtSetInformationFile(h, &io, &info, sizeof(info) - 1, FileIoCompletionNotificationInformation); 3172 ok(status == STATUS_INFO_LENGTH_MISMATCH || status == STATUS_INVALID_INFO_CLASS /* XP */, 3173 "expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); 3174 if (status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED) 3175 { 3176 win_skip("FileIoCompletionNotificationInformation class not supported\n"); 3177 CloseHandle(h); 3178 return; 3179 } 3180 3181 info.Flags = FILE_SKIP_COMPLETION_PORT_ON_SUCCESS; 3182 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); 3183 ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %08x\n", status); 3184 3185 CloseHandle(h); 3186 if (!(h = create_temp_file(FILE_FLAG_OVERLAPPED))) return; 3187 3188 info.Flags = FILE_SKIP_SET_EVENT_ON_HANDLE; 3189 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); 3190 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); 3191 3192 info.Flags = FILE_SKIP_SET_USER_EVENT_ON_FAST_IO; 3193 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); 3194 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); 3195 3196 CloseHandle(h); 3197 if (!(h = create_temp_file(FILE_FLAG_OVERLAPPED))) return; 3198 3199 info.Flags = ~0U; 3200 status = pNtQueryInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); 3201 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); 3202 ok(!(info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS), "got %08x\n", info.Flags); 3203 3204 memset(&ov, 0, sizeof(ov)); 3205 ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL); 3206 port = CreateIoCompletionPort(h, NULL, 0xdeadbeef, 0); 3207 ok(port != NULL, "CreateIoCompletionPort failed, error %u\n", GetLastError()); 3208 3209 for (i = 0; i < 10; i++) 3210 { 3211 SetLastError(0xdeadbeef); 3212 ret = WriteFile(h, buf, sizeof(buf), &num_bytes, &ov); 3213 if (ret || GetLastError() != ERROR_IO_PENDING) break; 3214 ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE); 3215 ok(ret, "GetOverlappedResult failed, error %u\n", GetLastError()); 3216 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000); 3217 ok(ret, "GetQueuedCompletionStatus failed, error %u\n", GetLastError()); 3218 ret = FALSE; 3219 } 3220 if (ret) 3221 { 3222 ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %u\n", num_bytes); 3223 3224 key = 0; 3225 pov = NULL; 3226 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000); 3227 ok(ret, "GetQueuedCompletionStatus failed, error %u\n", GetLastError()); 3228 ok(key == 0xdeadbeef, "expected 0xdeadbeef, got %lx\n", key); 3229 ok(pov == &ov, "expected %p, got %p\n", &ov, pov); 3230 } 3231 else 3232 win_skip("WriteFile never returned TRUE\n"); 3233 3234 info.Flags = FILE_SKIP_COMPLETION_PORT_ON_SUCCESS; 3235 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); 3236 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); 3237 3238 info.Flags = 0; 3239 status = pNtQueryInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); 3240 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); 3241 ok((info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS) != 0, "got %08x\n", info.Flags); 3242 3243 for (i = 0; i < 10; i++) 3244 { 3245 SetLastError(0xdeadbeef); 3246 ret = WriteFile(h, buf, sizeof(buf), &num_bytes, &ov); 3247 if (ret || GetLastError() != ERROR_IO_PENDING) break; 3248 ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE); 3249 ok(ret, "GetOverlappedResult failed, error %u\n", GetLastError()); 3250 ret = FALSE; 3251 } 3252 if (ret) 3253 { 3254 ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %u\n", num_bytes); 3255 3256 pov = (void *)0xdeadbeef; 3257 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 500); 3258 ok(!ret, "GetQueuedCompletionStatus succeeded\n"); 3259 ok(pov == NULL, "expected NULL, got %p\n", pov); 3260 } 3261 else 3262 win_skip("WriteFile never returned TRUE\n"); 3263 3264 info.Flags = 0; 3265 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); 3266 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); 3267 3268 info.Flags = 0; 3269 status = pNtQueryInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); 3270 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); 3271 ok((info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS) != 0, "got %08x\n", info.Flags); 3272 3273 for (i = 0; i < 10; i++) 3274 { 3275 SetLastError(0xdeadbeef); 3276 ret = WriteFile(h, buf, sizeof(buf), &num_bytes, &ov); 3277 if (ret || GetLastError() != ERROR_IO_PENDING) break; 3278 ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE); 3279 ok(ret, "GetOverlappedResult failed, error %u\n", GetLastError()); 3280 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000); 3281 ok(ret, "GetQueuedCompletionStatus failed, error %u\n", GetLastError()); 3282 ret = FALSE; 3283 } 3284 if (ret) 3285 { 3286 ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %u\n", num_bytes); 3287 3288 pov = (void *)0xdeadbeef; 3289 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000); 3290 ok(!ret, "GetQueuedCompletionStatus succeeded\n"); 3291 ok(pov == NULL, "expected NULL, got %p\n", pov); 3292 } 3293 else 3294 win_skip("WriteFile never returned TRUE\n"); 3295 3296 CloseHandle(ov.hEvent); 3297 CloseHandle(port); 3298 CloseHandle(h); 3299 } 3300 3301 static void test_file_id_information(void) 3302 { 3303 BY_HANDLE_FILE_INFORMATION info; 3304 FILE_ID_INFORMATION fid; 3305 IO_STATUS_BLOCK io; 3306 NTSTATUS status; 3307 DWORD *dwords; 3308 HANDLE h; 3309 BOOL ret; 3310 3311 if (!(h = create_temp_file(0))) return; 3312 3313 memset( &fid, 0x11, sizeof(fid) ); 3314 status = pNtQueryInformationFile( h, &io, &fid, sizeof(fid), FileIdInformation ); 3315 if (status == STATUS_NOT_IMPLEMENTED || status == STATUS_INVALID_INFO_CLASS) 3316 { 3317 win_skip( "FileIdInformation not supported\n" ); 3318 CloseHandle( h ); 3319 return; 3320 } 3321 3322 memset( &info, 0x22, sizeof(info) ); 3323 ret = GetFileInformationByHandle( h, &info ); 3324 ok( ret, "GetFileInformationByHandle failed\n" ); 3325 3326 dwords = (DWORD *)&fid.VolumeSerialNumber; 3327 ok( dwords[0] == info.dwVolumeSerialNumber, "expected %08x, got %08x\n", 3328 info.dwVolumeSerialNumber, dwords[0] ); 3329 ok( dwords[1] != 0x11111111, "expected != 0x11111111\n" ); 3330 3331 dwords = (DWORD *)&fid.FileId; 3332 ok( dwords[0] == info.nFileIndexLow, "expected %08x, got %08x\n", info.nFileIndexLow, dwords[0] ); 3333 ok( dwords[1] == info.nFileIndexHigh, "expected %08x, got %08x\n", info.nFileIndexHigh, dwords[1] ); 3334 ok( dwords[2] == 0, "expected 0, got %08x\n", dwords[2] ); 3335 ok( dwords[3] == 0, "expected 0, got %08x\n", dwords[3] ); 3336 3337 CloseHandle( h ); 3338 } 3339 3340 static void test_file_access_information(void) 3341 { 3342 FILE_ACCESS_INFORMATION info; 3343 IO_STATUS_BLOCK io; 3344 NTSTATUS status; 3345 HANDLE h; 3346 3347 if (!(h = create_temp_file(0))) return; 3348 3349 status = pNtQueryInformationFile( h, &io, &info, sizeof(info) - 1, FileAccessInformation ); 3350 ok( status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status ); 3351 3352 status = pNtQueryInformationFile( (HANDLE)0xdeadbeef, &io, &info, sizeof(info), FileAccessInformation ); 3353 ok( status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %08x\n", status ); 3354 3355 memset(&info, 0x11, sizeof(info)); 3356 status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileAccessInformation ); 3357 ok( status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status ); 3358 ok( info.AccessFlags == 0x13019f, "got %08x\n", info.AccessFlags ); 3359 3360 CloseHandle( h ); 3361 } 3362 3363 static void test_query_volume_information_file(void) 3364 { 3365 NTSTATUS status; 3366 HANDLE dir; 3367 WCHAR path[MAX_PATH]; 3368 OBJECT_ATTRIBUTES attr; 3369 IO_STATUS_BLOCK io; 3370 UNICODE_STRING nameW; 3371 FILE_FS_VOLUME_INFORMATION *ffvi; 3372 BYTE buf[sizeof(FILE_FS_VOLUME_INFORMATION) + MAX_PATH * sizeof(WCHAR)]; 3373 3374 GetWindowsDirectoryW( path, MAX_PATH ); 3375 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL ); 3376 attr.Length = sizeof(attr); 3377 attr.RootDirectory = 0; 3378 attr.ObjectName = &nameW; 3379 attr.Attributes = OBJ_CASE_INSENSITIVE; 3380 attr.SecurityDescriptor = NULL; 3381 attr.SecurityQualityOfService = NULL; 3382 3383 status = pNtOpenFile( &dir, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io, 3384 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT ); 3385 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 3386 pRtlFreeUnicodeString( &nameW ); 3387 3388 ZeroMemory( buf, sizeof(buf) ); 3389 U(io).Status = 0xdadadada; 3390 io.Information = 0xcacacaca; 3391 3392 status = pNtQueryVolumeInformationFile( dir, &io, buf, sizeof(buf), FileFsVolumeInformation ); 3393 3394 ffvi = (FILE_FS_VOLUME_INFORMATION *)buf; 3395 3396 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %d\n", status); 3397 ok(U(io).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %d\n", U(io).Status); 3398 3399 todo_wine 3400 { 3401 ok(io.Information == (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + ffvi->VolumeLabelLength), 3402 "expected %d, got %lu\n", (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + ffvi->VolumeLabelLength), 3403 io.Information); 3404 3405 ok(ffvi->VolumeCreationTime.QuadPart != 0, "Missing VolumeCreationTime\n"); 3406 ok(ffvi->VolumeSerialNumber != 0, "Missing VolumeSerialNumber\n"); 3407 ok(ffvi->SupportsObjects == 1,"expected 1, got %d\n", ffvi->SupportsObjects); 3408 } 3409 ok(ffvi->VolumeLabelLength == lstrlenW(ffvi->VolumeLabel) * sizeof(WCHAR), "got %d\n", ffvi->VolumeLabelLength); 3410 3411 trace("VolumeSerialNumber: %x VolumeLabelName: %s\n", ffvi->VolumeSerialNumber, wine_dbgstr_w(ffvi->VolumeLabel)); 3412 3413 CloseHandle( dir ); 3414 } 3415 3416 static void test_query_attribute_information_file(void) 3417 { 3418 NTSTATUS status; 3419 HANDLE dir; 3420 WCHAR path[MAX_PATH]; 3421 OBJECT_ATTRIBUTES attr; 3422 IO_STATUS_BLOCK io; 3423 UNICODE_STRING nameW; 3424 FILE_FS_ATTRIBUTE_INFORMATION *ffai; 3425 BYTE buf[sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + MAX_PATH * sizeof(WCHAR)]; 3426 3427 GetWindowsDirectoryW( path, MAX_PATH ); 3428 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL ); 3429 attr.Length = sizeof(attr); 3430 attr.RootDirectory = 0; 3431 attr.ObjectName = &nameW; 3432 attr.Attributes = OBJ_CASE_INSENSITIVE; 3433 attr.SecurityDescriptor = NULL; 3434 attr.SecurityQualityOfService = NULL; 3435 3436 status = pNtOpenFile( &dir, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io, 3437 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT ); 3438 ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); 3439 pRtlFreeUnicodeString( &nameW ); 3440 3441 ZeroMemory( buf, sizeof(buf) ); 3442 U(io).Status = 0xdadadada; 3443 io.Information = 0xcacacaca; 3444 3445 status = pNtQueryVolumeInformationFile( dir, &io, buf, sizeof(buf), FileFsAttributeInformation ); 3446 3447 ffai = (FILE_FS_ATTRIBUTE_INFORMATION *)buf; 3448 3449 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %d\n", status); 3450 ok(U(io).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %d\n", U(io).Status); 3451 ok(ffai->FileSystemAttribute != 0, "Missing FileSystemAttribute\n"); 3452 ok(ffai->MaximumComponentNameLength != 0, "Missing MaximumComponentNameLength\n"); 3453 ok(ffai->FileSystemNameLength != 0, "Missing FileSystemNameLength\n"); 3454 3455 trace("FileSystemAttribute: %x MaximumComponentNameLength: %x FileSystemName: %s\n", 3456 ffai->FileSystemAttribute, ffai->MaximumComponentNameLength, 3457 wine_dbgstr_wn(ffai->FileSystemName, ffai->FileSystemNameLength / sizeof(WCHAR))); 3458 3459 CloseHandle( dir ); 3460 } 3461 3462 static void test_NtCreateFile(void) 3463 { 3464 static const struct test_data 3465 { 3466 DWORD disposition, attrib_in, status, result, attrib_out, needs_cleanup; 3467 } td[] = 3468 { 3469 /* 0*/{ FILE_CREATE, FILE_ATTRIBUTE_READONLY, 0, FILE_CREATED, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY, FALSE }, 3470 /* 1*/{ FILE_CREATE, 0, STATUS_OBJECT_NAME_COLLISION, 0, 0, TRUE }, 3471 /* 2*/{ FILE_CREATE, 0, 0, FILE_CREATED, FILE_ATTRIBUTE_ARCHIVE, FALSE }, 3472 /* 3*/{ FILE_OPEN, FILE_ATTRIBUTE_READONLY, 0, FILE_OPENED, FILE_ATTRIBUTE_ARCHIVE, TRUE }, 3473 /* 4*/{ FILE_OPEN, FILE_ATTRIBUTE_READONLY, STATUS_OBJECT_NAME_NOT_FOUND, 0, 0, FALSE }, 3474 /* 5*/{ FILE_OPEN_IF, 0, 0, FILE_CREATED, FILE_ATTRIBUTE_ARCHIVE, FALSE }, 3475 /* 6*/{ FILE_OPEN_IF, FILE_ATTRIBUTE_READONLY, 0, FILE_OPENED, FILE_ATTRIBUTE_ARCHIVE, TRUE }, 3476 /* 7*/{ FILE_OPEN_IF, FILE_ATTRIBUTE_READONLY, 0, FILE_CREATED, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY, FALSE }, 3477 /* 8*/{ FILE_OPEN_IF, 0, 0, FILE_OPENED, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY, FALSE }, 3478 /* 9*/{ FILE_OVERWRITE, 0, STATUS_ACCESS_DENIED, 0, 0, TRUE }, 3479 /*10*/{ FILE_OVERWRITE, 0, STATUS_OBJECT_NAME_NOT_FOUND, 0, 0, FALSE }, 3480 /*11*/{ FILE_CREATE, 0, 0, FILE_CREATED, FILE_ATTRIBUTE_ARCHIVE, FALSE }, 3481 /*12*/{ FILE_OVERWRITE, FILE_ATTRIBUTE_READONLY, 0, FILE_OVERWRITTEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY, FALSE }, 3482 /*13*/{ FILE_OVERWRITE_IF, 0, STATUS_ACCESS_DENIED, 0, 0, TRUE }, 3483 /*14*/{ FILE_OVERWRITE_IF, 0, 0, FILE_CREATED, FILE_ATTRIBUTE_ARCHIVE, FALSE }, 3484 /*15*/{ FILE_OVERWRITE_IF, FILE_ATTRIBUTE_READONLY, 0, FILE_OVERWRITTEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY, FALSE }, 3485 /*16*/{ FILE_SUPERSEDE, 0, 0, FILE_SUPERSEDED, FILE_ATTRIBUTE_ARCHIVE, FALSE }, 3486 /*17*/{ FILE_SUPERSEDE, FILE_ATTRIBUTE_READONLY, 0, FILE_SUPERSEDED, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY, TRUE }, 3487 /*18*/{ FILE_SUPERSEDE, 0, 0, FILE_CREATED, FILE_ATTRIBUTE_ARCHIVE, TRUE } 3488 }; 3489 static const WCHAR fooW[] = {'f','o','o',0}; 3490 NTSTATUS status; 3491 HANDLE handle; 3492 WCHAR path[MAX_PATH]; 3493 OBJECT_ATTRIBUTES attr; 3494 IO_STATUS_BLOCK io; 3495 UNICODE_STRING nameW; 3496 DWORD ret, i; 3497 3498 GetTempPathW(MAX_PATH, path); 3499 GetTempFileNameW(path, fooW, 0, path); 3500 DeleteFileW(path); 3501 pRtlDosPathNameToNtPathName_U(path, &nameW, NULL, NULL); 3502 3503 attr.Length = sizeof(attr); 3504 attr.RootDirectory = NULL; 3505 attr.ObjectName = &nameW; 3506 attr.Attributes = OBJ_CASE_INSENSITIVE; 3507 attr.SecurityDescriptor = NULL; 3508 attr.SecurityQualityOfService = NULL; 3509 3510 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) 3511 { 3512 status = pNtCreateFile(&handle, GENERIC_READ, &attr, &io, NULL, 3513 td[i].attrib_in, FILE_SHARE_READ|FILE_SHARE_WRITE, 3514 td[i].disposition, 0, NULL, 0); 3515 3516 ok(status == td[i].status, "%d: expected %#x got %#x\n", i, td[i].status, status); 3517 3518 if (!status) 3519 { 3520 ok(io.Information == td[i].result,"%d: expected %#x got %#lx\n", i, td[i].result, io.Information); 3521 3522 ret = GetFileAttributesW(path); 3523 ret &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED; 3524 /* FIXME: leave only 'else' case below once Wine is fixed */ 3525 if (ret != td[i].attrib_out) 3526 { 3527 todo_wine 3528 ok(ret == td[i].attrib_out, "%d: expected %#x got %#x\n", i, td[i].attrib_out, ret); 3529 SetFileAttributesW(path, td[i].attrib_out); 3530 } 3531 else 3532 ok(ret == td[i].attrib_out, "%d: expected %#x got %#x\n", i, td[i].attrib_out, ret); 3533 3534 CloseHandle(handle); 3535 } 3536 3537 if (td[i].needs_cleanup) 3538 { 3539 SetFileAttributesW(path, FILE_ATTRIBUTE_ARCHIVE); 3540 DeleteFileW(path); 3541 } 3542 } 3543 3544 pRtlFreeUnicodeString( &nameW ); 3545 SetFileAttributesW(path, FILE_ATTRIBUTE_ARCHIVE); 3546 DeleteFileW( path ); 3547 } 3548 3549 static void test_readonly(void) 3550 { 3551 static const WCHAR fooW[] = {'f','o','o',0}; 3552 NTSTATUS status; 3553 HANDLE handle; 3554 WCHAR path[MAX_PATH]; 3555 OBJECT_ATTRIBUTES attr; 3556 IO_STATUS_BLOCK io; 3557 UNICODE_STRING nameW; 3558 3559 GetTempPathW(MAX_PATH, path); 3560 GetTempFileNameW(path, fooW, 0, path); 3561 DeleteFileW(path); 3562 pRtlDosPathNameToNtPathName_U(path, &nameW, NULL, NULL); 3563 3564 attr.Length = sizeof(attr); 3565 attr.RootDirectory = NULL; 3566 attr.ObjectName = &nameW; 3567 attr.Attributes = OBJ_CASE_INSENSITIVE; 3568 attr.SecurityDescriptor = NULL; 3569 attr.SecurityQualityOfService = NULL; 3570 3571 status = pNtCreateFile(&handle, GENERIC_READ, &attr, &io, NULL, FILE_ATTRIBUTE_READONLY, 3572 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_CREATE, 0, NULL, 0); 3573 ok(status == STATUS_SUCCESS, "got %#x\n", status); 3574 CloseHandle(handle); 3575 3576 status = pNtOpenFile(&handle, GENERIC_WRITE, &attr, &io, 3577 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN_FOR_BACKUP_INTENT); 3578 ok(status == STATUS_ACCESS_DENIED, "got %#x\n", status); 3579 CloseHandle(handle); 3580 3581 status = pNtOpenFile(&handle, GENERIC_READ, &attr, &io, 3582 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN_FOR_BACKUP_INTENT); 3583 ok(status == STATUS_SUCCESS, "got %#x\n", status); 3584 CloseHandle(handle); 3585 3586 status = pNtOpenFile(&handle, FILE_READ_ATTRIBUTES, &attr, &io, 3587 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN_FOR_BACKUP_INTENT); 3588 ok(status == STATUS_SUCCESS, "got %#x\n", status); 3589 CloseHandle(handle); 3590 3591 status = pNtOpenFile(&handle, FILE_WRITE_ATTRIBUTES, &attr, &io, 3592 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN_FOR_BACKUP_INTENT); 3593 ok(status == STATUS_SUCCESS, "got %#x\n", status); 3594 CloseHandle(handle); 3595 3596 status = pNtOpenFile(&handle, DELETE, &attr, &io, 3597 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN_FOR_BACKUP_INTENT); 3598 ok(status == STATUS_SUCCESS, "got %#x\n", status); 3599 CloseHandle(handle); 3600 3601 status = pNtOpenFile(&handle, READ_CONTROL, &attr, &io, 3602 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN_FOR_BACKUP_INTENT); 3603 ok(status == STATUS_SUCCESS, "got %#x\n", status); 3604 CloseHandle(handle); 3605 3606 status = pNtOpenFile(&handle, WRITE_DAC, &attr, &io, 3607 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN_FOR_BACKUP_INTENT); 3608 ok(status == STATUS_SUCCESS, "got %#x\n", status); 3609 CloseHandle(handle); 3610 3611 status = pNtOpenFile(&handle, WRITE_OWNER, &attr, &io, 3612 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN_FOR_BACKUP_INTENT); 3613 ok(status == STATUS_SUCCESS, "got %#x\n", status); 3614 CloseHandle(handle); 3615 3616 status = pNtOpenFile(&handle, SYNCHRONIZE, &attr, &io, 3617 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN_FOR_BACKUP_INTENT); 3618 ok(status == STATUS_SUCCESS, "got %#x\n", status); 3619 CloseHandle( handle ); 3620 3621 pRtlFreeUnicodeString(&nameW); 3622 SetFileAttributesW(path, FILE_ATTRIBUTE_ARCHIVE); 3623 DeleteFileW(path); 3624 } 3625 3626 static void test_read_write(void) 3627 { 3628 static const char contents[14] = "1234567890abcd"; 3629 char buf[256]; 3630 HANDLE hfile, event; 3631 OVERLAPPED ovl; 3632 IO_STATUS_BLOCK iob; 3633 DWORD ret, bytes, status, off; 3634 LARGE_INTEGER offset; 3635 LONG i; 3636 3637 event = CreateEventA( NULL, TRUE, FALSE, NULL ); 3638 3639 U(iob).Status = -1; 3640 iob.Information = -1; 3641 offset.QuadPart = 0; 3642 status = pNtReadFile(INVALID_HANDLE_VALUE, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 3643 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status); 3644 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3645 ok(iob.Information == -1, "expected -1, got %lu\n", iob.Information); 3646 3647 U(iob).Status = -1; 3648 iob.Information = -1; 3649 offset.QuadPart = 0; 3650 status = pNtReadFile(INVALID_HANDLE_VALUE, 0, NULL, NULL, &iob, NULL, sizeof(buf), &offset, NULL); 3651 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status); 3652 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3653 ok(iob.Information == -1, "expected -1, got %lu\n", iob.Information); 3654 3655 U(iob).Status = -1; 3656 iob.Information = -1; 3657 offset.QuadPart = 0; 3658 status = pNtWriteFile(INVALID_HANDLE_VALUE, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 3659 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status); 3660 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3661 ok(iob.Information == -1, "expected -1, got %lu\n", iob.Information); 3662 3663 U(iob).Status = -1; 3664 iob.Information = -1; 3665 offset.QuadPart = 0; 3666 status = pNtWriteFile(INVALID_HANDLE_VALUE, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 3667 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status); 3668 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3669 ok(iob.Information == -1, "expected -1, got %lu\n", iob.Information); 3670 3671 hfile = create_temp_file(0); 3672 if (!hfile) return; 3673 3674 U(iob).Status = -1; 3675 iob.Information = -1; 3676 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, NULL, sizeof(contents), NULL, NULL); 3677 ok(status == STATUS_INVALID_USER_BUFFER, "expected STATUS_INVALID_USER_BUFFER, got %#x\n", status); 3678 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3679 ok(iob.Information == -1, "expected -1, got %lu\n", iob.Information); 3680 3681 U(iob).Status = -1; 3682 iob.Information = -1; 3683 SetEvent(event); 3684 status = pNtWriteFile(hfile, event, NULL, NULL, &iob, NULL, sizeof(contents), NULL, NULL); 3685 ok(status == STATUS_INVALID_USER_BUFFER, "expected STATUS_INVALID_USER_BUFFER, got %#x\n", status); 3686 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3687 ok(iob.Information == -1, "expected -1, got %lu\n", iob.Information); 3688 ok(!is_signaled(event), "event is not signaled\n"); 3689 3690 U(iob).Status = -1; 3691 iob.Information = -1; 3692 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, NULL, sizeof(contents), NULL, NULL); 3693 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status); 3694 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3695 ok(iob.Information == -1, "expected -1, got %lu\n", iob.Information); 3696 3697 U(iob).Status = -1; 3698 iob.Information = -1; 3699 SetEvent(event); 3700 status = pNtReadFile(hfile, event, NULL, NULL, &iob, NULL, sizeof(contents), NULL, NULL); 3701 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status); 3702 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3703 ok(iob.Information == -1, "expected -1, got %lu\n", iob.Information); 3704 ok(is_signaled(event), "event is not signaled\n"); 3705 3706 U(iob).Status = -1; 3707 iob.Information = -1; 3708 SetEvent(event); 3709 status = pNtReadFile(hfile, event, NULL, NULL, &iob, (void*)0xdeadbeef, sizeof(contents), NULL, NULL); 3710 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status); 3711 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3712 ok(iob.Information == -1, "expected -1, got %lu\n", iob.Information); 3713 ok(is_signaled(event), "event is not signaled\n"); 3714 3715 U(iob).Status = -1; 3716 iob.Information = -1; 3717 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, 7, NULL, NULL); 3718 ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status); 3719 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 3720 ok(iob.Information == 7, "expected 7, got %lu\n", iob.Information); 3721 3722 SetFilePointer(hfile, 0, NULL, FILE_BEGIN); 3723 3724 U(iob).Status = -1; 3725 iob.Information = -1; 3726 offset.QuadPart = (LONGLONG)-1 /* FILE_WRITE_TO_END_OF_FILE */; 3727 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents + 7, sizeof(contents) - 7, &offset, NULL); 3728 ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status); 3729 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 3730 ok(iob.Information == sizeof(contents) - 7, "expected sizeof(contents)-7, got %lu\n", iob.Information); 3731 3732 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 3733 ok(off == sizeof(contents), "expected sizeof(contents), got %u\n", off); 3734 3735 bytes = 0xdeadbeef; 3736 SetLastError(0xdeadbeef); 3737 ret = ReadFile(INVALID_HANDLE_VALUE, buf, 0, &bytes, NULL); 3738 ok(!ret, "ReadFile should fail\n"); 3739 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 3740 ok(bytes == 0, "bytes %u\n", bytes); 3741 3742 bytes = 0xdeadbeef; 3743 SetLastError(0xdeadbeef); 3744 ret = ReadFile(hfile, buf, 0, &bytes, NULL); 3745 ok(ret, "ReadFile error %d\n", GetLastError()); 3746 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); 3747 ok(bytes == 0, "bytes %u\n", bytes); 3748 3749 bytes = 0xdeadbeef; 3750 SetLastError(0xdeadbeef); 3751 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL); 3752 ok(ret, "ReadFile error %d\n", GetLastError()); 3753 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); 3754 ok(bytes == 0, "bytes %u\n", bytes); 3755 3756 SetFilePointer(hfile, 0, NULL, FILE_BEGIN); 3757 3758 bytes = 0; 3759 SetLastError(0xdeadbeef); 3760 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL); 3761 ok(ret, "ReadFile error %d\n", GetLastError()); 3762 ok(bytes == sizeof(contents), "bytes %u\n", bytes); 3763 ok(!memcmp(contents, buf, sizeof(contents)), "file contents mismatch\n"); 3764 3765 for (i = -20; i < -1; i++) 3766 { 3767 if (i == -2) continue; 3768 3769 U(iob).Status = -1; 3770 iob.Information = -1; 3771 offset.QuadPart = (LONGLONG)i; 3772 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, sizeof(contents), &offset, NULL); 3773 ok(status == STATUS_INVALID_PARAMETER, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i, status); 3774 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3775 ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information); 3776 } 3777 3778 SetFilePointer(hfile, sizeof(contents) - 4, NULL, FILE_BEGIN); 3779 3780 U(iob).Status = -1; 3781 iob.Information = -1; 3782 offset.QuadPart = (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */; 3783 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, "DCBA", 4, &offset, NULL); 3784 ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status); 3785 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 3786 ok(iob.Information == 4, "expected 4, got %lu\n", iob.Information); 3787 3788 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 3789 ok(off == sizeof(contents), "expected sizeof(contents), got %u\n", off); 3790 3791 U(iob).Status = -1; 3792 iob.Information = -1; 3793 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), NULL, NULL); 3794 ok(status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#x\n", status); 3795 ok(U(iob).Status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#x\n", U(iob).Status); 3796 ok(iob.Information == 0, "expected 0, got %lu\n", iob.Information); 3797 3798 SetFilePointer(hfile, 0, NULL, FILE_BEGIN); 3799 3800 bytes = 0; 3801 SetLastError(0xdeadbeef); 3802 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL); 3803 ok(ret, "ReadFile error %d\n", GetLastError()); 3804 ok(bytes == sizeof(contents), "bytes %u\n", bytes); 3805 ok(!memcmp(contents, buf, sizeof(contents) - 4), "file contents mismatch\n"); 3806 ok(!memcmp(buf + sizeof(contents) - 4, "DCBA", 4), "file contents mismatch\n"); 3807 3808 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 3809 ok(off == sizeof(contents), "expected sizeof(contents), got %u\n", off); 3810 3811 SetFilePointer(hfile, 0, NULL, FILE_BEGIN); 3812 3813 bytes = 0; 3814 SetLastError(0xdeadbeef); 3815 ret = WriteFile(hfile, contents, sizeof(contents), &bytes, NULL); 3816 ok(ret, "WriteFile error %d\n", GetLastError()); 3817 ok(bytes == sizeof(contents), "bytes %u\n", bytes); 3818 3819 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 3820 ok(off == sizeof(contents), "expected sizeof(contents), got %u\n", off); 3821 3822 /* test reading beyond EOF */ 3823 bytes = -1; 3824 SetLastError(0xdeadbeef); 3825 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL); 3826 ok(ret, "ReadFile error %d\n", GetLastError()); 3827 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); 3828 ok(bytes == 0, "bytes %u\n", bytes); 3829 3830 bytes = -1; 3831 SetLastError(0xdeadbeef); 3832 ret = ReadFile(hfile, buf, 0, &bytes, NULL); 3833 ok(ret, "ReadFile error %d\n", GetLastError()); 3834 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); 3835 ok(bytes == 0, "bytes %u\n", bytes); 3836 3837 bytes = -1; 3838 SetLastError(0xdeadbeef); 3839 ret = ReadFile(hfile, NULL, 0, &bytes, NULL); 3840 ok(ret, "ReadFile error %d\n", GetLastError()); 3841 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); 3842 ok(bytes == 0, "bytes %u\n", bytes); 3843 3844 S(U(ovl)).Offset = sizeof(contents); 3845 S(U(ovl)).OffsetHigh = 0; 3846 ovl.Internal = -1; 3847 ovl.InternalHigh = -1; 3848 ovl.hEvent = 0; 3849 bytes = -1; 3850 SetLastError(0xdeadbeef); 3851 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl); 3852 ok(!ret, "ReadFile should fail\n"); 3853 ok(GetLastError() == ERROR_HANDLE_EOF, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError()); 3854 ok(bytes == 0, "bytes %u\n", bytes); 3855 ok((NTSTATUS)ovl.Internal == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", ovl.Internal); 3856 ok(ovl.InternalHigh == 0, "expected 0, got %lu\n", ovl.InternalHigh); 3857 3858 S(U(ovl)).Offset = sizeof(contents); 3859 S(U(ovl)).OffsetHigh = 0; 3860 ovl.Internal = -1; 3861 ovl.InternalHigh = -1; 3862 ovl.hEvent = 0; 3863 bytes = -1; 3864 SetLastError(0xdeadbeef); 3865 ret = ReadFile(hfile, buf, 0, &bytes, &ovl); 3866 ok(ret, "ReadFile error %d\n", GetLastError()); 3867 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); 3868 ok(bytes == 0, "bytes %u\n", bytes); 3869 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 3870 ok(ovl.InternalHigh == 0, "expected 0, got %lu\n", ovl.InternalHigh); 3871 3872 U(iob).Status = -1; 3873 iob.Information = -1; 3874 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), NULL, NULL); 3875 ok(status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#x\n", status); 3876 ok(U(iob).Status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#x\n", U(iob).Status); 3877 ok(iob.Information == 0, "expected 0, got %lu\n", iob.Information); 3878 3879 U(iob).Status = -1; 3880 iob.Information = -1; 3881 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, 0, NULL, NULL); 3882 ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status); 3883 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 3884 ok(iob.Information == 0, "expected 0, got %lu\n", iob.Information); 3885 3886 U(iob).Status = -1; 3887 iob.Information = -1; 3888 offset.QuadPart = sizeof(contents); 3889 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 3890 ok(status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#x\n", status); 3891 ok(U(iob).Status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#x\n", U(iob).Status); 3892 ok(iob.Information == 0, "expected 0, got %lu\n", iob.Information); 3893 3894 U(iob).Status = -1; 3895 iob.Information = -1; 3896 offset.QuadPart = sizeof(contents); 3897 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, 0, &offset, NULL); 3898 ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status); 3899 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 3900 ok(iob.Information == 0, "expected 0, got %lu\n", iob.Information); 3901 3902 U(iob).Status = -1; 3903 iob.Information = -1; 3904 offset.QuadPart = (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */; 3905 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 3906 ok(status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#x\n", status); 3907 ok(U(iob).Status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#x\n", U(iob).Status); 3908 ok(iob.Information == 0, "expected 0, got %lu\n", iob.Information); 3909 3910 U(iob).Status = -1; 3911 iob.Information = -1; 3912 offset.QuadPart = (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */; 3913 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, 0, &offset, NULL); 3914 ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status); 3915 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 3916 ok(iob.Information == 0, "expected 0, got %lu\n", iob.Information); 3917 3918 for (i = -20; i < 0; i++) 3919 { 3920 if (i == -2) continue; 3921 3922 U(iob).Status = -1; 3923 iob.Information = -1; 3924 offset.QuadPart = (LONGLONG)i; 3925 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 3926 ok(status == STATUS_INVALID_PARAMETER, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i, status); 3927 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 3928 ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information); 3929 } 3930 3931 SetFilePointer(hfile, 0, NULL, FILE_BEGIN); 3932 3933 bytes = 0; 3934 SetLastError(0xdeadbeef); 3935 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL); 3936 ok(ret, "ReadFile error %d\n", GetLastError()); 3937 ok(bytes == sizeof(contents), "bytes %u\n", bytes); 3938 ok(!memcmp(contents, buf, sizeof(contents)), "file contents mismatch\n"); 3939 3940 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 3941 ok(off == sizeof(contents), "expected sizeof(contents), got %u\n", off); 3942 3943 U(iob).Status = -1; 3944 iob.Information = -1; 3945 offset.QuadPart = 0; 3946 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 3947 ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status); 3948 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 3949 ok(iob.Information == sizeof(contents), "expected sizeof(contents), got %lu\n", iob.Information); 3950 ok(!memcmp(contents, buf, sizeof(contents)), "file contents mismatch\n"); 3951 3952 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 3953 ok(off == sizeof(contents), "expected sizeof(contents), got %u\n", off); 3954 3955 U(iob).Status = -1; 3956 iob.Information = -1; 3957 offset.QuadPart = sizeof(contents) - 4; 3958 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, "DCBA", 4, &offset, NULL); 3959 ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status); 3960 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 3961 ok(iob.Information == 4, "expected 4, got %lu\n", iob.Information); 3962 3963 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 3964 ok(off == sizeof(contents), "expected sizeof(contents), got %u\n", off); 3965 3966 U(iob).Status = -1; 3967 iob.Information = -1; 3968 offset.QuadPart = 0; 3969 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 3970 ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status); 3971 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 3972 ok(iob.Information == sizeof(contents), "expected sizeof(contents), got %lu\n", iob.Information); 3973 ok(!memcmp(contents, buf, sizeof(contents) - 4), "file contents mismatch\n"); 3974 ok(!memcmp(buf + sizeof(contents) - 4, "DCBA", 4), "file contents mismatch\n"); 3975 3976 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 3977 ok(off == sizeof(contents), "expected sizeof(contents), got %u\n", off); 3978 3979 S(U(ovl)).Offset = sizeof(contents) - 4; 3980 S(U(ovl)).OffsetHigh = 0; 3981 ovl.hEvent = 0; 3982 bytes = 0; 3983 SetLastError(0xdeadbeef); 3984 ret = WriteFile(hfile, "ABCD", 4, &bytes, &ovl); 3985 ok(ret, "WriteFile error %d\n", GetLastError()); 3986 ok(bytes == 4, "bytes %u\n", bytes); 3987 3988 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 3989 ok(off == sizeof(contents), "expected sizeof(contents), got %u\n", off); 3990 3991 S(U(ovl)).Offset = 0; 3992 S(U(ovl)).OffsetHigh = 0; 3993 ovl.Internal = -1; 3994 ovl.InternalHigh = -1; 3995 ovl.hEvent = 0; 3996 bytes = 0; 3997 SetLastError(0xdeadbeef); 3998 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl); 3999 ok(ret, "ReadFile error %d\n", GetLastError()); 4000 ok(bytes == sizeof(contents), "bytes %u\n", bytes); 4001 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 4002 ok(ovl.InternalHigh == sizeof(contents), "expected sizeof(contents), got %lu\n", ovl.InternalHigh); 4003 ok(!memcmp(contents, buf, sizeof(contents) - 4), "file contents mismatch\n"); 4004 ok(!memcmp(buf + sizeof(contents) - 4, "ABCD", 4), "file contents mismatch\n"); 4005 4006 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4007 ok(off == sizeof(contents), "expected sizeof(contents), got %u\n", off); 4008 4009 CloseHandle(hfile); 4010 4011 hfile = create_temp_file(FILE_FLAG_OVERLAPPED); 4012 if (!hfile) return; 4013 4014 bytes = 0xdeadbeef; 4015 SetLastError(0xdeadbeef); 4016 ret = ReadFile(INVALID_HANDLE_VALUE, buf, 0, &bytes, NULL); 4017 ok(!ret, "ReadFile should fail\n"); 4018 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 4019 ok(bytes == 0, "bytes %u\n", bytes); 4020 4021 S(U(ovl)).Offset = 0; 4022 S(U(ovl)).OffsetHigh = 0; 4023 ovl.Internal = -1; 4024 ovl.InternalHigh = -1; 4025 ovl.hEvent = 0; 4026 bytes = 0xdeadbeef; 4027 SetLastError(0xdeadbeef); 4028 /* ReadFile return value depends on Windows version and testing it is not practical */ 4029 ReadFile(hfile, buf, 0, &bytes, &ovl); 4030 ok(bytes == 0, "bytes %u\n", bytes); 4031 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 4032 ok(ovl.InternalHigh == 0, "expected 0, got %lu\n", ovl.InternalHigh); 4033 4034 bytes = 0xdeadbeef; 4035 SetLastError(0xdeadbeef); 4036 ret = WriteFile(hfile, contents, sizeof(contents), &bytes, NULL); 4037 ok(!ret, "WriteFile should fail\n"); 4038 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 4039 ok(bytes == 0, "bytes %u\n", bytes); 4040 4041 U(iob).Status = -1; 4042 iob.Information = -1; 4043 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, sizeof(contents), NULL, NULL); 4044 ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %#x\n", status); 4045 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 4046 ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information); 4047 4048 for (i = -20; i < -1; i++) 4049 { 4050 U(iob).Status = -1; 4051 iob.Information = -1; 4052 offset.QuadPart = (LONGLONG)i; 4053 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, sizeof(contents), &offset, NULL); 4054 ok(status == STATUS_INVALID_PARAMETER, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i, status); 4055 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 4056 ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information); 4057 } 4058 4059 U(iob).Status = -1; 4060 iob.Information = -1; 4061 offset.QuadPart = 0; 4062 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, sizeof(contents), &offset, NULL); 4063 ok(status == STATUS_PENDING || status == STATUS_SUCCESS /* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status); 4064 if (status == STATUS_PENDING) 4065 { 4066 ret = WaitForSingleObject(hfile, 3000); 4067 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %d\n", ret); 4068 } 4069 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 4070 ok(iob.Information == sizeof(contents), "expected sizeof(contents), got %lu\n", iob.Information); 4071 4072 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4073 ok(off == 0, "expected 0, got %u\n", off); 4074 4075 bytes = 0xdeadbeef; 4076 SetLastError(0xdeadbeef); 4077 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL); 4078 ok(!ret, "ReadFile should fail\n"); 4079 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 4080 ok(bytes == 0, "bytes %u\n", bytes); 4081 4082 U(iob).Status = -1; 4083 iob.Information = -1; 4084 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), NULL, NULL); 4085 ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %#x\n", status); 4086 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 4087 ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information); 4088 4089 for (i = -20; i < 0; i++) 4090 { 4091 U(iob).Status = -1; 4092 iob.Information = -1; 4093 offset.QuadPart = (LONGLONG)i; 4094 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 4095 ok(status == STATUS_INVALID_PARAMETER, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i, status); 4096 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 4097 ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information); 4098 } 4099 4100 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4101 ok(off == 0, "expected 0, got %u\n", off); 4102 4103 /* test reading beyond EOF */ 4104 offset.QuadPart = sizeof(contents); 4105 S(U(ovl)).Offset = offset.u.LowPart; 4106 S(U(ovl)).OffsetHigh = offset.u.HighPart; 4107 ovl.Internal = -1; 4108 ovl.InternalHigh = -1; 4109 ovl.hEvent = 0; 4110 bytes = 0xdeadbeef; 4111 SetLastError(0xdeadbeef); 4112 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl); 4113 ok(!ret, "ReadFile should fail\n"); 4114 ret = GetLastError(); 4115 ok(ret == ERROR_IO_PENDING || ret == ERROR_HANDLE_EOF /* before Vista */, "expected ERROR_IO_PENDING or ERROR_HANDLE_EOF, got %d\n", ret); 4116 ok(bytes == 0, "bytes %u\n", bytes); 4117 4118 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4119 ok(off == 0, "expected 0, got %u\n", off); 4120 4121 if (ret == ERROR_IO_PENDING) 4122 { 4123 bytes = 0xdeadbeef; 4124 SetLastError(0xdeadbeef); 4125 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE); 4126 ok(!ret, "GetOverlappedResult should report FALSE\n"); 4127 ok(GetLastError() == ERROR_HANDLE_EOF, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError()); 4128 ok(bytes == 0, "expected 0, read %u\n", bytes); 4129 ok((NTSTATUS)ovl.Internal == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", ovl.Internal); 4130 ok(ovl.InternalHigh == 0, "expected 0, got %lu\n", ovl.InternalHigh); 4131 } 4132 4133 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4134 ok(off == 0, "expected 0, got %u\n", off); 4135 4136 offset.QuadPart = sizeof(contents); 4137 S(U(ovl)).Offset = offset.u.LowPart; 4138 S(U(ovl)).OffsetHigh = offset.u.HighPart; 4139 ovl.Internal = -1; 4140 ovl.InternalHigh = -1; 4141 ovl.hEvent = 0; 4142 bytes = 0xdeadbeef; 4143 SetLastError(0xdeadbeef); 4144 ret = ReadFile(hfile, buf, 0, &bytes, &ovl); 4145 /* ReadFile return value depends on Windows version and testing it is not practical */ 4146 if (!ret) 4147 ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError()); 4148 ret = GetLastError(); 4149 ok(bytes == 0, "bytes %u\n", bytes); 4150 4151 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4152 ok(off == 0, "expected 0, got %u\n", off); 4153 4154 if (ret == ERROR_IO_PENDING) 4155 { 4156 bytes = 0xdeadbeef; 4157 SetLastError(0xdeadbeef); 4158 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE); 4159 ok(ret, "GetOverlappedResult should report TRUE\n"); 4160 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); 4161 ok(bytes == 0, "expected 0, read %u\n", bytes); 4162 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 4163 ok(ovl.InternalHigh == 0, "expected 0, got %lu\n", ovl.InternalHigh); 4164 } 4165 4166 offset.QuadPart = sizeof(contents); 4167 S(U(ovl)).Offset = offset.u.LowPart; 4168 S(U(ovl)).OffsetHigh = offset.u.HighPart; 4169 ovl.Internal = -1; 4170 ovl.InternalHigh = -1; 4171 ovl.hEvent = 0; 4172 bytes = 0xdeadbeef; 4173 SetLastError(0xdeadbeef); 4174 ret = ReadFile(hfile, NULL, 0, &bytes, &ovl); 4175 /* ReadFile return value depends on Windows version and testing it is not practical */ 4176 if (!ret) 4177 ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError()); 4178 ret = GetLastError(); 4179 ok(bytes == 0, "bytes %u\n", bytes); 4180 4181 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4182 ok(off == 0, "expected 0, got %u\n", off); 4183 4184 if (ret == ERROR_IO_PENDING) 4185 { 4186 bytes = 0xdeadbeef; 4187 SetLastError(0xdeadbeef); 4188 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE); 4189 ok(ret, "GetOverlappedResult should report TRUE\n"); 4190 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); 4191 ok(bytes == 0, "expected 0, read %u\n", bytes); 4192 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 4193 ok(ovl.InternalHigh == 0, "expected 0, got %lu\n", ovl.InternalHigh); 4194 } 4195 4196 U(iob).Status = -1; 4197 iob.Information = -1; 4198 offset.QuadPart = sizeof(contents); 4199 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 4200 if (status == STATUS_PENDING) 4201 { 4202 ret = WaitForSingleObject(hfile, 3000); 4203 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %d\n", ret); 4204 ok(U(iob).Status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#x\n", U(iob).Status); 4205 ok(iob.Information == 0, "expected 0, got %lu\n", iob.Information); 4206 } 4207 else 4208 { 4209 ok(status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#x\n", status); 4210 ok(U(iob).Status == -1, "expected -1, got %#x\n", U(iob).Status); 4211 ok(iob.Information == -1, "expected -1, got %lu\n", iob.Information); 4212 } 4213 4214 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4215 ok(off == 0, "expected 0, got %u\n", off); 4216 4217 U(iob).Status = -1; 4218 iob.Information = -1; 4219 offset.QuadPart = sizeof(contents); 4220 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, 0, &offset, NULL); 4221 if (status == STATUS_PENDING) 4222 { 4223 ret = WaitForSingleObject(hfile, 3000); 4224 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %d\n", ret); 4225 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 4226 ok(iob.Information == 0, "expected 0, got %lu\n", iob.Information); 4227 } 4228 else 4229 { 4230 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", status); 4231 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 4232 ok(iob.Information == 0, "expected 0, got %lu\n", iob.Information); 4233 } 4234 4235 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4236 ok(off == 0, "expected 0, got %u\n", off); 4237 4238 S(U(ovl)).Offset = 0; 4239 S(U(ovl)).OffsetHigh = 0; 4240 ovl.Internal = -1; 4241 ovl.InternalHigh = -1; 4242 ovl.hEvent = 0; 4243 bytes = 0; 4244 SetLastError(0xdeadbeef); 4245 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl); 4246 /* ReadFile return value depends on Windows version and testing it is not practical */ 4247 if (!ret) 4248 { 4249 ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError()); 4250 ok(bytes == 0, "bytes %u\n", bytes); 4251 } 4252 else ok(bytes == 14, "bytes %u\n", bytes); 4253 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 4254 ok(ovl.InternalHigh == sizeof(contents), "expected sizeof(contents), got %lu\n", ovl.InternalHigh); 4255 4256 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4257 ok(off == 0, "expected 0, got %u\n", off); 4258 4259 bytes = 0xdeadbeef; 4260 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE); 4261 ok(ret, "GetOverlappedResult error %d\n", GetLastError()); 4262 ok(bytes == sizeof(contents), "bytes %u\n", bytes); 4263 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 4264 ok(ovl.InternalHigh == sizeof(contents), "expected sizeof(contents), got %lu\n", ovl.InternalHigh); 4265 ok(!memcmp(contents, buf, sizeof(contents)), "file contents mismatch\n"); 4266 4267 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4268 ok(off == 0, "expected 0, got %u\n", off); 4269 4270 SetFilePointer(hfile, sizeof(contents) - 4, NULL, FILE_BEGIN); 4271 SetEndOfFile(hfile); 4272 SetFilePointer(hfile, 0, NULL, FILE_BEGIN); 4273 4274 U(iob).Status = -1; 4275 iob.Information = -1; 4276 offset.QuadPart = (LONGLONG)-1 /* FILE_WRITE_TO_END_OF_FILE */; 4277 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, "DCBA", 4, &offset, NULL); 4278 ok(status == STATUS_PENDING || status == STATUS_SUCCESS /* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status); 4279 if (status == STATUS_PENDING) 4280 { 4281 ret = WaitForSingleObject(hfile, 3000); 4282 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %d\n", ret); 4283 } 4284 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 4285 ok(iob.Information == 4, "expected 4, got %lu\n", iob.Information); 4286 4287 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4288 ok(off == 0, "expected 0, got %u\n", off); 4289 4290 U(iob).Status = -1; 4291 iob.Information = -1; 4292 offset.QuadPart = 0; 4293 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL); 4294 ok(status == STATUS_PENDING || status == STATUS_SUCCESS, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status); 4295 if (status == STATUS_PENDING) 4296 { 4297 ret = WaitForSingleObject(hfile, 3000); 4298 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %d\n", ret); 4299 } 4300 ok(U(iob).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iob).Status); 4301 ok(iob.Information == sizeof(contents), "expected sizeof(contents), got %lu\n", iob.Information); 4302 4303 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4304 ok(off == 0, "expected 0, got %u\n", off); 4305 4306 ok(!memcmp(contents, buf, sizeof(contents) - 4), "file contents mismatch\n"); 4307 ok(!memcmp(buf + sizeof(contents) - 4, "DCBA", 4), "file contents mismatch\n"); 4308 4309 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4310 ok(off == 0, "expected 0, got %u\n", off); 4311 4312 S(U(ovl)).Offset = sizeof(contents) - 4; 4313 S(U(ovl)).OffsetHigh = 0; 4314 ovl.Internal = -1; 4315 ovl.InternalHigh = -1; 4316 ovl.hEvent = 0; 4317 bytes = 0; 4318 SetLastError(0xdeadbeef); 4319 ret = WriteFile(hfile, "ABCD", 4, &bytes, &ovl); 4320 /* WriteFile return value depends on Windows version and testing it is not practical */ 4321 if (!ret) 4322 { 4323 ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError()); 4324 ok(bytes == 0, "bytes %u\n", bytes); 4325 ret = WaitForSingleObject(hfile, 3000); 4326 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %d\n", ret); 4327 } 4328 else ok(bytes == 4, "bytes %u\n", bytes); 4329 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 4330 ok(ovl.InternalHigh == 4, "expected 4, got %lu\n", ovl.InternalHigh); 4331 4332 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4333 ok(off == 0, "expected 0, got %u\n", off); 4334 4335 bytes = 0xdeadbeef; 4336 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE); 4337 ok(ret, "GetOverlappedResult error %d\n", GetLastError()); 4338 ok(bytes == 4, "bytes %u\n", bytes); 4339 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 4340 ok(ovl.InternalHigh == 4, "expected 4, got %lu\n", ovl.InternalHigh); 4341 4342 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4343 ok(off == 0, "expected 0, got %u\n", off); 4344 4345 S(U(ovl)).Offset = 0; 4346 S(U(ovl)).OffsetHigh = 0; 4347 ovl.Internal = -1; 4348 ovl.InternalHigh = -1; 4349 ovl.hEvent = 0; 4350 bytes = 0; 4351 SetLastError(0xdeadbeef); 4352 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl); 4353 /* ReadFile return value depends on Windows version and testing it is not practical */ 4354 if (!ret) 4355 { 4356 ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError()); 4357 ok(bytes == 0, "bytes %u\n", bytes); 4358 ret = WaitForSingleObject(hfile, 3000); 4359 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %d\n", ret); 4360 } 4361 else ok(bytes == 14, "bytes %u\n", bytes); 4362 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 4363 ok(ovl.InternalHigh == sizeof(contents), "expected sizeof(contents), got %lu\n", ovl.InternalHigh); 4364 4365 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4366 ok(off == 0, "expected 0, got %u\n", off); 4367 4368 bytes = 0xdeadbeef; 4369 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE); 4370 ok(ret, "GetOverlappedResult error %d\n", GetLastError()); 4371 ok(bytes == sizeof(contents), "bytes %u\n", bytes); 4372 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", ovl.Internal); 4373 ok(ovl.InternalHigh == sizeof(contents), "expected sizeof(contents), got %lu\n", ovl.InternalHigh); 4374 ok(!memcmp(contents, buf, sizeof(contents) - 4), "file contents mismatch\n"); 4375 ok(!memcmp(buf + sizeof(contents) - 4, "ABCD", 4), "file contents mismatch\n"); 4376 4377 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT); 4378 ok(off == 0, "expected 0, got %u\n", off); 4379 4380 CloseHandle(event); 4381 CloseHandle(hfile); 4382 } 4383 4384 static void test_ioctl(void) 4385 { 4386 HANDLE event = CreateEventA(NULL, TRUE, FALSE, NULL); 4387 FILE_PIPE_PEEK_BUFFER peek_buf; 4388 IO_STATUS_BLOCK iosb; 4389 HANDLE file; 4390 NTSTATUS status; 4391 4392 file = create_temp_file(FILE_FLAG_OVERLAPPED); 4393 ok(file != INVALID_HANDLE_VALUE, "could not create temp file\n"); 4394 4395 SetEvent(event); 4396 status = pNtFsControlFile(file, event, NULL, NULL, &iosb, 0xdeadbeef, 0, 0, 0, 0); 4397 todo_wine 4398 ok(status == STATUS_INVALID_DEVICE_REQUEST, "NtFsControlFile returned %x\n", status); 4399 ok(!is_signaled(event), "event is signaled\n"); 4400 4401 status = pNtFsControlFile(file, (HANDLE)0xdeadbeef, NULL, NULL, &iosb, 0xdeadbeef, 0, 0, 0, 0); 4402 ok(status == STATUS_INVALID_HANDLE, "NtFsControlFile returned %x\n", status); 4403 4404 memset(&iosb, 0x55, sizeof(iosb)); 4405 status = NtFsControlFile(file, NULL, NULL, NULL, &iosb, FSCTL_PIPE_PEEK, NULL, 0, 4406 &peek_buf, sizeof(peek_buf)); 4407 todo_wine 4408 ok(status == STATUS_INVALID_DEVICE_REQUEST, "NtFsControlFile failed: %x\n", status); 4409 ok(iosb.Status == 0x55555555, "iosb.Status = %x\n", iosb.Status); 4410 4411 CloseHandle(event); 4412 CloseHandle(file); 4413 } 4414 4415 static void test_flush_buffers_file(void) 4416 { 4417 char path[MAX_PATH], buffer[MAX_PATH]; 4418 HANDLE hfile, hfileread; 4419 NTSTATUS status; 4420 IO_STATUS_BLOCK io_status_block; 4421 4422 GetTempPathA(MAX_PATH, path); 4423 GetTempFileNameA(path, "foo", 0, buffer); 4424 hfile = CreateFileA(buffer, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 4425 FILE_ATTRIBUTE_NORMAL, 0); 4426 ok(hfile != INVALID_HANDLE_VALUE, "failed to create temp file.\n" ); 4427 4428 hfileread = CreateFileA(buffer, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 4429 OPEN_EXISTING, 0, NULL); 4430 ok(hfileread != INVALID_HANDLE_VALUE, "could not open temp file, error %d.\n", GetLastError()); 4431 4432 status = pNtFlushBuffersFile(hfile, NULL); 4433 todo_wine 4434 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status); 4435 4436 status = pNtFlushBuffersFile(hfile, (IO_STATUS_BLOCK *)0xdeadbeaf); 4437 todo_wine 4438 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status); 4439 4440 status = pNtFlushBuffersFile(hfile, &io_status_block); 4441 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x.\n", status); 4442 4443 status = pNtFlushBuffersFile(hfileread, &io_status_block); 4444 ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#x.\n", status); 4445 4446 status = pNtFlushBuffersFile(NULL, &io_status_block); 4447 ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %#x.\n", status); 4448 4449 CloseHandle(hfileread); 4450 CloseHandle(hfile); 4451 hfile = CreateFileA(buffer, FILE_APPEND_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 4452 OPEN_EXISTING, 0, NULL); 4453 ok(hfile != INVALID_HANDLE_VALUE, "could not open temp file, error %d.\n", GetLastError()); 4454 4455 status = pNtFlushBuffersFile(hfile, &io_status_block); 4456 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x.\n", status); 4457 4458 CloseHandle(hfile); 4459 DeleteFileA(buffer); 4460 } 4461 4462 static void test_query_ea(void) 4463 { 4464 #define EA_BUFFER_SIZE 4097 4465 unsigned char data[EA_BUFFER_SIZE + 8]; 4466 unsigned char *buffer = (void *)(((DWORD_PTR)data + 7) & ~7); 4467 DWORD buffer_len, i; 4468 IO_STATUS_BLOCK io; 4469 NTSTATUS status; 4470 HANDLE handle; 4471 4472 if (!(handle = create_temp_file(0))) return; 4473 4474 /* test with INVALID_HANDLE_VALUE */ 4475 U(io).Status = 0xdeadbeef; 4476 io.Information = 0xdeadbeef; 4477 memset(buffer, 0xcc, EA_BUFFER_SIZE); 4478 buffer_len = EA_BUFFER_SIZE - 1; 4479 status = pNtQueryEaFile(INVALID_HANDLE_VALUE, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE); 4480 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "expected STATUS_OBJECT_TYPE_MISMATCH, got %x\n", status); 4481 ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); 4482 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); 4483 ok(buffer[0] == 0xcc, "data at position 0 overwritten\n"); 4484 4485 /* test with 0xdeadbeef */ 4486 U(io).Status = 0xdeadbeef; 4487 io.Information = 0xdeadbeef; 4488 memset(buffer, 0xcc, EA_BUFFER_SIZE); 4489 buffer_len = EA_BUFFER_SIZE - 1; 4490 status = pNtQueryEaFile((void *)0xdeadbeef, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE); 4491 ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %x\n", status); 4492 ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); 4493 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); 4494 ok(buffer[0] == 0xcc, "data at position 0 overwritten\n"); 4495 4496 /* test without buffer */ 4497 U(io).Status = 0xdeadbeef; 4498 io.Information = 0xdeadbeef; 4499 status = pNtQueryEaFile(handle, &io, NULL, 0, TRUE, NULL, 0, NULL, FALSE); 4500 ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status); 4501 ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); 4502 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); 4503 4504 /* test with zero buffer */ 4505 U(io).Status = 0xdeadbeef; 4506 io.Information = 0xdeadbeef; 4507 status = pNtQueryEaFile(handle, &io, buffer, 0, TRUE, NULL, 0, NULL, FALSE); 4508 ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status); 4509 ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); 4510 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); 4511 4512 /* test with very small buffer */ 4513 U(io).Status = 0xdeadbeef; 4514 io.Information = 0xdeadbeef; 4515 memset(buffer, 0xcc, EA_BUFFER_SIZE); 4516 buffer_len = 4; 4517 status = pNtQueryEaFile(handle, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE); 4518 ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status); 4519 ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); 4520 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); 4521 for (i = 0; i < buffer_len && !buffer[i]; i++); 4522 ok(i == buffer_len, "expected %u bytes filled with 0x00, got %u bytes\n", buffer_len, i); 4523 ok(buffer[i] == 0xcc, "data at position %u overwritten\n", buffer[i]); 4524 4525 /* test with very big buffer */ 4526 U(io).Status = 0xdeadbeef; 4527 io.Information = 0xdeadbeef; 4528 memset(buffer, 0xcc, EA_BUFFER_SIZE); 4529 buffer_len = EA_BUFFER_SIZE - 1; 4530 status = pNtQueryEaFile(handle, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE); 4531 ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status); 4532 ok(U(io).Status == 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io).Status); 4533 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io.Information); 4534 for (i = 0; i < buffer_len && !buffer[i]; i++); 4535 ok(i == buffer_len, "expected %u bytes filled with 0x00, got %u bytes\n", buffer_len, i); 4536 ok(buffer[i] == 0xcc, "data at position %u overwritten\n", buffer[i]); 4537 4538 CloseHandle(handle); 4539 #undef EA_BUFFER_SIZE 4540 } 4541 4542 static INT build_reparse_buffer(WCHAR *filename, REPARSE_DATA_BUFFER **pbuffer) 4543 { 4544 REPARSE_DATA_BUFFER *buffer; 4545 INT buffer_len, string_len; 4546 WCHAR *dest; 4547 4548 string_len = (lstrlenW(filename)+1)*sizeof(WCHAR); 4549 buffer_len = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer[1]) + string_len; 4550 buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_len); 4551 buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; 4552 buffer->ReparseDataLength = sizeof(buffer->MountPointReparseBuffer) + string_len; 4553 buffer->MountPointReparseBuffer.SubstituteNameLength = string_len - sizeof(WCHAR); 4554 buffer->MountPointReparseBuffer.PrintNameOffset = string_len; 4555 dest = &buffer->MountPointReparseBuffer.PathBuffer[0]; 4556 memcpy(dest, filename, string_len); 4557 *pbuffer = buffer; 4558 return buffer_len; 4559 } 4560 4561 static void test_junction_points(void) 4562 { 4563 static const WCHAR junctionW[] = {'\\','j','u','n','c','t','i','o','n',0}; 4564 WCHAR path[MAX_PATH], junction_path[MAX_PATH], target_path[MAX_PATH]; 4565 static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0}; 4566 FILE_BASIC_INFORMATION old_attrib, new_attrib; 4567 static const WCHAR fooW[] = {'f','o','o',0}; 4568 static WCHAR volW[] = {'c',':','\\',0}; 4569 REPARSE_GUID_DATA_BUFFER guid_buffer; 4570 static const WCHAR dotW[] = {'.',0}; 4571 REPARSE_DATA_BUFFER *buffer = NULL; 4572 DWORD dwret, dwLen, dwFlags, err; 4573 INT buffer_len, string_len; 4574 IO_STATUS_BLOCK iosb; 4575 UNICODE_STRING nameW; 4576 HANDLE hJunction; 4577 WCHAR *dest; 4578 BOOL bret; 4579 4580 /* Create a temporary folder for the junction point tests */ 4581 GetTempFileNameW(dotW, fooW, 0, path); 4582 DeleteFileW(path); 4583 if (!CreateDirectoryW(path, NULL)) 4584 { 4585 win_skip("Unable to create a temporary junction point directory.\n"); 4586 return; 4587 } 4588 4589 /* Check that the volume this folder is located on supports junction points */ 4590 pRtlDosPathNameToNtPathName_U(path, &nameW, NULL, NULL); 4591 volW[0] = nameW.Buffer[4]; 4592 pRtlFreeUnicodeString( &nameW ); 4593 GetVolumeInformationW(volW, 0, 0, 0, &dwLen, &dwFlags, 0, 0); 4594 if (!(dwFlags & FILE_SUPPORTS_REPARSE_POINTS)) 4595 { 4596 skip("File system does not support junction points.\n"); 4597 RemoveDirectoryW(path); 4598 return; 4599 } 4600 4601 /* Create the folder to be replaced by a junction point */ 4602 lstrcpyW(junction_path, path); 4603 lstrcatW(junction_path, junctionW); 4604 bret = CreateDirectoryW(junction_path, NULL); 4605 ok(bret, "Failed to create junction point directory.\n"); 4606 4607 /* Create a destination folder for the junction point to target */ 4608 lstrcpyW(target_path, path); 4609 lstrcatW(target_path, targetW); 4610 bret = CreateDirectoryW(target_path, NULL); 4611 ok(bret, "Failed to create junction point target directory.\n"); 4612 pRtlDosPathNameToNtPathName_U(target_path, &nameW, NULL, NULL); 4613 4614 /* Create the junction point */ 4615 hJunction = CreateFileW(junction_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 4616 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0); 4617 if (hJunction == INVALID_HANDLE_VALUE) 4618 { 4619 win_skip("Failed to open junction point directory handle (0x%x).\n", GetLastError()); 4620 goto cleanup; 4621 } 4622 dwret = NtQueryInformationFile(hJunction, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation); 4623 ok(dwret == STATUS_SUCCESS, "Failed to get junction point folder's attributes (0x%x).\n", dwret); 4624 buffer_len = build_reparse_buffer(nameW.Buffer, &buffer); 4625 bret = DeviceIoControl(hJunction, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0); 4626 ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError()); 4627 4628 /* Check the file attributes of the junction point */ 4629 dwret = GetFileAttributesW(junction_path); 4630 ok(dwret != (DWORD)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret); 4631 ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a junction point! (attributes: %d)\n", dwret); 4632 4633 /* Read back the junction point */ 4634 HeapFree(GetProcessHeap(), 0, buffer); 4635 buffer_len = sizeof(*buffer) + MAX_PATH*sizeof(WCHAR); 4636 buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_len); 4637 bret = DeviceIoControl(hJunction, FSCTL_GET_REPARSE_POINT, NULL, 0, (LPVOID)buffer, buffer_len, &dwret, 0); 4638 string_len = buffer->MountPointReparseBuffer.SubstituteNameLength; 4639 dest = &buffer->MountPointReparseBuffer.PathBuffer[buffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)]; 4640 ok(bret, "Failed to read junction point!\n"); 4641 ok((memcmp(dest, nameW.Buffer, string_len) == 0), "Junction point destination does not match ('%s' != '%s')!\n", 4642 wine_dbgstr_w(dest), wine_dbgstr_w(nameW.Buffer)); 4643 4644 /* Delete the junction point */ 4645 memset(&old_attrib, 0x00, sizeof(old_attrib)); 4646 old_attrib.LastAccessTime.QuadPart = 0x200deadcafebeef; 4647 dwret = NtSetInformationFile(hJunction, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation); 4648 ok(dwret == STATUS_SUCCESS, "Failed to set junction point folder's attributes (0x%x).\n", dwret); 4649 memset(&guid_buffer, 0x00, sizeof(guid_buffer)); 4650 guid_buffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; 4651 bret = DeviceIoControl(hJunction, FSCTL_DELETE_REPARSE_POINT, (LPVOID)&guid_buffer, 4652 REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, NULL, 0, &dwret, 0); 4653 ok(bret, "Failed to delete junction point! (0x%x)\n", GetLastError()); 4654 memset(&new_attrib, 0x00, sizeof(new_attrib)); 4655 dwret = NtQueryInformationFile(hJunction, &iosb, &new_attrib, sizeof(new_attrib), FileBasicInformation); 4656 ok(dwret == STATUS_SUCCESS, "Failed to get junction point folder's attributes (0x%x).\n", dwret); 4657 ok(old_attrib.LastAccessTime.QuadPart == new_attrib.LastAccessTime.QuadPart, 4658 "Junction point folder's access time does not match.\n"); 4659 CloseHandle(hJunction); 4660 4661 /* Check deleting a junction point as if it were a directory */ 4662 HeapFree(GetProcessHeap(), 0, buffer); 4663 hJunction = CreateFileW(junction_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 4664 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0); 4665 buffer_len = build_reparse_buffer(nameW.Buffer, &buffer); 4666 bret = DeviceIoControl(hJunction, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0); 4667 ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError()); 4668 CloseHandle(hJunction); 4669 bret = RemoveDirectoryW(junction_path); 4670 ok(bret, "Failed to delete junction point as directory!\n"); 4671 dwret = GetFileAttributesW(junction_path); 4672 ok(dwret == (DWORD)~0, "Junction point still exists (attributes: 0x%x)!\n", dwret); 4673 4674 /* Check deleting a junction point as if it were a file */ 4675 HeapFree(GetProcessHeap(), 0, buffer); 4676 bret = CreateDirectoryW(junction_path, NULL); 4677 ok(bret, "Failed to create junction point target directory.\n"); 4678 hJunction = CreateFileW(junction_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 4679 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0); 4680 buffer_len = build_reparse_buffer(nameW.Buffer, &buffer); 4681 bret = DeviceIoControl(hJunction, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0); 4682 ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError()); 4683 CloseHandle(hJunction); 4684 bret = DeleteFileW(junction_path); 4685 ok(!bret, "Succeeded in deleting junction point as file!\n"); 4686 err = GetLastError(); 4687 ok(err == ERROR_ACCESS_DENIED, "Expected last error 0x%x for DeleteFile on junction point (actually 0x%x)!\n", 4688 ERROR_ACCESS_DENIED, err); 4689 dwret = GetFileAttributesW(junction_path); 4690 ok(dwret != (DWORD)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret); 4691 ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a junction point! (attributes: 0x%x)\n", dwret); 4692 4693 /* Test deleting a junction point's target */ 4694 dwret = GetFileAttributesW(junction_path); 4695 ok(dwret == 0x410 || broken(dwret == 0x430) /* win2k */, 4696 "Unexpected junction point attributes (0x%x != 0x410)!\n", dwret); 4697 bret = RemoveDirectoryW(target_path); 4698 ok(bret, "Failed to delete junction point target!\n"); 4699 bret = CreateDirectoryW(target_path, NULL); 4700 ok(bret, "Failed to create junction point target directory.\n"); 4701 4702 cleanup: 4703 /* Cleanup */ 4704 pRtlFreeUnicodeString( &nameW ); 4705 HeapFree(GetProcessHeap(), 0, buffer); 4706 bret = RemoveDirectoryW(junction_path); 4707 ok(bret, "Failed to remove temporary junction point directory!\n"); 4708 bret = RemoveDirectoryW(target_path); 4709 ok(bret, "Failed to remove temporary target directory!\n"); 4710 RemoveDirectoryW(path); 4711 } 4712 4713 START_TEST(file) 4714 { 4715 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); 4716 HMODULE hntdll = GetModuleHandleA("ntdll.dll"); 4717 if (!hntdll) 4718 { 4719 skip("not running on NT, skipping test\n"); 4720 return; 4721 } 4722 4723 pGetVolumePathNameW = (void *)GetProcAddress(hkernel32, "GetVolumePathNameW"); 4724 pGetSystemWow64DirectoryW = (void *)GetProcAddress(hkernel32, "GetSystemWow64DirectoryW"); 4725 4726 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); 4727 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); 4728 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U"); 4729 pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll, "RtlWow64EnableFsRedirectionEx"); 4730 pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile"); 4731 pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile"); 4732 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile"); 4733 pNtDeleteFile = (void *)GetProcAddress(hntdll, "NtDeleteFile"); 4734 pNtReadFile = (void *)GetProcAddress(hntdll, "NtReadFile"); 4735 pNtWriteFile = (void *)GetProcAddress(hntdll, "NtWriteFile"); 4736 pNtCancelIoFile = (void *)GetProcAddress(hntdll, "NtCancelIoFile"); 4737 pNtCancelIoFileEx = (void *)GetProcAddress(hntdll, "NtCancelIoFileEx"); 4738 pNtClose = (void *)GetProcAddress(hntdll, "NtClose"); 4739 pNtFsControlFile = (void *)GetProcAddress(hntdll, "NtFsControlFile"); 4740 pNtCreateIoCompletion = (void *)GetProcAddress(hntdll, "NtCreateIoCompletion"); 4741 pNtOpenIoCompletion = (void *)GetProcAddress(hntdll, "NtOpenIoCompletion"); 4742 pNtQueryIoCompletion = (void *)GetProcAddress(hntdll, "NtQueryIoCompletion"); 4743 pNtRemoveIoCompletion = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletion"); 4744 pNtSetIoCompletion = (void *)GetProcAddress(hntdll, "NtSetIoCompletion"); 4745 pNtSetInformationFile = (void *)GetProcAddress(hntdll, "NtSetInformationFile"); 4746 pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile"); 4747 pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile"); 4748 pNtQueryVolumeInformationFile = (void *)GetProcAddress(hntdll, "NtQueryVolumeInformationFile"); 4749 pNtQueryFullAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryFullAttributesFile"); 4750 pNtFlushBuffersFile = (void *)GetProcAddress(hntdll, "NtFlushBuffersFile"); 4751 pNtQueryEaFile = (void *)GetProcAddress(hntdll, "NtQueryEaFile"); 4752 4753 test_read_write(); 4754 test_NtCreateFile(); 4755 test_readonly(); 4756 create_file_test(); 4757 open_file_test(); 4758 delete_file_test(); 4759 read_file_test(); 4760 append_file_test(); 4761 nt_mailslot_test(); 4762 test_iocompletion(); 4763 test_file_basic_information(); 4764 test_file_all_information(); 4765 test_file_both_information(); 4766 test_file_name_information(); 4767 test_file_full_size_information(); 4768 test_file_all_name_information(); 4769 test_file_rename_information(); 4770 test_file_link_information(); 4771 test_file_disposition_information(); 4772 test_file_completion_information(); 4773 test_file_id_information(); 4774 test_file_access_information(); 4775 test_query_volume_information_file(); 4776 test_query_attribute_information_file(); 4777 test_ioctl(); 4778 test_flush_buffers_file(); 4779 test_query_ea(); 4780 test_junction_points(); 4781 } 4782