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