ReactOS  0.4.14-dev-583-g2a1ba2c
file.c
Go to the documentation of this file.
1 /* Unit test suite for Ntdll file functions
2  *
3  * Copyright 2007 Jeff Latimer
4  * Copyright 2007 Andrey Turkin
5  * Copyright 2008 Jeff Zaroyko
6  * Copyright 2011 Dmitry Timoshkov
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  *
22  * NOTES
23  * We use function pointers here as there is no import library for NTDLL on
24  * windows.
25  */
26 
27 #include <stdio.h>
28 #include <stdarg.h>
29 
30 #include "ntstatus.h"
31 /* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro
32  * definition errors when we get to winnt.h
33  */
34 #define WIN32_NO_STATUS
35 
36 #include "wine/test.h"
37 #include "winternl.h"
38 #include "winuser.h"
39 #include "winioctl.h"
40 #ifndef __REACTOS__
41 #include "ntifs.h"
42 #else
43 /* FIXME: Inspect */
44 typedef struct _REPARSE_DATA_BUFFER {
48  _ANONYMOUS_UNION union {
49  struct {
54  ULONG Flags;
55  WCHAR PathBuffer[1];
57  struct {
62  WCHAR PathBuffer[1];
64  struct {
65  UCHAR DataBuffer[1];
69 #endif
70 
71 #ifndef IO_COMPLETION_ALL_ACCESS
72 #define IO_COMPLETION_ALL_ACCESS 0x001F0003
73 #endif
74 
75 static BOOL (WINAPI * pGetVolumePathNameW)(LPCWSTR, LPWSTR, DWORD);
76 static UINT (WINAPI *pGetSystemWow64DirectoryW)( LPWSTR, UINT );
77 
78 static VOID (WINAPI *pRtlFreeUnicodeString)( PUNICODE_STRING );
79 static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
80 static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* );
81 static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG, ULONG * );
82 
83 static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
87 static NTSTATUS (WINAPI *pNtDeleteFile)(POBJECT_ATTRIBUTES ObjectAttributes);
88 static NTSTATUS (WINAPI *pNtReadFile)(HANDLE hFile, HANDLE hEvent,
92 static NTSTATUS (WINAPI *pNtWriteFile)(HANDLE hFile, HANDLE hEvent,
95  const void* buffer, ULONG length,
97 static NTSTATUS (WINAPI *pNtCancelIoFile)(HANDLE hFile, PIO_STATUS_BLOCK io_status);
99 static NTSTATUS (WINAPI *pNtClose)( PHANDLE );
101 
102 static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG);
103 static NTSTATUS (WINAPI *pNtOpenIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
106 static NTSTATUS (WINAPI *pNtSetIoCompletion)(HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T);
108 static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
111 static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS);
112 static NTSTATUS (WINAPI *pNtQueryFullAttributesFile)(const OBJECT_ATTRIBUTES*, FILE_NETWORK_OPEN_INFORMATION*);
113 static NTSTATUS (WINAPI *pNtFlushBuffersFile)(HANDLE, IO_STATUS_BLOCK*);
115 
116 static inline BOOL is_signaled( HANDLE obj )
117 {
118  return WaitForSingleObject( obj, 0 ) == WAIT_OBJECT_0;
119 }
120 
121 #define TEST_BUF_LEN 3
122 
124 {
125  char path[MAX_PATH], buffer[MAX_PATH];
126  HANDLE handle;
127 
129  GetTempFileNameA( path, "foo", 0, buffer );
132  ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
133  return (handle == INVALID_HANDLE_VALUE) ? 0 : handle;
134 }
135 
136 #define CVALUE_FIRST 0xfffabbcc
137 #define CKEY_FIRST 0x1030341
138 #define CKEY_SECOND 0x132E46
139 
143 
145 {
146  NTSTATUS res;
147  ULONG a, req;
148 
149  res = pNtQueryIoCompletion( h, IoCompletionBasicInformation, &a, sizeof(a), &req );
150  ok( res == STATUS_SUCCESS, "NtQueryIoCompletion failed: %x\n", res );
151  if (res != STATUS_SUCCESS) return -1;
152  ok( req == sizeof(a), "Unexpected response size: %x\n", req );
153  return a;
154 }
155 
157 {
158  LARGE_INTEGER timeout = {{-10000000*3}};
159  DWORD res = pNtRemoveIoCompletion( h, &completionKey, &completionValue, &ioSb, &timeout);
160  ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %x\n", res );
161  if (res != STATUS_SUCCESS)
162  {
164  memset(&ioSb, 0, sizeof(ioSb));
165  return FALSE;
166  }
167  return TRUE;
168 }
169 
170 
171 static void WINAPI apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved )
172 {
173  int *count = arg;
174 
175  trace( "apc called block %p iosb.status %x iosb.info %lu\n",
176  iosb, U(*iosb).Status, iosb->Information );
177  (*count)++;
178  ok( !reserved, "reserved is not 0: %x\n", reserved );
179 }
180 
181 static void create_file_test(void)
182 {
183  static const WCHAR notepadW[] = {'n','o','t','e','p','a','d','.','e','x','e',0};
184  static const WCHAR systemrootW[] = {'\\','S','y','s','t','e','m','R','o','o','t',
185  '\\','f','a','i','l','i','n','g',0};
186  static const WCHAR systemrootExplorerW[] = {'\\','S','y','s','t','e','m','R','o','o','t',
187  '\\','e','x','p','l','o','r','e','r','.','e','x','e',0};
188  static const WCHAR questionmarkInvalidNameW[] = {'a','f','i','l','e','?',0};
189  static const WCHAR pipeInvalidNameW[] = {'a','|','b',0};
190  static const WCHAR pathInvalidNtW[] = {'\\','\\','?','\\',0};
191  static const WCHAR pathInvalidNt2W[] = {'\\','?','?','\\',0};
192  static const WCHAR pathInvalidDosW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
193  static const char testdata[] = "Hello World";
194  static const WCHAR sepW[] = {'\\',0};
197  HANDLE dir, file;
203  char buf[32];
204  DWORD ret;
205 
207  pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
208  attr.Length = sizeof(attr);
209  attr.RootDirectory = 0;
210  attr.ObjectName = &nameW;
211  attr.Attributes = OBJ_CASE_INSENSITIVE;
212  attr.SecurityDescriptor = NULL;
213  attr.SecurityQualityOfService = NULL;
214 
215  /* try various open modes and options on directories */
216  status = pNtCreateFile( &dir, GENERIC_READ|GENERIC_WRITE, &attr, &io, NULL, 0,
218  ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
219 
220  U(io).Status = 0xdeadbeef;
221  offset.QuadPart = 0;
222  status = pNtReadFile( dir, NULL, NULL, NULL, &io, buf, sizeof(buf), &offset, NULL );
223  ok( status == STATUS_INVALID_DEVICE_REQUEST || status == STATUS_PENDING, "NtReadFile error %08x\n", status );
224  if (status == STATUS_PENDING)
225  {
226  ret = WaitForSingleObject( dir, 1000 );
227  ok( ret == WAIT_OBJECT_0, "WaitForSingleObject error %u\n", ret );
229  "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io).Status );
230  }
231 
232  U(io).Status = 0xdeadbeef;
233  offset.QuadPart = 0;
234  status = pNtWriteFile( dir, NULL, NULL, NULL, &io, testdata, sizeof(testdata), &offset, NULL);
235  todo_wine
236  ok( status == STATUS_INVALID_DEVICE_REQUEST || status == STATUS_PENDING, "NtWriteFile error %08x\n", status );
237  if (status == STATUS_PENDING)
238  {
239  ret = WaitForSingleObject( dir, 1000 );
240  ok( ret == WAIT_OBJECT_0, "WaitForSingleObject error %u\n", ret );
242  "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io).Status );
243  }
244 
245  CloseHandle( dir );
246 
247  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
250  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
251 
252  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
254  ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
255  CloseHandle( dir );
256 
257  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
259  ok( status == STATUS_INVALID_PARAMETER, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
260 
261  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
263  ok( status == STATUS_INVALID_PARAMETER, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
264 
265  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
267  ok( status == STATUS_INVALID_PARAMETER, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
268 
269  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
270  FILE_OPEN, 0, NULL, 0 );
271  ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
272  CloseHandle( dir );
273 
274  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
275  FILE_CREATE, 0, NULL, 0 );
277  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
278 
279  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
280  FILE_OPEN_IF, 0, NULL, 0 );
281  ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
282  CloseHandle( dir );
283 
284  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
285  FILE_SUPERSEDE, 0, NULL, 0 );
287  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
288 
289  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
290  FILE_OVERWRITE, 0, NULL, 0 );
292  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
293 
294  status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
295  FILE_OVERWRITE_IF, 0, NULL, 0 );
297  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
298 
299  pRtlFreeUnicodeString( &nameW );
300 
301  pRtlInitUnicodeString( &nameW, systemrootW );
302  attr.Length = sizeof(attr);
303  attr.RootDirectory = NULL;
304  attr.ObjectName = &nameW;
305  attr.Attributes = OBJ_CASE_INSENSITIVE;
306  attr.SecurityDescriptor = NULL;
307  attr.SecurityQualityOfService = NULL;
308  dir = NULL;
309  status = pNtCreateFile( &dir, FILE_APPEND_DATA, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, 0,
311  todo_wine
313  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
314 
315  /* Invalid chars in file/dirnames */
316  pRtlDosPathNameToNtPathName_U(questionmarkInvalidNameW, &nameW, NULL, NULL);
317  attr.ObjectName = &nameW;
318  status = pNtCreateFile(&dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
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,
328  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status);
329  pRtlFreeUnicodeString(&nameW);
330 
331  pRtlDosPathNameToNtPathName_U(pipeInvalidNameW, &nameW, NULL, NULL);
332  attr.ObjectName = &nameW;
333  status = pNtCreateFile(&dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
337  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status);
338 
339  status = pNtCreateFile(&file, GENERIC_WRITE|SYNCHRONIZE, &attr, &io, NULL, 0,
340  0, FILE_CREATE,
343  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status);
344  pRtlFreeUnicodeString(&nameW);
345 
346  pRtlInitUnicodeString( &nameW, pathInvalidNtW );
347  status = pNtCreateFile( &dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
351  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
352 
353  status = pNtQueryFullAttributesFile( &attr, &info );
355  "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
356 
357  pRtlInitUnicodeString( &nameW, pathInvalidNt2W );
358  status = pNtCreateFile( &dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
362  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
363 
364  status = pNtQueryFullAttributesFile( &attr, &info );
366  "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
367 
368  pRtlInitUnicodeString( &nameW, pathInvalidDosW );
369  status = pNtCreateFile( &dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
373  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
374 
375  status = pNtQueryFullAttributesFile( &attr, &info );
377  "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
378 
380  path[2] = 0;
382  "QueryDosDeviceW failed with error %u\n", GetLastError() );
383  lstrcatW( temp, sepW );
384  lstrcatW( temp, path+3 );
385  lstrcatW( temp, sepW );
386  lstrcatW( temp, notepadW );
387 
388  pRtlInitUnicodeString( &nameW, temp );
389  status = pNtQueryFullAttributesFile( &attr, &info );
391  "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
392 
393  pRtlInitUnicodeString( &nameW, systemrootExplorerW );
394  status = pNtQueryFullAttributesFile( &attr, &info );
396  "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
397 }
398 
399 static void open_file_test(void)
400 {
401  static const char testdata[] = "Hello World";
402  static WCHAR fooW[] = {'f','o','o',0};
406  BYTE data[1024];
410  UINT i, len;
411  BOOL ret, restart = TRUE;
412  DWORD numbytes;
413 
415  pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
416  attr.Length = sizeof(attr);
417  attr.RootDirectory = 0;
418  attr.ObjectName = &nameW;
419  attr.Attributes = OBJ_CASE_INSENSITIVE;
420  attr.SecurityDescriptor = NULL;
421  attr.SecurityQualityOfService = NULL;
422  status = pNtOpenFile( &dir, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
424  ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
425  pRtlFreeUnicodeString( &nameW );
426 
427  path[3] = 0; /* root of the drive */
428  pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
429  status = pNtOpenFile( &root, GENERIC_READ, &attr, &io,
431  ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
432  pRtlFreeUnicodeString( &nameW );
433 
434  /* test opening system dir with RootDirectory set to windows dir */
436  while (path[len] == '\\') len++;
437  nameW.Buffer = path + len;
438  nameW.Length = lstrlenW(path + len) * sizeof(WCHAR);
439  attr.RootDirectory = dir;
440  status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
442  ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
443  CloseHandle( handle );
444 
445  /* try uppercase name */
446  for (i = len; path[i]; i++) if (path[i] >= 'a' && path[i] <= 'z') path[i] -= 'a' - 'A';
447  status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
449  ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
450  CloseHandle( handle );
451 
452  /* try with leading backslash */
453  nameW.Buffer--;
454  nameW.Length += sizeof(WCHAR);
455  status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
460  "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
461  if (!status) CloseHandle( handle );
462 
463  /* try with empty name */
464  nameW.Length = 0;
465  status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
467  ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
468  CloseHandle( handle );
469 
470  /* try open by file id */
471 
472  while (!pNtQueryDirectoryFile( dir, NULL, NULL, NULL, &io, data, sizeof(data),
474  {
476 
477  restart = FALSE;
478 
479  if (!info->FileId.QuadPart) continue;
480 
481  nameW.Buffer = (WCHAR *)&info->FileId;
482  nameW.Length = sizeof(info->FileId);
483  info->FileName[info->FileNameLength/sizeof(WCHAR)] = 0;
484  attr.RootDirectory = dir;
485  /* We skip 'open' files by not specifying FILE_SHARE_WRITE */
486  status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
489  ((info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_DIRECTORY_FILE : 0) );
491  "open %s failed %x\n", wine_dbgstr_w(info->FileName), status );
493  {
494  win_skip( "FILE_OPEN_BY_FILE_ID not supported\n" );
495  break;
496  }
498  trace( "%s is currently open\n", wine_dbgstr_w(info->FileName) );
499  if (!status)
500  {
501  BYTE buf[sizeof(FILE_ALL_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
502 
503  if (!pNtQueryInformationFile( handle, &io, buf, sizeof(buf), FileAllInformation ))
504  {
506 
507  /* check that it's the same file/directory */
508 
509  /* don't check the size for directories */
510  if (!(info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
511  ok( info->EndOfFile.QuadPart == fai->StandardInformation.EndOfFile.QuadPart,
512  "mismatched file size for %s\n", wine_dbgstr_w(info->FileName));
513 
514  ok( info->CreationTime.QuadPart == fai->BasicInformation.CreationTime.QuadPart,
515  "mismatched creation time for %s\n", wine_dbgstr_w(info->FileName));
516  }
517  CloseHandle( handle );
518 
519  /* try same thing from drive root */
520  attr.RootDirectory = root;
521  status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
524  ((info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_DIRECTORY_FILE : 0) );
526  "open %s failed %x\n", wine_dbgstr_w(info->FileName), status );
527  if (!status) CloseHandle( handle );
528  }
529  }
530 
531  CloseHandle( dir );
532  CloseHandle( root );
533 
536  pRtlDosPathNameToNtPathName_U( tmpfile, &nameW, NULL, NULL );
537 
539  ok( file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError() );
540  numbytes = 0xdeadbeef;
541  ret = WriteFile( file, testdata, sizeof(testdata) - 1, &numbytes, NULL );
542  ok( ret, "WriteFile failed with error %u\n", GetLastError() );
543  ok( numbytes == sizeof(testdata) - 1, "failed to write all data\n" );
544  CloseHandle( file );
545 
546  attr.Length = sizeof(attr);
547  attr.RootDirectory = 0;
548  attr.ObjectName = &nameW;
549  attr.Attributes = OBJ_CASE_INSENSITIVE;
550  attr.SecurityDescriptor = NULL;
551  attr.SecurityQualityOfService = NULL;
552  status = pNtOpenFile( &file, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
554  ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
555  pRtlFreeUnicodeString( &nameW );
556 
557  numbytes = 0xdeadbeef;
558  memset( data, 0, sizeof(data) );
559  ret = ReadFile( file, data, sizeof(data), &numbytes, NULL );
560  ok( ret, "ReadFile failed with error %u\n", GetLastError() );
561  ok( numbytes == sizeof(testdata) - 1, "failed to read all data\n" );
562  ok( !memcmp( data, testdata, sizeof(testdata) - 1 ), "testdata doesn't match\n" );
563 
564  nameW.Length = sizeof(fooW) - sizeof(WCHAR);
565  nameW.Buffer = fooW;
566  attr.RootDirectory = file;
567  attr.ObjectName = &nameW;
568  status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
571  "expected STATUS_OBJECT_PATH_NOT_FOUND, got %08x\n", status );
572 
573  nameW.Length = 0;
574  nameW.Buffer = NULL;
575  attr.RootDirectory = file;
576  attr.ObjectName = &nameW;
577  status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
579  ok( !status, "open %s failed %x\n", wine_dbgstr_w(tmpfile), status );
580 
581  numbytes = SetFilePointer( file, 0, 0, FILE_CURRENT );
582  ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes );
583  numbytes = SetFilePointer( root, 0, 0, FILE_CURRENT );
584  ok( numbytes == 0, "SetFilePointer returned %u\n", numbytes );
585 
586  numbytes = 0xdeadbeef;
587  memset( data, 0, sizeof(data) );
588  ret = ReadFile( root, data, sizeof(data), &numbytes, NULL );
589  ok( ret, "ReadFile failed with error %u\n", GetLastError() );
590  ok( numbytes == sizeof(testdata) - 1, "failed to read all data\n" );
591  ok( !memcmp( data, testdata, sizeof(testdata) - 1 ), "testdata doesn't match\n" );
592 
593  numbytes = SetFilePointer( file, 0, 0, FILE_CURRENT );
594  ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes );
595  numbytes = SetFilePointer( root, 0, 0, FILE_CURRENT );
596  ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %u\n", numbytes );
597 
598  CloseHandle( file );
599  CloseHandle( root );
600  DeleteFileW( tmpfile );
601 }
602 
603 static void delete_file_test(void)
604 {
605  NTSTATUS ret;
608  WCHAR pathW[MAX_PATH];
609  WCHAR pathsubW[MAX_PATH];
610  static const WCHAR testdirW[] = {'n','t','d','e','l','e','t','e','f','i','l','e',0};
611  static const WCHAR subdirW[] = {'\\','s','u','b',0};
612 
613  ret = GetTempPathW(MAX_PATH, pathW);
614  if (!ret)
615  {
616  ok(0, "couldn't get temp dir\n");
617  return;
618  }
619  if (ret + sizeof(testdirW)/sizeof(WCHAR)-1 + sizeof(subdirW)/sizeof(WCHAR)-1 >= MAX_PATH)
620  {
621  ok(0, "MAX_PATH exceeded in constructing paths\n");
622  return;
623  }
624 
625  lstrcatW(pathW, testdirW);
626  lstrcpyW(pathsubW, pathW);
627  lstrcatW(pathsubW, subdirW);
628 
629  ret = CreateDirectoryW(pathW, NULL);
630  ok(ret == TRUE, "couldn't create directory ntdeletefile\n");
631  if (!pRtlDosPathNameToNtPathName_U(pathW, &nameW, NULL, NULL))
632  {
633  ok(0,"RtlDosPathNametoNtPathName_U failed\n");
634  return;
635  }
636 
637  attr.Length = sizeof(attr);
638  attr.RootDirectory = 0;
639  attr.Attributes = OBJ_CASE_INSENSITIVE;
640  attr.ObjectName = &nameW;
641  attr.SecurityDescriptor = NULL;
642  attr.SecurityQualityOfService = NULL;
643 
644  /* test NtDeleteFile on an empty directory */
645  ret = pNtDeleteFile(&attr);
646  ok(ret == STATUS_SUCCESS, "NtDeleteFile should succeed in removing an empty directory\n");
647  ret = RemoveDirectoryW(pathW);
648  ok(ret == FALSE, "expected to fail removing directory, NtDeleteFile should have removed it\n");
649 
650  /* test NtDeleteFile on a non-empty directory */
651  ret = CreateDirectoryW(pathW, NULL);
652  ok(ret == TRUE, "couldn't create directory ntdeletefile ?!\n");
653  ret = CreateDirectoryW(pathsubW, NULL);
654  ok(ret == TRUE, "couldn't create directory subdir\n");
655  ret = pNtDeleteFile(&attr);
656  ok(ret == STATUS_SUCCESS, "expected NtDeleteFile to ret STATUS_SUCCESS\n");
657  ret = RemoveDirectoryW(pathsubW);
658  ok(ret == TRUE, "expected to remove directory ntdeletefile\\sub\n");
659  ret = RemoveDirectoryW(pathW);
660  ok(ret == TRUE, "expected to remove directory ntdeletefile, NtDeleteFile failed.\n");
661 
662  pRtlFreeUnicodeString( &nameW );
663 }
664 
665 static void read_file_test(void)
666 {
667  const char text[] = "foobar";
668  HANDLE handle;
671  int apc_count = 0;
672  char buffer[128];
674  HANDLE event = CreateEventA( NULL, TRUE, FALSE, NULL );
675 
676  if (!(handle = create_temp_file( FILE_FLAG_OVERLAPPED ))) return;
677  apc_count = 0;
678  U(iosb).Status = 0xdeadbabe;
679  iosb.Information = 0xdeadbeef;
680  offset.QuadPart = 0;
681  ResetEvent( event );
682  status = pNtWriteFile( handle, event, apc, &apc_count, &iosb, text, strlen(text), &offset, NULL );
683  ok( status == STATUS_SUCCESS || status == STATUS_PENDING, "wrong status %x\n", status );
685  ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status );
686  ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information );
687  ok( is_signaled( event ), "event is not signaled\n" );
688  ok( !apc_count, "apc was called\n" );
689  SleepEx( 1, TRUE ); /* alertable sleep */
690  ok( apc_count == 1, "apc was not called\n" );
691 
692  apc_count = 0;
693  U(iosb).Status = 0xdeadbabe;
694  iosb.Information = 0xdeadbeef;
695  offset.QuadPart = 0;
696  ResetEvent( event );
697  status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, strlen(text) + 10, &offset, NULL );
698  ok( status == STATUS_SUCCESS ||
699  status == STATUS_PENDING, /* vista */
700  "wrong status %x\n", status );
702  ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status );
703  ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information );
704  ok( is_signaled( event ), "event is not signaled\n" );
705  ok( !apc_count, "apc was called\n" );
706  SleepEx( 1, TRUE ); /* alertable sleep */
707  ok( apc_count == 1, "apc was not called\n" );
708 
709  /* read beyond eof */
710  apc_count = 0;
711  U(iosb).Status = 0xdeadbabe;
712  iosb.Information = 0xdeadbeef;
713  offset.QuadPart = strlen(text) + 2;
714  status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, 2, &offset, NULL );
715  ok(status == STATUS_PENDING || status == STATUS_END_OF_FILE /* before Vista */, "expected STATUS_PENDING or STATUS_END_OF_FILE, got %#x\n", status);
716  if (status == STATUS_PENDING) /* vista */
717  {
718  WaitForSingleObject( event, 1000 );
719  ok( U(iosb).Status == STATUS_END_OF_FILE, "wrong status %x\n", U(iosb).Status );
720  ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information );
721  ok( is_signaled( event ), "event is not signaled\n" );
722  ok( !apc_count, "apc was called\n" );
723  SleepEx( 1, TRUE ); /* alertable sleep */
724  ok( apc_count == 1, "apc was not called\n" );
725  }
726  CloseHandle( handle );
727 
728  /* now a non-overlapped file */
729  if (!(handle = create_temp_file(0))) return;
730  apc_count = 0;
731  U(iosb).Status = 0xdeadbabe;
732  iosb.Information = 0xdeadbeef;
733  offset.QuadPart = 0;
734  status = pNtWriteFile( handle, event, apc, &apc_count, &iosb, text, strlen(text), &offset, NULL );
736  status == STATUS_SUCCESS ||
737  status == STATUS_PENDING, /* vista */
738  "wrong status %x\n", status );
740  ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status );
741  ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information );
742  ok( is_signaled( event ), "event is not signaled\n" );
743  ok( !apc_count, "apc was called\n" );
744  SleepEx( 1, TRUE ); /* alertable sleep */
745  ok( apc_count == 1, "apc was not called\n" );
746 
747  apc_count = 0;
748  U(iosb).Status = 0xdeadbabe;
749  iosb.Information = 0xdeadbeef;
750  offset.QuadPart = 0;
751  ResetEvent( event );
752  status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, strlen(text) + 10, &offset, NULL );
753  ok( status == STATUS_SUCCESS, "wrong status %x\n", status );
754  ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status );
755  ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information );
756  ok( is_signaled( event ), "event is not signaled\n" );
757  ok( !apc_count, "apc was called\n" );
758  SleepEx( 1, TRUE ); /* alertable sleep */
759  todo_wine ok( !apc_count, "apc was called\n" );
760 
761  /* read beyond eof */
762  apc_count = 0;
763  U(iosb).Status = 0xdeadbabe;
764  iosb.Information = 0xdeadbeef;
765  offset.QuadPart = strlen(text) + 2;
766  ResetEvent( event );
767  status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, 2, &offset, NULL );
768  ok( status == STATUS_END_OF_FILE, "wrong status %x\n", status );
769  ok( U(iosb).Status == STATUS_END_OF_FILE, "wrong status %x\n", U(iosb).Status );
770  ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information );
771  ok( is_signaled( event ), "event is not signaled\n" );
772  ok( !apc_count, "apc was called\n" );
773  SleepEx( 1, TRUE ); /* alertable sleep */
774  ok( !apc_count, "apc was called\n" );
775 
776  CloseHandle( handle );
777 
778  CloseHandle( event );
779 }
780 
781 static void append_file_test(void)
782 {
783  static const char text[6] = "foobar";
784  HANDLE handle;
788  char path[MAX_PATH], buffer[MAX_PATH], buf[16];
789  DWORD ret;
790 
792  GetTempFileNameA( path, "foo", 0, buffer );
793 
795  ok(handle != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
796 
797  U(iosb).Status = -1;
798  iosb.Information = -1;
799  status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text, 2, NULL, NULL);
800  ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status);
801  ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status);
802  ok(iosb.Information == 2, "expected 2, got %lu\n", iosb.Information);
803 
805 
806  /* It is possible to open a file with only FILE_APPEND_DATA access flags.
807  It matches the O_WRONLY|O_APPEND open() posix behavior */
809  ok(handle != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
810 
811  U(iosb).Status = -1;
812  iosb.Information = -1;
813  offset.QuadPart = 1;
814  status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 2, 2, &offset, NULL);
815  ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status);
816  ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status);
817  ok(iosb.Information == 2, "expected 2, got %lu\n", iosb.Information);
818 
820  ok(ret == 4, "expected 4, got %u\n", ret);
821 
822  U(iosb).Status = -1;
823  iosb.Information = -1;
824  offset.QuadPart = 3;
825  status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 4, 2, &offset, NULL);
826  ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status);
827  ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status);
828  ok(iosb.Information == 2, "expected 2, got %lu\n", iosb.Information);
829 
831  ok(ret == 6, "expected 6, got %u\n", ret);
832 
834 
836  ok(handle != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
837 
838  memset(buf, 0, sizeof(buf));
839  U(iosb).Status = -1;
840  iosb.Information = -1;
841  offset.QuadPart = 0;
842  status = pNtReadFile(handle, 0, NULL, NULL, &iosb, buf, sizeof(buf), &offset, NULL);
843  ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status);
844  ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status);
845  ok(iosb.Information == 6, "expected 6, got %lu\n", iosb.Information);
846  buf[6] = 0;
847  ok(memcmp(buf, text, 6) == 0, "wrong file contents: %s\n", buf);
848 
849  U(iosb).Status = -1;
850  iosb.Information = -1;
851  offset.QuadPart = 0;
852  status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 3, 3, &offset, NULL);
853  ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status);
854  ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status);
855  ok(iosb.Information == 3, "expected 3, got %lu\n", iosb.Information);
856 
857  memset(buf, 0, sizeof(buf));
858  U(iosb).Status = -1;
859  iosb.Information = -1;
860  offset.QuadPart = 0;
861  status = pNtReadFile(handle, 0, NULL, NULL, &iosb, buf, sizeof(buf), &offset, NULL);
862  ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status);
863  ok(U(iosb).Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", U(iosb).Status);
864  ok(iosb.Information == 6, "expected 6, got %lu\n", iosb.Information);
865  buf[6] = 0;
866  ok(memcmp(buf, "barbar", 6) == 0, "wrong file contents: %s\n", buf);
867 
870 }
871 
872 static void nt_mailslot_test(void)
873 {
874  HANDLE hslot;
877 
879  ULONG MailslotQuota;
880  ULONG MaxMessageSize;
881  LARGE_INTEGER TimeOut;
883  NTSTATUS rc;
885  WCHAR buffer1[] = { '\\','?','?','\\','M','A','I','L','S','L','O','T','\\',
886  'R',':','\\','F','R','E','D','\0' };
887 
888  TimeOut.QuadPart = -1;
889 
890  pRtlInitUnicodeString(&str, buffer1);
892  CreateOptions = MailslotQuota = MaxMessageSize = 0;
894 
895  /*
896  * Check for NULL pointer handling
897  */
898  rc = pNtCreateMailslotFile(NULL, DesiredAccess,
899  &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize,
900  &TimeOut);
901  ok( rc == STATUS_ACCESS_VIOLATION ||
902  rc == STATUS_INVALID_PARAMETER, /* win2k3 */
903  "rc = %x not STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER\n", rc);
904 
905  /*
906  * Test to see if the Timeout can be NULL
907  */
908  hslot = (HANDLE)0xdeadbeef;
909  rc = pNtCreateMailslotFile(&hslot, DesiredAccess,
910  &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize,
911  NULL);
912  ok( rc == STATUS_SUCCESS ||
913  rc == STATUS_INVALID_PARAMETER, /* win2k3 */
914  "rc = %x not STATUS_SUCCESS or STATUS_INVALID_PARAMETER\n", rc);
915  ok( hslot != 0, "Handle is invalid\n");
916 
917  if ( rc == STATUS_SUCCESS ) pNtClose(hslot);
918 
919  /*
920  * Test a valid call
921  */
923  rc = pNtCreateMailslotFile(&hslot, DesiredAccess,
924  &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize,
925  &TimeOut);
926  ok( rc == STATUS_SUCCESS, "Create MailslotFile failed rc = %x\n", rc);
927  ok( hslot != 0, "Handle is invalid\n");
928 
929  rc = pNtClose(hslot);
930  ok( rc == STATUS_SUCCESS, "NtClose failed\n");
931 }
932 
934 {
935  NTSTATUS res;
936  ULONG count;
937  SIZE_T size = 3;
938 
939  if (sizeof(size) > 4) size |= (ULONGLONG)0x12345678 << 32;
940 
941  res = pNtSetIoCompletion( h, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size );
942  ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %x\n", res );
943 
945  ok( count == 1, "Unexpected msg count: %d\n", count );
946 
947  if (get_msg(h))
948  {
949  ok( completionKey == CKEY_FIRST, "Invalid completion key: %lx\n", completionKey );
950  ok( ioSb.Information == size, "Invalid ioSb.Information: %lu\n", ioSb.Information );
951  ok( U(ioSb).Status == STATUS_INVALID_DEVICE_REQUEST, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
952  ok( completionValue == CVALUE_FIRST, "Invalid completion value: %lx\n", completionValue );
953  }
954 
956  ok( !count, "Unexpected msg count: %d\n", count );
957 }
958 
960 {
961  static const char pipe_name[] = "\\\\.\\pipe\\iocompletiontestnamedpipe";
962 
965  HANDLE hPipeSrv, hPipeClt;
966  NTSTATUS res;
967 
968  hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL );
969  ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" );
970  if (hPipeSrv != INVALID_HANDLE_VALUE )
971  {
973  ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" );
974  if (hPipeClt != INVALID_HANDLE_VALUE)
975  {
976  U(iosb).Status = 0xdeadbeef;
977  res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation );
978  ok( res == STATUS_INVALID_PARAMETER, "Unexpected NtSetInformationFile on non-overlapped handle: %x\n", res );
979  ok( U(iosb).Status == STATUS_INVALID_PARAMETER /* 98 */ || U(iosb).Status == 0xdeadbeef /* NT4+ */,
980  "Unexpected iosb.Status on non-overlapped handle: %x\n", U(iosb).Status );
981  CloseHandle(hPipeClt);
982  }
983  CloseHandle( hPipeSrv );
984  }
985 
987  ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" );
988  if (hPipeSrv == INVALID_HANDLE_VALUE )
989  return;
990 
992  ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" );
993  if (hPipeClt != INVALID_HANDLE_VALUE)
994  {
995  OVERLAPPED o = {0,};
997  DWORD read;
998  long count;
999 
1000  U(iosb).Status = 0xdeadbeef;
1001  res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation );
1002  ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res );
1003  ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status );
1004 
1005  memset( send_buf, 0, TEST_BUF_LEN );
1006  memset( recv_buf, 0xde, TEST_BUF_LEN );
1008  ok( !count, "Unexpected msg count: %ld\n", count );
1009  ReadFile( hPipeSrv, recv_buf, TEST_BUF_LEN, &read, &o);
1011  ok( !count, "Unexpected msg count: %ld\n", count );
1012  WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL );
1013 
1014  if (get_msg(h))
1015  {
1016  ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
1017  ok( ioSb.Information == 3, "Invalid ioSb.Information: %ld\n", ioSb.Information );
1018  ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
1019  ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue );
1020  ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n", recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] );
1021  }
1023  ok( !count, "Unexpected msg count: %ld\n", count );
1024 
1025  memset( send_buf, 0, TEST_BUF_LEN );
1026  memset( recv_buf, 0xde, TEST_BUF_LEN );
1027  WriteFile( hPipeClt, send_buf, 2, &read, NULL );
1029  ok( !count, "Unexpected msg count: %ld\n", count );
1030  ReadFile( hPipeSrv, recv_buf, 2, &read, &o);
1032  ok( count == 1, "Unexpected msg count: %ld\n", count );
1033  if (get_msg(h))
1034  {
1035  ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
1036  ok( ioSb.Information == 2, "Invalid ioSb.Information: %ld\n", ioSb.Information );
1037  ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
1038  ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue );
1039  ok( !memcmp( send_buf, recv_buf, 2 ), "Receive buffer (%x %x) did not match send buffer (%x %x)\n", recv_buf[0], recv_buf[1], send_buf[0], send_buf[1] );
1040  }
1041 
1042  ReadFile( hPipeSrv, recv_buf, TEST_BUF_LEN, &read, &o);
1043  CloseHandle( hPipeSrv );
1045  ok( count == 1, "Unexpected msg count: %ld\n", count );
1046  if (get_msg(h))
1047  {
1048  ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
1049  ok( ioSb.Information == 0, "Invalid ioSb.Information: %ld\n", ioSb.Information );
1050  /* wine sends wrong status here */
1051  ok( U(ioSb).Status == STATUS_PIPE_BROKEN, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
1052  ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue );
1053  }
1054  }
1055 
1056  CloseHandle( hPipeClt );
1057 
1058  /* test associating a completion port with a handle after an async is queued */
1060  ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" );
1061  if (hPipeSrv == INVALID_HANDLE_VALUE )
1062  return;
1064  ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" );
1065  if (hPipeClt != INVALID_HANDLE_VALUE)
1066  {
1067  OVERLAPPED o = {0,};
1068  BYTE send_buf[TEST_BUF_LEN], recv_buf[TEST_BUF_LEN];
1069  int apc_count = 0;
1070  DWORD read;
1071  long count;
1072 
1073  memset( send_buf, 0, TEST_BUF_LEN );
1074  memset( recv_buf, 0xde, TEST_BUF_LEN );
1076  ok( !count, "Unexpected msg count: %ld\n", count );
1077  ReadFile( hPipeSrv, recv_buf, TEST_BUF_LEN, &read, &o);
1078 
1079  U(iosb).Status = 0xdeadbeef;
1080  res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation );
1081  ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res );
1082  ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status );
1084  ok( !count, "Unexpected msg count: %ld\n", count );
1085 
1086  WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL );
1087 
1088  if (get_msg(h))
1089  {
1090  ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
1091  ok( ioSb.Information == 3, "Invalid ioSb.Information: %ld\n", ioSb.Information );
1092  ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
1093  ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue );
1094  ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n", recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] );
1095  }
1097  ok( !count, "Unexpected msg count: %ld\n", count );
1098 
1099  /* using APCs on handle with associated completion port is not allowed */
1100  res = NtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
1101  ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %x\n", res);
1102  }
1103 
1104  CloseHandle( hPipeSrv );
1105  CloseHandle( hPipeClt );
1106 
1107  /* test associating a completion port with a handle after an async using APC is queued */
1109  ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" );
1110  if (hPipeSrv == INVALID_HANDLE_VALUE )
1111  return;
1113  ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" );
1114  if (hPipeClt != INVALID_HANDLE_VALUE)
1115  {
1116  BYTE send_buf[TEST_BUF_LEN], recv_buf[TEST_BUF_LEN];
1117  int apc_count = 0;
1118  DWORD read;
1119  long count;
1120 
1121  memset( send_buf, 0, TEST_BUF_LEN );
1122  memset( recv_buf, 0xde, TEST_BUF_LEN );
1124  ok( !count, "Unexpected msg count: %ld\n", count );
1125 
1126  res = NtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
1127  ok(res == STATUS_PENDING, "NtReadFile returned %x\n", res);
1128 
1129  U(iosb).Status = 0xdeadbeef;
1130  res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation );
1131  ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res );
1132  ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status );
1134  ok( !count, "Unexpected msg count: %ld\n", count );
1135 
1136  WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL );
1137 
1138  ok(!apc_count, "apc_count = %u\n", apc_count);
1140  ok( !count, "Unexpected msg count: %ld\n", count );
1141 
1142  SleepEx(1, TRUE); /* alertable sleep */
1143  ok(apc_count == 1, "apc was not called\n");
1145  ok( !count, "Unexpected msg count: %ld\n", count );
1146 
1147  /* using APCs on handle with associated completion port is not allowed */
1148  res = NtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
1149  ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %x\n", res);
1150  }
1151 
1152  CloseHandle( hPipeSrv );
1153  CloseHandle( hPipeClt );
1154 }
1155 
1157 {
1161  HANDLE h;
1162  NTSTATUS res;
1163 
1164  if(!(h = create_temp_file(0))) return ;
1165 
1166  memset(&ffsi,0,sizeof(ffsi));
1167  memset(&fsi,0,sizeof(fsi));
1168 
1169  /* Assume No Quota Settings configured on Wine Testbot */
1170  res = pNtQueryVolumeInformationFile(h, &io, &ffsi, sizeof ffsi, FileFsFullSizeInformation);
1171  ok(res == STATUS_SUCCESS, "cannot get attributes, res %x\n", res);
1172  res = pNtQueryVolumeInformationFile(h, &io, &fsi, sizeof fsi, FileFsSizeInformation);
1173  ok(res == STATUS_SUCCESS, "cannot get attributes, res %x\n", res);
1174 
1175  /* Test for FileFsSizeInformation */
1177  "[fsi] TotalAllocationUnits expected positive, got 0x%s\n",
1180  "[fsi] AvailableAllocationUnits expected positive, got 0x%s\n",
1182 
1183  /* Assume file system is NTFS */
1184  ok(fsi.BytesPerSector == 512, "[fsi] BytesPerSector expected 512, got %d\n",fsi.BytesPerSector);
1185  ok(fsi.SectorsPerAllocationUnit == 8, "[fsi] SectorsPerAllocationUnit expected 8, got %d\n",fsi.SectorsPerAllocationUnit);
1186 
1187  ok(ffsi.TotalAllocationUnits.QuadPart > 0,
1188  "[ffsi] TotalAllocationUnits expected positive, got negative value 0x%s\n",
1191  "[ffsi] CallerAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1194  "[ffsi] ActualAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1197  "[ffsi] TotalAllocationUnits error fsi:0x%s, ffsi:0x%s\n",
1201  "[ffsi] CallerAvailableAllocationUnits error fsi:0x%s, ffsi: 0x%s\n",
1204 
1205  /* Assume file system is NTFS */
1206  ok(ffsi.BytesPerSector == 512, "[ffsi] BytesPerSector expected 512, got %d\n",ffsi.BytesPerSector);
1207  ok(ffsi.SectorsPerAllocationUnit == 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %d\n",ffsi.SectorsPerAllocationUnit);
1208 
1209  CloseHandle( h );
1210 }
1211 
1213 {
1216  HANDLE h;
1217  int res;
1219 
1220  if (!(h = create_temp_file(0))) return;
1221 
1222  /* Check default first */
1223  memset(&fbi, 0, sizeof(fbi));
1224  res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1225  ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
1227  "attribute %x not expected\n", fbi.FileAttributes );
1228 
1229  /* Then SYSTEM */
1230  /* Clear fbi to avoid setting times */
1231  memset(&fbi, 0, sizeof(fbi));
1233  U(io).Status = 0xdeadbeef;
1234  res = pNtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1235  ok ( res == STATUS_SUCCESS, "can't set system attribute, NtSetInformationFile returned %x\n", res );
1236  ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %x\n", U(io).Status );
1237 
1238  memset(&fbi, 0, sizeof(fbi));
1239  res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1240  ok ( res == STATUS_SUCCESS, "can't get attributes\n");
1241  ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fbi.FileAttributes );
1242 
1243  /* Then HIDDEN */
1244  memset(&fbi, 0, sizeof(fbi));
1246  U(io).Status = 0xdeadbeef;
1247  res = pNtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1248  ok ( res == STATUS_SUCCESS, "can't set system attribute, NtSetInformationFile returned %x\n", res );
1249  ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %x\n", U(io).Status );
1250 
1251  memset(&fbi, 0, sizeof(fbi));
1252  res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1253  ok ( res == STATUS_SUCCESS, "can't get attributes\n");
1254  ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fbi.FileAttributes );
1255 
1256  /* Check NORMAL last of all (to make sure we can clear attributes) */
1257  memset(&fbi, 0, sizeof(fbi));
1259  U(io).Status = 0xdeadbeef;
1260  res = pNtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1261  ok ( res == STATUS_SUCCESS, "can't set normal attribute, NtSetInformationFile returned %x\n", res );
1262  ok ( U(io).Status == STATUS_SUCCESS, "can't set normal attribute, io.Status is %x\n", U(io).Status );
1263 
1264  memset(&fbi, 0, sizeof(fbi));
1265  res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1266  ok ( res == STATUS_SUCCESS, "can't get attributes\n");
1267  todo_wine ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_NORMAL, "attribute %x not 0\n", fbi.FileAttributes );
1268 
1269  CloseHandle( h );
1270 }
1271 
1272 static void test_file_all_information(void)
1273 {
1275  /* FileAllInformation, like FileNameInformation, has a variable-length pathname
1276  * buffer at the end. Vista objects with STATUS_BUFFER_OVERFLOW if you
1277  * don't leave enough room there.
1278  */
1279  struct {
1281  WCHAR buf[256];
1282  } fai_buf;
1283  HANDLE h;
1284  int res;
1286 
1287  if (!(h = create_temp_file(0))) return;
1288 
1289  /* Check default first */
1290  res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
1291  ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
1292  ok ( (fai_buf.fai.BasicInformation.FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE,
1293  "attribute %x not expected\n", fai_buf.fai.BasicInformation.FileAttributes );
1294 
1295  /* Then SYSTEM */
1296  /* Clear fbi to avoid setting times */
1297  memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
1298  fai_buf.fai.BasicInformation.FileAttributes = FILE_ATTRIBUTE_SYSTEM;
1299  U(io).Status = 0xdeadbeef;
1300  res = pNtSetInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
1301  ok ( res == STATUS_INVALID_INFO_CLASS || broken(res == STATUS_NOT_IMPLEMENTED), "shouldn't be able to set FileAllInformation, res %x\n", res);
1302  todo_wine ok ( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileAllInformation, io.Status is %x\n", U(io).Status);
1303  U(io).Status = 0xdeadbeef;
1304  res = pNtSetInformationFile(h, &io, &fai_buf.fai.BasicInformation, sizeof fai_buf.fai.BasicInformation, FileBasicInformation);
1305  ok ( res == STATUS_SUCCESS, "can't set system attribute, res: %x\n", res );
1306  ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status: %x\n", U(io).Status );
1307 
1308  memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
1309  res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
1310  ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
1311  ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fai_buf.fai.BasicInformation.FileAttributes );
1312 
1313  /* Then HIDDEN */
1314  memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
1315  fai_buf.fai.BasicInformation.FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1316  U(io).Status = 0xdeadbeef;
1317  res = pNtSetInformationFile(h, &io, &fai_buf.fai.BasicInformation, sizeof fai_buf.fai.BasicInformation, FileBasicInformation);
1318  ok ( res == STATUS_SUCCESS, "can't set system attribute, res: %x\n", res );
1319  ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status: %x\n", U(io).Status );
1320 
1321  memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
1322  res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
1323  ok ( res == STATUS_SUCCESS, "can't get attributes\n");
1324  ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fai_buf.fai.BasicInformation.FileAttributes );
1325 
1326  /* Check NORMAL last of all (to make sure we can clear attributes) */
1327  memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
1328  fai_buf.fai.BasicInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1329  U(io).Status = 0xdeadbeef;
1330  res = pNtSetInformationFile(h, &io, &fai_buf.fai.BasicInformation, sizeof fai_buf.fai.BasicInformation, FileBasicInformation);
1331  ok ( res == STATUS_SUCCESS, "can't set system attribute, res: %x\n", res );
1332  ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status: %x\n", U(io).Status );
1333 
1334  memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
1335  res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
1336  ok ( res == STATUS_SUCCESS, "can't get attributes\n");
1337  todo_wine ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_NORMAL, "attribute %x not FILE_ATTRIBUTE_NORMAL\n", fai_buf.fai.BasicInformation.FileAttributes );
1338 
1339  CloseHandle( h );
1340 }
1341 
1342 static void delete_object( WCHAR *path )
1343 {
1344  BOOL ret = DeleteFileW( path );
1346  "DeleteFileW failed with %u\n", GetLastError() );
1347  if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1348  {
1349  ret = RemoveDirectoryW( path );
1350  ok( ret, "RemoveDirectoryW failed with %u\n", GetLastError() );
1351  }
1352 }
1353 
1355 {
1356  static const WCHAR foo_txtW[] = {'\\','f','o','o','.','t','x','t',0};
1357  static const WCHAR fooW[] = {'f','o','o',0};
1358  WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16], *filename, *p;
1360  FILE_NAME_INFORMATION *fni;
1361  BOOL success, fileDeleted;
1362  UNICODE_STRING name_str;
1363  HANDLE handle, handle2;
1365  NTSTATUS res;
1366 
1367  GetTempPathW( MAX_PATH, tmp_path );
1368 
1369  /* oldpath is a file, newpath doesn't exist */
1370  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1371  ok( res != 0, "failed to create temp file\n" );
1372  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1373  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1374 
1375  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1376  ok( res != 0, "failed to create temp file\n" );
1377  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1378  DeleteFileW( newpath );
1379  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1380  fri->Replace = FALSE;
1381  fri->RootDir = NULL;
1382  fri->FileNameLength = name_str.Length;
1383  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1384  pRtlFreeUnicodeString( &name_str );
1385 
1386  U(io).Status = 0xdeadbeef;
1387  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1388  ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
1389  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
1391  ok( fileDeleted, "file should not exist\n" );
1393  ok( !fileDeleted, "file should exist\n" );
1394 
1395  fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
1396  res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
1397  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
1398  fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
1399  ok( !lstrcmpiW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n",
1400  wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) );
1401  HeapFree( GetProcessHeap(), 0, fni );
1402 
1403  CloseHandle( handle );
1404  HeapFree( GetProcessHeap(), 0, fri );
1405  delete_object( oldpath );
1406  delete_object( newpath );
1407 
1408  /* oldpath is a file, newpath is a file, Replace = FALSE */
1409  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1410  ok( res != 0, "failed to create temp file\n" );
1411  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1412  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1413 
1414  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1415  ok( res != 0, "failed to create temp file\n" );
1416  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1417  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1418  fri->Replace = FALSE;
1419  fri->RootDir = NULL;
1420  fri->FileNameLength = name_str.Length;
1421  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1422  pRtlFreeUnicodeString( &name_str );
1423 
1424  U(io).Status = 0xdeadbeef;
1425  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1426  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1427  ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
1429  ok( !fileDeleted, "file should exist\n" );
1431  ok( !fileDeleted, "file should exist\n" );
1432 
1433  CloseHandle( handle );
1434  HeapFree( GetProcessHeap(), 0, fri );
1435  delete_object( oldpath );
1436  delete_object( newpath );
1437 
1438  /* oldpath is a file, newpath is a file, Replace = TRUE */
1439  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1440  ok( res != 0, "failed to create temp file\n" );
1441  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1442  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1443 
1444  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1445  ok( res != 0, "failed to create temp file\n" );
1446  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1447  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1448  fri->Replace = TRUE;
1449  fri->RootDir = NULL;
1450  fri->FileNameLength = name_str.Length;
1451  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1452  pRtlFreeUnicodeString( &name_str );
1453 
1454  U(io).Status = 0xdeadbeef;
1455  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1456  ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
1457  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
1459  ok( fileDeleted, "file should not exist\n" );
1461  ok( !fileDeleted, "file should exist\n" );
1462 
1463  CloseHandle( handle );
1464  HeapFree( GetProcessHeap(), 0, fri );
1465  delete_object( oldpath );
1466  delete_object( newpath );
1467 
1468  /* oldpath is a file, newpath is a file, Replace = FALSE, target file opened */
1469  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1470  ok( res != 0, "failed to create temp file\n" );
1471  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1472  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1473 
1474  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1475  ok( res != 0, "failed to create temp file\n" );
1476  handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1477  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1478 
1479  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1480  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1481  fri->Replace = FALSE;
1482  fri->RootDir = NULL;
1483  fri->FileNameLength = name_str.Length;
1484  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1485  pRtlFreeUnicodeString( &name_str );
1486 
1487  U(io).Status = 0xdeadbeef;
1488  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1489  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1490  ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
1492  ok( !fileDeleted, "file should exist\n" );
1494  ok( !fileDeleted, "file should exist\n" );
1495 
1496  CloseHandle( handle );
1497  CloseHandle( handle2 );
1498  HeapFree( GetProcessHeap(), 0, fri );
1499  delete_object( oldpath );
1500  delete_object( newpath );
1501 
1502  /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened */
1503  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1504  ok( res != 0, "failed to create temp file\n" );
1505  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1506  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1507 
1508  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1509  ok( res != 0, "failed to create temp file\n" );
1510  handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1511  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1512 
1513  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1514  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1515  fri->Replace = TRUE;
1516  fri->RootDir = NULL;
1517  fri->FileNameLength = name_str.Length;
1518  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1519  pRtlFreeUnicodeString( &name_str );
1520 
1521  U(io).Status = 0xdeadbeef;
1522  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1523  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1524  ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
1526  ok( !fileDeleted, "file should exist\n" );
1528  ok( !fileDeleted, "file should exist\n" );
1529 
1530  CloseHandle( handle );
1531  CloseHandle( handle2 );
1532  HeapFree( GetProcessHeap(), 0, fri );
1533  delete_object( oldpath );
1534  delete_object( newpath );
1535 
1536  /* oldpath is a directory, newpath doesn't exist, Replace = FALSE */
1537  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1538  ok( res != 0, "failed to create temp file\n" );
1539  DeleteFileW( oldpath );
1540  success = CreateDirectoryW( oldpath, NULL );
1541  ok( success != 0, "failed to create temp directory\n" );
1543  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1544 
1545  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1546  ok( res != 0, "failed to create temp file\n" );
1547  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1548  DeleteFileW( newpath );
1549  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1550  fri->Replace = FALSE;
1551  fri->RootDir = NULL;
1552  fri->FileNameLength = name_str.Length;
1553  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1554  pRtlFreeUnicodeString( &name_str );
1555 
1556  U(io).Status = 0xdeadbeef;
1557  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1558  ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
1559  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
1561  ok( fileDeleted, "file should not exist\n" );
1563  ok( !fileDeleted, "file should exist\n" );
1564 
1565  fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
1566  res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
1567  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
1568  fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
1569  ok( !lstrcmpiW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n",
1570  wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) );
1571  HeapFree( GetProcessHeap(), 0, fni );
1572 
1573  CloseHandle( handle );
1574  HeapFree( GetProcessHeap(), 0, fri );
1575  delete_object( oldpath );
1576  delete_object( newpath );
1577 
1578  /* oldpath is a directory (but child object opened), newpath doesn't exist, Replace = FALSE */
1579  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1580  ok( res != 0, "failed to create temp file\n" );
1581  DeleteFileW( oldpath );
1582  success = CreateDirectoryW( oldpath, NULL );
1583  ok( success != 0, "failed to create temp directory\n" );
1585  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1586 
1587  lstrcpyW( newpath, oldpath );
1588  lstrcatW( newpath, foo_txtW );
1590  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1591 
1592  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1593  ok( res != 0, "failed to create temp file\n" );
1594  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1595  DeleteFileW( newpath );
1596  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1597  fri->Replace = FALSE;
1598  fri->RootDir = NULL;
1599  fri->FileNameLength = name_str.Length;
1600  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1601  pRtlFreeUnicodeString( &name_str );
1602 
1603  U(io).Status = 0xdeadbeef;
1604  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1605  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1606  todo_wine ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
1608  todo_wine ok( !fileDeleted, "file should exist\n" );
1610  todo_wine ok( fileDeleted, "file should not exist\n" );
1611 
1612  CloseHandle( handle );
1613  CloseHandle( handle2 );
1614  HeapFree( GetProcessHeap(), 0, fri );
1615  delete_object( oldpath );
1616  if (res == STATUS_SUCCESS) /* remove when Wine is fixed */
1617  {
1618  lstrcpyW( oldpath, newpath );
1619  lstrcatW( oldpath, foo_txtW );
1620  delete_object( oldpath );
1621  }
1622  delete_object( newpath );
1623 
1624  /* oldpath is a directory, newpath is a file, Replace = FALSE */
1625  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1626  ok( res != 0, "failed to create temp file\n" );
1627  DeleteFileW( oldpath );
1628  success = CreateDirectoryW( oldpath, NULL );
1629  ok( success != 0, "failed to create temp directory\n" );
1631  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1632 
1633  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1634  ok( res != 0, "failed to create temp file\n" );
1635  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1636  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1637  fri->Replace = FALSE;
1638  fri->RootDir = NULL;
1639  fri->FileNameLength = name_str.Length;
1640  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1641  pRtlFreeUnicodeString( &name_str );
1642 
1643  U(io).Status = 0xdeadbeef;
1644  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1645  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1646  ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
1648  ok( !fileDeleted, "file should exist\n" );
1650  ok( !fileDeleted, "file should exist\n" );
1651 
1652  CloseHandle( handle );
1653  HeapFree( GetProcessHeap(), 0, fri );
1654  delete_object( oldpath );
1655  delete_object( newpath );
1656 
1657  /* oldpath is a directory, newpath is a file, Replace = FALSE, target file opened */
1658  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1659  ok( res != 0, "failed to create temp file\n" );
1660  DeleteFileW( oldpath );
1661  success = CreateDirectoryW( oldpath, NULL );
1662  ok( success != 0, "failed to create temp directory\n" );
1664  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1665 
1666  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1667  ok( res != 0, "failed to create temp file\n" );
1668  handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1669  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1670 
1671  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1672  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1673  fri->Replace = FALSE;
1674  fri->RootDir = NULL;
1675  fri->FileNameLength = name_str.Length;
1676  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1677  pRtlFreeUnicodeString( &name_str );
1678 
1679  U(io).Status = 0xdeadbeef;
1680  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1681  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1682  ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
1684  ok( !fileDeleted, "file should exist\n" );
1686  ok( !fileDeleted, "file should exist\n" );
1687 
1688  CloseHandle( handle );
1689  CloseHandle( handle2 );
1690  HeapFree( GetProcessHeap(), 0, fri );
1691  delete_object( oldpath );
1692  delete_object( newpath );
1693 
1694  /* oldpath is a directory, newpath is a file, Replace = TRUE */
1695  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1696  ok( res != 0, "failed to create temp file\n" );
1697  DeleteFileW( oldpath );
1698  success = CreateDirectoryW( oldpath, NULL );
1699  ok( success != 0, "failed to create temp directory\n" );
1701  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1702 
1703  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1704  ok( res != 0, "failed to create temp file\n" );
1705  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1706  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1707  fri->Replace = TRUE;
1708  fri->RootDir = NULL;
1709  fri->FileNameLength = name_str.Length;
1710  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1711  pRtlFreeUnicodeString( &name_str );
1712 
1713  U(io).Status = 0xdeadbeef;
1714  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1715  ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
1716  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
1718  ok( fileDeleted, "file should not exist\n" );
1720  ok( !fileDeleted, "file should exist\n" );
1721 
1722  CloseHandle( handle );
1723  HeapFree( GetProcessHeap(), 0, fri );
1724  delete_object( oldpath );
1725  delete_object( newpath );
1726 
1727  /* oldpath is a directory, newpath is a file, Replace = TRUE, target file opened */
1728  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1729  ok( res != 0, "failed to create temp file\n" );
1730  DeleteFileW( oldpath );
1731  success = CreateDirectoryW( oldpath, NULL );
1732  ok( success != 0, "failed to create temp directory\n" );
1734  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1735 
1736  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1737  ok( res != 0, "failed to create temp file\n" );
1738  handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1739  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1740 
1741  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1742  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1743  fri->Replace = TRUE;
1744  fri->RootDir = NULL;
1745  fri->FileNameLength = name_str.Length;
1746  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1747  pRtlFreeUnicodeString( &name_str );
1748 
1749  U(io).Status = 0xdeadbeef;
1750  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1751  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1752  ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
1754  ok( !fileDeleted, "file should exist\n" );
1756  ok( !fileDeleted, "file should exist\n" );
1757 
1758  CloseHandle( handle );
1759  CloseHandle( handle2 );
1760  HeapFree( GetProcessHeap(), 0, fri );
1761  delete_object( oldpath );
1762  delete_object( newpath );
1763 
1764  /* oldpath is a directory, newpath is a directory, Replace = FALSE */
1765  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1766  ok( res != 0, "failed to create temp file\n" );
1767  DeleteFileW( oldpath );
1768  success = CreateDirectoryW( oldpath, NULL );
1769  ok( success != 0, "failed to create temp directory\n" );
1771  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1772 
1773  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1774  ok( res != 0, "failed to create temp file\n" );
1775  DeleteFileW( newpath );
1776  success = CreateDirectoryW( newpath, NULL );
1777  ok( success != 0, "failed to create temp directory\n" );
1778  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1779  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1780  fri->Replace = FALSE;
1781  fri->RootDir = NULL;
1782  fri->FileNameLength = name_str.Length;
1783  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1784  pRtlFreeUnicodeString( &name_str );
1785 
1786  U(io).Status = 0xdeadbeef;
1787  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1788  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1789  ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
1791  ok( !fileDeleted, "file should exist\n" );
1793  ok( !fileDeleted, "file should exist\n" );
1794 
1795  CloseHandle( handle );
1796  HeapFree( GetProcessHeap(), 0, fri );
1797  delete_object( oldpath );
1798  delete_object( newpath );
1799 
1800  /* oldpath is a directory, newpath is a directory, Replace = TRUE */
1801  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1802  ok( res != 0, "failed to create temp file\n" );
1803  DeleteFileW( oldpath );
1804  success = CreateDirectoryW( oldpath, NULL );
1805  ok( success != 0, "failed to create temp directory\n" );
1807  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1808 
1809  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1810  ok( res != 0, "failed to create temp file\n" );
1811  DeleteFileW( newpath );
1812  success = CreateDirectoryW( newpath, NULL );
1813  ok( success != 0, "failed to create temp directory\n" );
1814  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1815  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1816  fri->Replace = TRUE;
1817  fri->RootDir = NULL;
1818  fri->FileNameLength = name_str.Length;
1819  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1820  pRtlFreeUnicodeString( &name_str );
1821 
1822  U(io).Status = 0xdeadbeef;
1823  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1824  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1825  ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
1827  ok( !fileDeleted, "file should exist\n" );
1829  ok( !fileDeleted, "file should exist\n" );
1830 
1831  CloseHandle( handle );
1832  HeapFree( GetProcessHeap(), 0, fri );
1833  delete_object( oldpath );
1834  delete_object( newpath );
1835 
1836  /* oldpath is a directory, newpath is a directory, Replace = TRUE, target file opened */
1837  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1838  ok( res != 0, "failed to create temp file\n" );
1839  DeleteFileW( oldpath );
1840  success = CreateDirectoryW( oldpath, NULL );
1841  ok( success != 0, "failed to create temp directory\n" );
1843  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1844 
1845  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1846  ok( res != 0, "failed to create temp file\n" );
1847  DeleteFileW( newpath );
1848  success = CreateDirectoryW( newpath, NULL );
1849  ok( success != 0, "failed to create temp directory\n" );
1851  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1852 
1853  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1854  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1855  fri->Replace = TRUE;
1856  fri->RootDir = NULL;
1857  fri->FileNameLength = name_str.Length;
1858  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1859  pRtlFreeUnicodeString( &name_str );
1860 
1861  U(io).Status = 0xdeadbeef;
1862  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1863  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1864  ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
1866  ok( !fileDeleted, "file should exist\n" );
1868  ok( !fileDeleted, "file should exist\n" );
1869 
1870  CloseHandle( handle );
1871  CloseHandle( handle2 );
1872  HeapFree( GetProcessHeap(), 0, fri );
1873  delete_object( oldpath );
1874  delete_object( newpath );
1875 
1876  /* oldpath is a file, newpath is a directory, Replace = FALSE */
1877  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1878  ok( res != 0, "failed to create temp file\n" );
1879  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1880  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1881 
1882  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1883  ok( res != 0, "failed to create temp file\n" );
1884  DeleteFileW( newpath );
1885  success = CreateDirectoryW( newpath, NULL );
1886  ok( success != 0, "failed to create temp directory\n" );
1887  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1888  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1889  fri->Replace = FALSE;
1890  fri->RootDir = NULL;
1891  fri->FileNameLength = name_str.Length;
1892  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1893  pRtlFreeUnicodeString( &name_str );
1894 
1895  U(io).Status = 0xdeadbeef;
1896  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1897  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1898  ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
1900  ok( !fileDeleted, "file should exist\n" );
1902  ok( !fileDeleted, "file should exist\n" );
1903 
1904  CloseHandle( handle );
1905  HeapFree( GetProcessHeap(), 0, fri );
1906  delete_object( oldpath );
1907  delete_object( newpath );
1908 
1909  /* oldpath is a file, newpath is a directory, Replace = TRUE */
1910  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1911  ok( res != 0, "failed to create temp file\n" );
1912  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1913  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1914 
1915  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1916  ok( res != 0, "failed to create temp file\n" );
1917  DeleteFileW( newpath );
1918  success = CreateDirectoryW( newpath, NULL );
1919  ok( success != 0, "failed to create temp directory\n" );
1920  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1921  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1922  fri->Replace = TRUE;
1923  fri->RootDir = NULL;
1924  fri->FileNameLength = name_str.Length;
1925  memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1926  pRtlFreeUnicodeString( &name_str );
1927 
1928  U(io).Status = 0xdeadbeef;
1929  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1930  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
1931  ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
1933  ok( !fileDeleted, "file should exist\n" );
1935  ok( !fileDeleted, "file should exist\n" );
1936 
1937  CloseHandle( handle );
1938  HeapFree( GetProcessHeap(), 0, fri );
1939  delete_object( oldpath );
1940  delete_object( newpath );
1941 
1942  /* oldpath is a file, newpath doesn't exist, test with RootDir != NULL */
1943  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1944  ok( res != 0, "failed to create temp file\n" );
1945  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1946  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1947 
1948  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1949  ok( res != 0, "failed to create temp file\n" );
1950  DeleteFileW( newpath );
1951  for (filename = newpath, p = newpath; *p; p++)
1952  if (*p == '\\') filename = p + 1;
1953  handle2 = CreateFileW( tmp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1954  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1955 
1956  fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + lstrlenW(filename) * sizeof(WCHAR) );
1957  fri->Replace = FALSE;
1958  fri->RootDir = handle2;
1959  fri->FileNameLength = lstrlenW(filename) * sizeof(WCHAR);
1960  memcpy( fri->FileName, filename, fri->FileNameLength );
1961 
1962  U(io).Status = 0xdeadbeef;
1963  res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformation );
1964  ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
1965  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
1967  ok( fileDeleted, "file should not exist\n" );
1969  ok( !fileDeleted, "file should exist\n" );
1970 
1971  fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
1972  res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
1973  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
1974  fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
1975  ok( !lstrcmpiW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n",
1976  wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) );
1977  HeapFree( GetProcessHeap(), 0, fni );
1978 
1979  CloseHandle( handle );
1980  CloseHandle( handle2 );
1981  HeapFree( GetProcessHeap(), 0, fri );
1982  delete_object( oldpath );
1983  delete_object( newpath );
1984 }
1985 
1987 {
1988  static const WCHAR foo_txtW[] = {'\\','f','o','o','.','t','x','t',0};
1989  static const WCHAR fooW[] = {'f','o','o',0};
1990  WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16], *filename, *p;
1991  FILE_LINK_INFORMATION *fli;
1992  FILE_NAME_INFORMATION *fni;
1993  BOOL success, fileDeleted;
1994  UNICODE_STRING name_str;
1995  HANDLE handle, handle2;
1997  NTSTATUS res;
1998 
1999  GetTempPathW( MAX_PATH, tmp_path );
2000 
2001  /* oldpath is a file, newpath doesn't exist */
2002  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2003  ok( res != 0, "failed to create temp file\n" );
2004  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2005  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2006 
2007  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2008  ok( res != 0, "failed to create temp file\n" );
2009  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2010  DeleteFileW( newpath );
2011  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2012  fli->ReplaceIfExists = FALSE;
2013  fli->RootDirectory = NULL;
2014  fli->FileNameLength = name_str.Length;
2015  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2016  pRtlFreeUnicodeString( &name_str );
2017 
2018  U(io).Status = 0xdeadbeef;
2019  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2020  ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
2021  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
2023  ok( !fileDeleted, "file should exist\n" );
2025  ok( !fileDeleted, "file should exist\n" );
2026 
2027  fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
2028  res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
2029  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
2030  fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
2031  ok( !lstrcmpiW(fni->FileName, oldpath + 2), "FileName expected %s, got %s\n",
2032  wine_dbgstr_w(oldpath + 2), wine_dbgstr_w(fni->FileName) );
2033  HeapFree( GetProcessHeap(), 0, fni );
2034 
2035  CloseHandle( handle );
2036  HeapFree( GetProcessHeap(), 0, fli );
2037  delete_object( oldpath );
2038  delete_object( newpath );
2039 
2040  /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE */
2041  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2042  ok( res != 0, "failed to create temp file\n" );
2043  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2044  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2045 
2046  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2047  ok( res != 0, "failed to create temp file\n" );
2048  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2049  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2050  fli->ReplaceIfExists = FALSE;
2051  fli->RootDirectory = NULL;
2052  fli->FileNameLength = name_str.Length;
2053  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2054  pRtlFreeUnicodeString( &name_str );
2055 
2056  U(io).Status = 0xdeadbeef;
2057  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2058  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2059  ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
2061  ok( !fileDeleted, "file should exist\n" );
2063  ok( !fileDeleted, "file should exist\n" );
2064 
2065  CloseHandle( handle );
2066  HeapFree( GetProcessHeap(), 0, fli );
2067  delete_object( oldpath );
2068  delete_object( newpath );
2069 
2070  /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE */
2071  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2072  ok( res != 0, "failed to create temp file\n" );
2073  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2074  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2075 
2076  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2077  ok( res != 0, "failed to create temp file\n" );
2078  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2079  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2080  fli->ReplaceIfExists = TRUE;
2081  fli->RootDirectory = NULL;
2082  fli->FileNameLength = name_str.Length;
2083  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2084  pRtlFreeUnicodeString( &name_str );
2085 
2086  U(io).Status = 0xdeadbeef;
2087  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2088  ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
2089  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
2091  ok( !fileDeleted, "file should exist\n" );
2093  ok( !fileDeleted, "file should exist\n" );
2094 
2095  CloseHandle( handle );
2096  HeapFree( GetProcessHeap(), 0, fli );
2097  delete_object( oldpath );
2098  delete_object( newpath );
2099 
2100  /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2101  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2102  ok( res != 0, "failed to create temp file\n" );
2103  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2104  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2105 
2106  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2107  ok( res != 0, "failed to create temp file\n" );
2108  handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2109  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2110 
2111  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2112  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2113  fli->ReplaceIfExists = FALSE;
2114  fli->RootDirectory = NULL;
2115  fli->FileNameLength = name_str.Length;
2116  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2117  pRtlFreeUnicodeString( &name_str );
2118 
2119  U(io).Status = 0xdeadbeef;
2120  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2121  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2122  ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
2124  ok( !fileDeleted, "file should exist\n" );
2126  ok( !fileDeleted, "file should exist\n" );
2127 
2128  CloseHandle( handle );
2129  CloseHandle( handle2 );
2130  HeapFree( GetProcessHeap(), 0, fli );
2131  delete_object( oldpath );
2132  delete_object( newpath );
2133 
2134  /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2135  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2136  ok( res != 0, "failed to create temp file\n" );
2137  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2138  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2139 
2140  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2141  ok( res != 0, "failed to create temp file\n" );
2142  handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2143  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2144 
2145  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2146  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2147  fli->ReplaceIfExists = TRUE;
2148  fli->RootDirectory = NULL;
2149  fli->FileNameLength = name_str.Length;
2150  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2151  pRtlFreeUnicodeString( &name_str );
2152 
2153  U(io).Status = 0xdeadbeef;
2154  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2155  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2156  ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
2158  ok( !fileDeleted, "file should exist\n" );
2160  ok( !fileDeleted, "file should exist\n" );
2161 
2162  CloseHandle( handle );
2163  CloseHandle( handle2 );
2164  HeapFree( GetProcessHeap(), 0, fli );
2165  delete_object( oldpath );
2166  delete_object( newpath );
2167 
2168  /* oldpath is a directory, newpath doesn't exist, ReplaceIfExists = FALSE */
2169  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2170  ok( res != 0, "failed to create temp file\n" );
2171  DeleteFileW( oldpath );
2172  success = CreateDirectoryW( oldpath, NULL );
2173  ok( success != 0, "failed to create temp directory\n" );
2175  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2176 
2177  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2178  ok( res != 0, "failed to create temp file\n" );
2179  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2180  DeleteFileW( newpath );
2181  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2182  fli->ReplaceIfExists = FALSE;
2183  fli->RootDirectory = NULL;
2184  fli->FileNameLength = name_str.Length;
2185  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2186  pRtlFreeUnicodeString( &name_str );
2187 
2188  U(io).Status = 0xdeadbeef;
2189  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2190  todo_wine ok( U(io).Status == 0xdeadbeef , "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2191  ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
2193  ok( !fileDeleted, "file should exist\n" );
2195  ok( fileDeleted, "file should not exist\n" );
2196 
2197  fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
2198  res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
2199  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
2200  fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
2201  ok( !lstrcmpiW(fni->FileName, oldpath + 2), "FileName expected %s, got %s\n",
2202  wine_dbgstr_w(oldpath + 2), wine_dbgstr_w(fni->FileName) );
2203  HeapFree( GetProcessHeap(), 0, fni );
2204 
2205  CloseHandle( handle );
2206  HeapFree( GetProcessHeap(), 0, fli );
2207  delete_object( oldpath );
2208  delete_object( newpath );
2209 
2210  /* oldpath is a directory (but child object opened), newpath doesn't exist, ReplaceIfExists = FALSE */
2211  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2212  ok( res != 0, "failed to create temp file\n" );
2213  DeleteFileW( oldpath );
2214  success = CreateDirectoryW( oldpath, NULL );
2215  ok( success != 0, "failed to create temp directory\n" );
2217  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2218 
2219  lstrcpyW( newpath, oldpath );
2220  lstrcatW( newpath, foo_txtW );
2222  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2223 
2224  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2225  ok( res != 0, "failed to create temp file\n" );
2226  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2227  DeleteFileW( newpath );
2228  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2229  fli->ReplaceIfExists = FALSE;
2230  fli->RootDirectory = NULL;
2231  fli->FileNameLength = name_str.Length;
2232  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2233  pRtlFreeUnicodeString( &name_str );
2234 
2235  U(io).Status = 0xdeadbeef;
2236  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2237  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2238  ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
2240  ok( !fileDeleted, "file should exist\n" );
2242  ok( fileDeleted, "file should not exist\n" );
2243 
2244  CloseHandle( handle );
2245  CloseHandle( handle2 );
2246  HeapFree( GetProcessHeap(), 0, fli );
2247  delete_object( oldpath );
2248  delete_object( newpath );
2249 
2250  /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE */
2251  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2252  ok( res != 0, "failed to create temp file\n" );
2253  DeleteFileW( oldpath );
2254  success = CreateDirectoryW( oldpath, NULL );
2255  ok( success != 0, "failed to create temp directory\n" );
2257  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2258 
2259  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2260  ok( res != 0, "failed to create temp file\n" );
2261  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2262  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2263  fli->ReplaceIfExists = FALSE;
2264  fli->RootDirectory = NULL;
2265  fli->FileNameLength = name_str.Length;
2266  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2267  pRtlFreeUnicodeString( &name_str );
2268 
2269  U(io).Status = 0xdeadbeef;
2270  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2271  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2273  "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
2275  ok( !fileDeleted, "file should exist\n" );
2277  ok( !fileDeleted, "file should exist\n" );
2278 
2279  CloseHandle( handle );
2280  HeapFree( GetProcessHeap(), 0, fli );
2281  delete_object( oldpath );
2282  delete_object( newpath );
2283 
2284  /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2285  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2286  ok( res != 0, "failed to create temp file\n" );
2287  DeleteFileW( oldpath );
2288  success = CreateDirectoryW( oldpath, NULL );
2289  ok( success != 0, "failed to create temp directory\n" );
2291  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2292 
2293  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2294  ok( res != 0, "failed to create temp file\n" );
2295  handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2296  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2297 
2298  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2299  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2300  fli->ReplaceIfExists = FALSE;
2301  fli->RootDirectory = NULL;
2302  fli->FileNameLength = name_str.Length;
2303  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2304  pRtlFreeUnicodeString( &name_str );
2305 
2306  U(io).Status = 0xdeadbeef;
2307  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2308  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2310  "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
2312  ok( !fileDeleted, "file should exist\n" );
2314  ok( !fileDeleted, "file should exist\n" );
2315 
2316  CloseHandle( handle );
2317  CloseHandle( handle2 );
2318  HeapFree( GetProcessHeap(), 0, fli );
2319  delete_object( oldpath );
2320  delete_object( newpath );
2321 
2322  /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE */
2323  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2324  ok( res != 0, "failed to create temp file\n" );
2325  DeleteFileW( oldpath );
2326  success = CreateDirectoryW( oldpath, NULL );
2327  ok( success != 0, "failed to create temp directory\n" );
2329  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2330 
2331  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2332  ok( res != 0, "failed to create temp file\n" );
2333  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2334  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2335  fli->ReplaceIfExists = TRUE;
2336  fli->RootDirectory = NULL;
2337  fli->FileNameLength = name_str.Length;
2338  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2339  pRtlFreeUnicodeString( &name_str );
2340 
2341  U(io).Status = 0xdeadbeef;
2342  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2343  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2344  ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
2346  ok( !fileDeleted, "file should exist\n" );
2348  ok( !fileDeleted, "file should exist\n" );
2349 
2350  CloseHandle( handle );
2351  HeapFree( GetProcessHeap(), 0, fli );
2352  delete_object( oldpath );
2353  delete_object( newpath );
2354 
2355  /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2356  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2357  ok( res != 0, "failed to create temp file\n" );
2358  DeleteFileW( oldpath );
2359  success = CreateDirectoryW( oldpath, NULL );
2360  ok( success != 0, "failed to create temp directory\n" );
2362  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2363 
2364  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2365  ok( res != 0, "failed to create temp file\n" );
2366  handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2367  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2368 
2369  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2370  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2371  fli->ReplaceIfExists = TRUE;
2372  fli->RootDirectory = NULL;
2373  fli->FileNameLength = name_str.Length;
2374  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2375  pRtlFreeUnicodeString( &name_str );
2376 
2377  U(io).Status = 0xdeadbeef;
2378  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2379  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2380  ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
2382  ok( !fileDeleted, "file should exist\n" );
2384  ok( !fileDeleted, "file should exist\n" );
2385 
2386  CloseHandle( handle );
2387  CloseHandle( handle2 );
2388  HeapFree( GetProcessHeap(), 0, fli );
2389  delete_object( oldpath );
2390  delete_object( newpath );
2391 
2392  /* oldpath is a directory, newpath is a directory, ReplaceIfExists = FALSE */
2393  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2394  ok( res != 0, "failed to create temp file\n" );
2395  DeleteFileW( oldpath );
2396  success = CreateDirectoryW( oldpath, NULL );
2397  ok( success != 0, "failed to create temp directory\n" );
2399  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2400 
2401  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2402  ok( res != 0, "failed to create temp file\n" );
2403  DeleteFileW( newpath );
2404  success = CreateDirectoryW( newpath, NULL );
2405  ok( success != 0, "failed to create temp directory\n" );
2406  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2407  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2408  fli->ReplaceIfExists = FALSE;
2409  fli->RootDirectory = NULL;
2410  fli->FileNameLength = name_str.Length;
2411  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2412  pRtlFreeUnicodeString( &name_str );
2413 
2414  U(io).Status = 0xdeadbeef;
2415  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2416  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2418  "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
2420  ok( !fileDeleted, "file should exist\n" );
2422  ok( !fileDeleted, "file should exist\n" );
2423 
2424  CloseHandle( handle );
2425  HeapFree( GetProcessHeap(), 0, fli );
2426  delete_object( oldpath );
2427  delete_object( newpath );
2428 
2429  /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE */
2430  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2431  ok( res != 0, "failed to create temp file\n" );
2432  DeleteFileW( oldpath );
2433  success = CreateDirectoryW( oldpath, NULL );
2434  ok( success != 0, "failed to create temp directory\n" );
2436  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2437 
2438  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2439  ok( res != 0, "failed to create temp file\n" );
2440  DeleteFileW( newpath );
2441  success = CreateDirectoryW( newpath, NULL );
2442  ok( success != 0, "failed to create temp directory\n" );
2443  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2444  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2445  fli->ReplaceIfExists = TRUE;
2446  fli->RootDirectory = NULL;
2447  fli->FileNameLength = name_str.Length;
2448  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2449  pRtlFreeUnicodeString( &name_str );
2450 
2451  U(io).Status = 0xdeadbeef;
2452  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2453  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2454  ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
2456  ok( !fileDeleted, "file should exist\n" );
2458  ok( !fileDeleted, "file should exist\n" );
2459 
2460  CloseHandle( handle );
2461  HeapFree( GetProcessHeap(), 0, fli );
2462  delete_object( oldpath );
2463  delete_object( newpath );
2464 
2465  /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE, target file opened */
2466  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2467  ok( res != 0, "failed to create temp file\n" );
2468  DeleteFileW( oldpath );
2469  success = CreateDirectoryW( oldpath, NULL );
2470  ok( success != 0, "failed to create temp directory\n" );
2472  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2473 
2474  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2475  ok( res != 0, "failed to create temp file\n" );
2476  DeleteFileW( newpath );
2477  success = CreateDirectoryW( newpath, NULL );
2478  ok( success != 0, "failed to create temp directory\n" );
2480  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2481 
2482  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2483  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2484  fli->ReplaceIfExists = TRUE;
2485  fli->RootDirectory = NULL;
2486  fli->FileNameLength = name_str.Length;
2487  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2488  pRtlFreeUnicodeString( &name_str );
2489 
2490  U(io).Status = 0xdeadbeef;
2491  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2492  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2493  ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
2495  ok( !fileDeleted, "file should exist\n" );
2497  ok( !fileDeleted, "file should exist\n" );
2498 
2499  CloseHandle( handle );
2500  CloseHandle( handle2 );
2501  HeapFree( GetProcessHeap(), 0, fli );
2502  delete_object( oldpath );
2503  delete_object( newpath );
2504 
2505  /* oldpath is a file, newpath is a directory, ReplaceIfExists = FALSE */
2506  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2507  ok( res != 0, "failed to create temp file\n" );
2508  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2509  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2510 
2511  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2512  ok( res != 0, "failed to create temp file\n" );
2513  DeleteFileW( newpath );
2514  success = CreateDirectoryW( newpath, NULL );
2515  ok( success != 0, "failed to create temp directory\n" );
2516  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2517  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2518  fli->ReplaceIfExists = FALSE;
2519  fli->RootDirectory = NULL;
2520  fli->FileNameLength = name_str.Length;
2521  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2522  pRtlFreeUnicodeString( &name_str );
2523 
2524  U(io).Status = 0xdeadbeef;
2525  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2526  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2527  ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
2529  ok( !fileDeleted, "file should exist\n" );
2531  ok( !fileDeleted, "file should exist\n" );
2532 
2533  CloseHandle( handle );
2534  HeapFree( GetProcessHeap(), 0, fli );
2535  delete_object( oldpath );
2536  delete_object( newpath );
2537 
2538  /* oldpath is a file, newpath is a directory, ReplaceIfExists = TRUE */
2539  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2540  ok( res != 0, "failed to create temp file\n" );
2541  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2542  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2543 
2544  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2545  ok( res != 0, "failed to create temp file\n" );
2546  DeleteFileW( newpath );
2547  success = CreateDirectoryW( newpath, NULL );
2548  ok( success != 0, "failed to create temp directory\n" );
2549  pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2550  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2551  fli->ReplaceIfExists = TRUE;
2552  fli->RootDirectory = NULL;
2553  fli->FileNameLength = name_str.Length;
2554  memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2555  pRtlFreeUnicodeString( &name_str );
2556 
2557  U(io).Status = 0xdeadbeef;
2558  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2559  todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
2560  ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
2562  ok( !fileDeleted, "file should exist\n" );
2564  ok( !fileDeleted, "file should exist\n" );
2565 
2566  CloseHandle( handle );
2567  HeapFree( GetProcessHeap(), 0, fli );
2568  delete_object( oldpath );
2569  delete_object( newpath );
2570 
2571  /* oldpath is a file, newpath doesn't exist, test with RootDirectory != NULL */
2572  res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2573  ok( res != 0, "failed to create temp file\n" );
2574  handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2575  ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2576 
2577  res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2578  ok( res != 0, "failed to create temp file\n" );
2579  DeleteFileW( newpath );
2580  for (filename = newpath, p = newpath; *p; p++)
2581  if (*p == '\\') filename = p + 1;
2582  handle2 = CreateFileW( tmp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2583  ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2584 
2585  fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + lstrlenW(filename) * sizeof(WCHAR) );
2586  fli->ReplaceIfExists = FALSE;
2587  fli->RootDirectory = handle2;
2588  fli->FileNameLength = lstrlenW(filename) * sizeof(WCHAR);
2589  memcpy( fli->FileName, filename, fli->FileNameLength );
2590 
2591  U(io).Status = 0xdeadbeef;
2592  res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
2593  ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
2594  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
2596  ok( !fileDeleted, "file should exist\n" );
2598  ok( !fileDeleted, "file should exist\n" );
2599 
2600  fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
2601  res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
2602  ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
2603  fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
2604  ok( !lstrcmpiW(fni->FileName, oldpath + 2), "FileName expected %s, got %s\n",
2605  wine_dbgstr_w(oldpath + 2), wine_dbgstr_w(fni->FileName) );
2606  HeapFree( GetProcessHeap(), 0, fni );
2607 
2608  CloseHandle( handle );
2609  CloseHandle( handle2 );
2610  HeapFree( GetProcessHeap(), 0, fli );
2611  delete_object( oldpath );
2612  delete_object( newpath );
2613 }
2614 
2616 {
2619  HANDLE h;
2620  int res;
2621 
2622  if (!(h = create_temp_file(0))) return;
2623 
2624  memset(&fbi, 0, sizeof(fbi));
2625  res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBothDirectoryInformation);
2626  ok ( res == STATUS_INVALID_INFO_CLASS || res == STATUS_NOT_IMPLEMENTED, "shouldn't be able to query FileBothDirectoryInformation, res %x\n", res);
2627 
2628  CloseHandle( h );
2629 }
2630 
2632 {
2633  char tmp_path[MAX_PATH], buffer[MAX_PATH + 16];
2634  DWORD dirpos;
2635  HANDLE handle, handle2, mapping;
2636  NTSTATUS res;
2639  BOOL fileDeleted;
2640  DWORD fdi2;
2641  void *ptr;
2642 
2643  GetTempPathA( MAX_PATH, tmp_path );
2644 
2645  /* tests for info struct size */
2646  GetTempFileNameA( tmp_path, "dis", 0, buffer );
2648  ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
2649  res = pNtSetInformationFile( handle, &io, &fdi, 0, FileDispositionInformation );
2650  todo_wine
2651  ok( res == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %x\n", res );
2652  fdi2 = 0x100;
2653  res = pNtSetInformationFile( handle, &io, &fdi2, sizeof(fdi2), FileDispositionInformation );
2654  ok( res == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %x\n", res );
2655  CloseHandle( handle );
2657  ok( !fileDeleted, "File shouldn't have been deleted\n" );
2658  DeleteFileA( buffer );
2659 
2660  /* cannot set disposition on file not opened with delete access */
2661  GetTempFileNameA( tmp_path, "dis", 0, buffer );
2663  ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
2664  res = pNtQueryInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
2665  ok( res == STATUS_INVALID_INFO_CLASS || res == STATUS_NOT_IMPLEMENTED, "Unexpected NtQueryInformationFile result (expected STATUS_INVALID_INFO_CLASS, got %x)\n", res );
2666  fdi.DoDeleteFile = TRUE;
2667  res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
2668  ok( res == STATUS_ACCESS_DENIED, "unexpected FileDispositionInformation result (expected STATUS_ACCESS_DENIED, got %x)\n", res );
2669  CloseHandle( handle );
2671  ok( !fileDeleted, "File shouldn't have been deleted\n" );
2672  DeleteFileA( buffer );
2673 
2674  /* can set disposition on file opened with proper access */
2675  GetTempFileNameA( tmp_path, "dis", 0, buffer );
2677  ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
2678  fdi.DoDeleteFile = TRUE;
2679  res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
2680  ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res );
2681  CloseHandle( handle );
2683  ok( fileDeleted, "File should have been deleted\n" );
2684  DeleteFileA( buffer );
2685 
2686  /* cannot set disposition on readonly file */
2687  GetTempFileNameA( tmp_path, "dis", 0, buffer );
2688  DeleteFileA( buffer );
2690  ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
2691  fdi.DoDeleteFile = TRUE;
2692  res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
2693  ok( res == STATUS_CANNOT_DELETE, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res );
2694  CloseHandle( handle );
2696  ok( !fileDeleted, "File shouldn't have been deleted\n" );
2698  DeleteFileA( buffer );
2699 
2700  /* cannot set disposition on readonly file */
2701  GetTempFileNameA( tmp_path, "dis", 0, buffer );
2703  ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
2704  fdi.DoDeleteFile = TRUE;
2705  res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
2706  todo_wine
2707  ok( res == STATUS_CANNOT_DELETE, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res );
2708  CloseHandle(