directory.c (c2c66aff) | directory.c (f7932ba2) |
---|---|
1/* Unit test suite for Ntdll directory functions 2 * 3 * Copyright 2007 Jeff Latimer 4 * Copyright 2007 Andrey Turkin 5 * Copyright 2008 Jeff Zaroyko 6 * Copyright 2009 Dan Kegel 7 * 8 * This library is free software; you can redistribute it and/or --- 20 unchanged lines hidden (view full) --- 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" | 1/* Unit test suite for Ntdll directory functions 2 * 3 * Copyright 2007 Jeff Latimer 4 * Copyright 2007 Andrey Turkin 5 * Copyright 2008 Jeff Zaroyko 6 * Copyright 2009 Dan Kegel 7 * 8 * This library is free software; you can redistribute it and/or --- 20 unchanged lines hidden (view full) --- 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 "winnls.h" |
|
37#include "wine/winternl.h" 38 39static NTSTATUS (WINAPI *pNtClose)( PHANDLE ); 40static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG ); 41static NTSTATUS (WINAPI *pNtQueryDirectoryFile)(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK, 42 PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN); | 38#include "wine/winternl.h" 39 40static NTSTATUS (WINAPI *pNtClose)( PHANDLE ); 41static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG ); 42static NTSTATUS (WINAPI *pNtQueryDirectoryFile)(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK, 43 PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN); |
44static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE,PIO_STATUS_BLOCK,PVOID,LONG,FILE_INFORMATION_CLASS); 45static NTSTATUS (WINAPI *pNtSetInformationFile)(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FILE_INFORMATION_CLASS); |
|
43static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING,LPCSTR); 44static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* ); 45static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR ); 46static VOID (WINAPI *pRtlFreeUnicodeString)( PUNICODE_STRING ); | 46static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING,LPCSTR); 47static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* ); 48static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR ); 49static VOID (WINAPI *pRtlFreeUnicodeString)( PUNICODE_STRING ); |
50static LONG (WINAPI *pRtlCompareUnicodeString)( const UNICODE_STRING*, const UNICODE_STRING*,BOOLEAN ); |
|
47static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen, 48 LPCSTR src, DWORD srclen ); 49static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirection)( BOOLEAN enable ); 50static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG disable, ULONG *old_value ); 51 52/* The attribute sets to test */ 53static struct testfile_s { 54 BOOL attr_done; /* set if attributes were tested for this file already */ 55 const DWORD attr; /* desired attribute */ | 51static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen, 52 LPCSTR src, DWORD srclen ); 53static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirection)( BOOLEAN enable ); 54static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG disable, ULONG *old_value ); 55 56/* The attribute sets to test */ 57static struct testfile_s { 58 BOOL attr_done; /* set if attributes were tested for this file already */ 59 const DWORD attr; /* desired attribute */ |
56 const char *name; /* filename to use */ | 60 WCHAR name[20]; /* filename to use */ |
57 const char *target; /* what to point to (only for reparse pts) */ 58 const char *description; /* for error messages */ 59 int nfound; /* How many were found (expect 1) */ | 61 const char *target; /* what to point to (only for reparse pts) */ 62 const char *description; /* for error messages */ 63 int nfound; /* How many were found (expect 1) */ |
60 WCHAR nameW[20]; /* unicode version of name (filled in later) */ | |
61} testfiles[] = { | 64} testfiles[] = { |
62 { 0, FILE_ATTRIBUTE_NORMAL, "n.tmp", NULL, "normal" }, 63 { 0, FILE_ATTRIBUTE_HIDDEN, "h.tmp", NULL, "hidden" }, 64 { 0, FILE_ATTRIBUTE_SYSTEM, "s.tmp", NULL, "system" }, 65 { 0, FILE_ATTRIBUTE_DIRECTORY, "d.tmp", NULL, "directory" }, 66 { 0, FILE_ATTRIBUTE_DIRECTORY, ".", NULL, ". directory" }, 67 { 0, FILE_ATTRIBUTE_DIRECTORY, "..", NULL, ".. directory" }, 68 { 0, 0, NULL } | 65 { 0, FILE_ATTRIBUTE_NORMAL, {'l','o','n','g','f','i','l','e','n','a','m','e','.','t','m','p'}, "normal" }, 66 { 0, FILE_ATTRIBUTE_NORMAL, {'n','.','t','m','p',}, "normal" }, 67 { 0, FILE_ATTRIBUTE_HIDDEN, {'h','.','t','m','p',}, "hidden" }, 68 { 0, FILE_ATTRIBUTE_SYSTEM, {'s','.','t','m','p',}, "system" }, 69 { 0, FILE_ATTRIBUTE_DIRECTORY, {'d','.','t','m','p',}, "directory" }, 70 { 0, FILE_ATTRIBUTE_NORMAL, {0xe9,'a','.','t','m','p'}, "normal" }, 71 { 0, FILE_ATTRIBUTE_NORMAL, {0xc9,'b','.','t','m','p'}, "normal" }, 72 { 0, FILE_ATTRIBUTE_NORMAL, {'e','a','.','t','m','p'}, "normal" }, 73 { 0, FILE_ATTRIBUTE_DIRECTORY, {'.'}, ". directory" }, 74 { 0, FILE_ATTRIBUTE_DIRECTORY, {'.','.'}, ".. directory" } |
69}; | 75}; |
70static const int max_test_dir_size = 20; /* size of above plus some for .. etc */ | 76static const int test_dir_count = sizeof(testfiles) / sizeof(testfiles[0]); 77static const int max_test_dir_size = sizeof(testfiles) / sizeof(testfiles[0]) + 5; /* size of above plus some for .. etc */ |
71 | 78 |
79static const WCHAR dummyW[] = {'d','u','m','m','y',0}; 80static const WCHAR dotW[] = {'.',0}; 81static const WCHAR dotdotW[] = {'.','.',0}; 82static const WCHAR backslashW[] = {'\\',0}; 83 |
|
72/* Create a test directory full of attribute test files, clear counts */ | 84/* Create a test directory full of attribute test files, clear counts */ |
73static void set_up_attribute_test(const char *testdirA) | 85static void set_up_attribute_test(const WCHAR *testdir) |
74{ 75 int i; 76 BOOL ret; 77 | 86{ 87 int i; 88 BOOL ret; 89 |
78 ret = CreateDirectoryA(testdirA, NULL); 79 ok(ret, "couldn't create dir '%s', error %d\n", testdirA, GetLastError()); | 90 ret = CreateDirectoryW(testdir, NULL); 91 ok(ret, "couldn't create dir %s, error %d\n", wine_dbgstr_w(testdir), GetLastError()); |
80 | 92 |
81 for (i=0; testfiles[i].name; i++) { 82 char buf[MAX_PATH]; 83 pRtlMultiByteToUnicodeN(testfiles[i].nameW, sizeof(testfiles[i].nameW), NULL, testfiles[i].name, strlen(testfiles[i].name)+1); | 93 for (i=0; i < test_dir_count; i++) { 94 WCHAR buf[MAX_PATH]; |
84 | 95 |
85 if (strcmp(testfiles[i].name, ".") == 0 || strcmp(testfiles[i].name, "..") == 0) | 96 if (lstrcmpW(testfiles[i].name, dotW) == 0 || lstrcmpW(testfiles[i].name, dotdotW) == 0) |
86 continue; | 97 continue; |
87 sprintf(buf, "%s\\%s", testdirA, testfiles[i].name); | 98 lstrcpyW( buf, testdir ); 99 lstrcatW( buf, backslashW ); 100 lstrcatW( buf, testfiles[i].name ); |
88 if (testfiles[i].attr & FILE_ATTRIBUTE_DIRECTORY) { | 101 if (testfiles[i].attr & FILE_ATTRIBUTE_DIRECTORY) { |
89 ret = CreateDirectoryA(buf, NULL); 90 ok(ret, "couldn't create dir '%s', error %d\n", buf, GetLastError()); | 102 ret = CreateDirectoryW(buf, NULL); 103 ok(ret, "couldn't create dir %s, error %d\n", wine_dbgstr_w(buf), GetLastError()); |
91 } else { | 104 } else { |
92 HANDLE h = CreateFileA(buf, | 105 HANDLE h = CreateFileW(buf, |
93 GENERIC_READ|GENERIC_WRITE, 94 0, NULL, CREATE_ALWAYS, 95 testfiles[i].attr, 0); | 106 GENERIC_READ|GENERIC_WRITE, 107 0, NULL, CREATE_ALWAYS, 108 testfiles[i].attr, 0); |
96 ok( h != INVALID_HANDLE_VALUE, "failed to create temp file '%s'\n", buf ); | 109 ok( h != INVALID_HANDLE_VALUE, "failed to create temp file %s\n", wine_dbgstr_w(buf) ); |
97 CloseHandle(h); 98 } 99 } 100} 101 102static void reset_found_files(void) 103{ 104 int i; 105 | 110 CloseHandle(h); 111 } 112 } 113} 114 115static void reset_found_files(void) 116{ 117 int i; 118 |
106 for (i = 0; testfiles[i].name; i++) | 119 for (i = 0; i < test_dir_count; i++) |
107 testfiles[i].nfound = 0; 108} 109 110/* Remove the given test directory and the attribute test files, if any */ | 120 testfiles[i].nfound = 0; 121} 122 123/* Remove the given test directory and the attribute test files, if any */ |
111static void tear_down_attribute_test(const char *testdirA) | 124static void tear_down_attribute_test(const WCHAR *testdir) |
112{ 113 int i; 114 | 125{ 126 int i; 127 |
115 for (i=0; testfiles[i].name; i++) { | 128 for (i = 0; i < test_dir_count; i++) { |
116 int ret; | 129 int ret; |
117 char buf[MAX_PATH]; 118 if (strcmp(testfiles[i].name, ".") == 0 || strcmp(testfiles[i].name, "..") == 0) | 130 WCHAR buf[MAX_PATH]; 131 if (lstrcmpW(testfiles[i].name, dotW) == 0 || lstrcmpW(testfiles[i].name, dotdotW) == 0) |
119 continue; | 132 continue; |
120 sprintf(buf, "%s\\%s", testdirA, testfiles[i].name); | 133 lstrcpyW( buf, testdir ); 134 lstrcatW( buf, backslashW ); 135 lstrcatW( buf, testfiles[i].name ); |
121 if (testfiles[i].attr & FILE_ATTRIBUTE_DIRECTORY) { | 136 if (testfiles[i].attr & FILE_ATTRIBUTE_DIRECTORY) { |
122 ret = RemoveDirectoryA(buf); | 137 ret = RemoveDirectoryW(buf); |
123 ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND), | 138 ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND), |
124 "Failed to rmdir %s, error %d\n", buf, GetLastError()); | 139 "Failed to rmdir %s, error %d\n", wine_dbgstr_w(buf), GetLastError()); |
125 } else { | 140 } else { |
126 ret = DeleteFileA(buf); | 141 ret = DeleteFileW(buf); |
127 ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND), | 142 ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND), |
128 "Failed to rm %s, error %d\n", buf, GetLastError()); | 143 "Failed to rm %s, error %d\n", wine_dbgstr_w(buf), GetLastError()); |
129 } 130 } | 144 } 145 } |
131 RemoveDirectoryA(testdirA); | 146 RemoveDirectoryW(testdir); |
132} 133 134/* Match one found file against testfiles[], increment count if found */ 135static void tally_test_file(FILE_BOTH_DIRECTORY_INFORMATION *dir_info) 136{ 137 int i; 138 DWORD attribmask = 139 (FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT); 140 DWORD attrib = dir_info->FileAttributes & attribmask; 141 WCHAR *nameW = dir_info->FileName; 142 int namelen = dir_info->FileNameLength / sizeof(WCHAR); 143 | 147} 148 149/* Match one found file against testfiles[], increment count if found */ 150static void tally_test_file(FILE_BOTH_DIRECTORY_INFORMATION *dir_info) 151{ 152 int i; 153 DWORD attribmask = 154 (FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT); 155 DWORD attrib = dir_info->FileAttributes & attribmask; 156 WCHAR *nameW = dir_info->FileName; 157 int namelen = dir_info->FileNameLength / sizeof(WCHAR); 158 |
144 for (i=0; testfiles[i].name; i++) { 145 int len = strlen(testfiles[i].name); 146 if (namelen != len || memcmp(nameW, testfiles[i].nameW, len*sizeof(WCHAR))) | 159 for (i = 0; i < test_dir_count; i++) { 160 int len = lstrlenW(testfiles[i].name); 161 if (namelen != len || memcmp(nameW, testfiles[i].name, len*sizeof(WCHAR))) |
147 continue; 148 if (!testfiles[i].attr_done) { | 162 continue; 163 if (!testfiles[i].attr_done) { |
149 ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%x), got %x (is your linux new enough?)\n", testfiles[i].name, testfiles[i].description, testfiles[i].attr, attrib); | 164 ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%x), got %x (is your linux new enough?)\n", wine_dbgstr_w(testfiles[i].name), testfiles[i].description, testfiles[i].attr, attrib); |
150 testfiles[i].attr_done = TRUE; 151 } 152 testfiles[i].nfound++; 153 break; 154 } | 165 testfiles[i].attr_done = TRUE; 166 } 167 testfiles[i].nfound++; 168 break; 169 } |
155 ok(testfiles[i].name != NULL, "unexpected file found\n"); | 170 ok(i < test_dir_count, "unexpected file found %s\n", wine_dbgstr_wn(dir_info->FileName, namelen)); |
156} 157 158static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char *testdirA, 159 UNICODE_STRING *mask, 160 BOOLEAN single_entry, BOOLEAN restart_flag) 161{ | 171} 172 173static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char *testdirA, 174 UNICODE_STRING *mask, 175 BOOLEAN single_entry, BOOLEAN restart_flag) 176{ |
162 HANDLE dirh; | 177 UNICODE_STRING dummy_mask; 178 HANDLE dirh, new_dirh; |
163 IO_STATUS_BLOCK io; 164 UINT data_pos, data_size; 165 UINT data_len; /* length of dir data */ 166 BYTE data[8192]; /* directory data */ 167 FILE_BOTH_DIRECTORY_INFORMATION *dir_info; | 179 IO_STATUS_BLOCK io; 180 UINT data_pos, data_size; 181 UINT data_len; /* length of dir data */ 182 BYTE data[8192]; /* directory data */ 183 FILE_BOTH_DIRECTORY_INFORMATION *dir_info; |
168 DWORD status; | 184 NTSTATUS status; |
169 int numfiles; 170 int i; 171 172 reset_found_files(); | 185 int numfiles; 186 int i; 187 188 reset_found_files(); |
189 pRtlInitUnicodeString( &dummy_mask, dummyW ); |
|
173 174 data_size = mask ? offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[256] ) : sizeof(data); 175 176 /* Read the directory and note which files are found */ 177 status = pNtOpenFile( &dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, attr, &io, FILE_SHARE_READ, 178 FILE_SYNCHRONOUS_IO_NONALERT|FILE_OPEN_FOR_BACKUP_INTENT|FILE_DIRECTORY_FILE); 179 ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%x, error %d\n", testdirA, status, GetLastError()); 180 if (status != STATUS_SUCCESS) { 181 skip("can't test if we can't open the directory\n"); 182 return; 183 } 184 | 190 191 data_size = mask ? offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[256] ) : sizeof(data); 192 193 /* Read the directory and note which files are found */ 194 status = pNtOpenFile( &dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, attr, &io, FILE_SHARE_READ, 195 FILE_SYNCHRONOUS_IO_NONALERT|FILE_OPEN_FOR_BACKUP_INTENT|FILE_DIRECTORY_FILE); 196 ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%x, error %d\n", testdirA, status, GetLastError()); 197 if (status != STATUS_SUCCESS) { 198 skip("can't test if we can't open the directory\n"); 199 return; 200 } 201 |
185 pNtQueryDirectoryFile( dirh, NULL, NULL, NULL, &io, data, data_size, 186 FileBothDirectoryInformation, single_entry, mask, restart_flag ); | 202 U(io).Status = 0xdeadbeef; 203 status = pNtQueryDirectoryFile( dirh, NULL, NULL, NULL, &io, data, data_size, 204 FileBothDirectoryInformation, single_entry, mask, restart_flag ); 205 ok (status == STATUS_SUCCESS, "failed to query directory; status %x\n", status); |
187 ok (U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status); 188 data_len = io.Information; 189 ok (data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n"); 190 | 206 ok (U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status); 207 data_len = io.Information; 208 ok (data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n"); 209 |
210 DuplicateHandle( GetCurrentProcess(), dirh, GetCurrentProcess(), &new_dirh, 211 0, FALSE, DUPLICATE_SAME_ACCESS ); 212 pNtClose(dirh); 213 |
|
191 data_pos = 0; 192 numfiles = 0; 193 while ((data_pos < data_len) && (numfiles < max_test_dir_size)) { 194 dir_info = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + data_pos); 195 196 tally_test_file(dir_info); 197 198 if (dir_info->NextEntryOffset == 0) { | 214 data_pos = 0; 215 numfiles = 0; 216 while ((data_pos < data_len) && (numfiles < max_test_dir_size)) { 217 dir_info = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + data_pos); 218 219 tally_test_file(dir_info); 220 221 if (dir_info->NextEntryOffset == 0) { |
199 pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size, 200 FileBothDirectoryInformation, single_entry, mask, FALSE ); 201 if (U(io).Status == STATUS_NO_MORE_FILES) 202 break; 203 ok (U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status); | 222 U(io).Status = 0xdeadbeef; 223 status = pNtQueryDirectoryFile( new_dirh, 0, NULL, NULL, &io, data, data_size, 224 FileBothDirectoryInformation, single_entry, &dummy_mask, FALSE ); 225 ok (U(io).Status == status, "wrong status %x / %x\n", status, U(io).Status); 226 if (status == STATUS_NO_MORE_FILES) break; 227 ok (status == STATUS_SUCCESS, "failed to query directory; status %x\n", status); |
204 data_len = io.Information; 205 if (data_len < sizeof(FILE_BOTH_DIRECTORY_INFORMATION)) 206 break; 207 data_pos = 0; 208 } else { 209 data_pos += dir_info->NextEntryOffset; 210 } 211 numfiles++; 212 } 213 ok(numfiles < max_test_dir_size, "too many loops\n"); 214 215 if (mask) | 228 data_len = io.Information; 229 if (data_len < sizeof(FILE_BOTH_DIRECTORY_INFORMATION)) 230 break; 231 data_pos = 0; 232 } else { 233 data_pos += dir_info->NextEntryOffset; 234 } 235 numfiles++; 236 } 237 ok(numfiles < max_test_dir_size, "too many loops\n"); 238 239 if (mask) |
216 for (i=0; testfiles[i].name; i++) 217 ok(testfiles[i].nfound == (testfiles[i].nameW == mask->Buffer), | 240 for (i = 0; i < test_dir_count; i++) 241 ok(testfiles[i].nfound == (testfiles[i].name == mask->Buffer), |
218 "Wrong number %d of %s files found (single_entry=%d,mask=%s)\n", 219 testfiles[i].nfound, testfiles[i].description, single_entry, 220 wine_dbgstr_wn(mask->Buffer, mask->Length/sizeof(WCHAR) )); 221 else | 242 "Wrong number %d of %s files found (single_entry=%d,mask=%s)\n", 243 testfiles[i].nfound, testfiles[i].description, single_entry, 244 wine_dbgstr_wn(mask->Buffer, mask->Length/sizeof(WCHAR) )); 245 else |
222 for (i=0; testfiles[i].name; i++) | 246 for (i = 0; i < test_dir_count; i++) |
223 ok(testfiles[i].nfound == 1, "Wrong number %d of %s files found (single_entry=%d,restart=%d)\n", 224 testfiles[i].nfound, testfiles[i].description, single_entry, restart_flag); | 247 ok(testfiles[i].nfound == 1, "Wrong number %d of %s files found (single_entry=%d,restart=%d)\n", 248 testfiles[i].nfound, testfiles[i].description, single_entry, restart_flag); |
225 pNtClose(dirh); | 249 pNtClose(new_dirh); |
226} 227 | 250} 251 |
228static void test_NtQueryDirectoryFile(void) | 252static void test_directory_sort( const WCHAR *testdir ) |
229{ 230 OBJECT_ATTRIBUTES attr; 231 UNICODE_STRING ntdirname; | 253{ 254 OBJECT_ATTRIBUTES attr; 255 UNICODE_STRING ntdirname; |
256 IO_STATUS_BLOCK io; 257 UINT data_pos, data_len, count; 258 BYTE data[8192]; 259 WCHAR prev[MAX_PATH], name[MAX_PATH]; 260 UNICODE_STRING prev_str, name_str; 261 FILE_BOTH_DIRECTORY_INFORMATION *info; 262 NTSTATUS status; 263 HANDLE handle; 264 int res; 265 266 if (!pRtlDosPathNameToNtPathName_U( testdir, &ntdirname, NULL, NULL )) 267 { 268 ok(0, "RtlDosPathNametoNtPathName_U failed\n"); 269 return; 270 } 271 InitializeObjectAttributes( &attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL ); 272 status = pNtOpenFile( &handle, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, 273 FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE ); 274 ok(status == STATUS_SUCCESS, "failed to open dir %s\n", wine_dbgstr_w(testdir) ); 275 276 U(io).Status = 0xdeadbeef; 277 status = pNtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, data, sizeof(data), 278 FileBothDirectoryInformation, FALSE, NULL, TRUE ); 279 ok( status == STATUS_SUCCESS, "failed to query directory; status %x\n", status ); 280 ok( U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status ); 281 data_len = io.Information; 282 ok( data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n" ); 283 data_pos = 0; 284 count = 0; 285 286 while (data_pos < data_len) 287 { 288 info = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + data_pos); 289 290 memcpy( name, info->FileName, info->FileNameLength ); 291 name[info->FileNameLength / sizeof(WCHAR)] = 0; 292 switch (count) 293 { 294 case 0: /* first entry must be '.' */ 295 ok( !lstrcmpW( name, dotW ), "wrong name %s\n", wine_dbgstr_w( name )); 296 break; 297 case 1: /* second entry must be '..' */ 298 ok( !lstrcmpW( name, dotdotW ), "wrong name %s\n", wine_dbgstr_w( name )); 299 break; 300 case 2: /* nothing to compare against */ 301 break; 302 default: 303 pRtlInitUnicodeString( &prev_str, prev ); 304 pRtlInitUnicodeString( &name_str, name ); 305 res = pRtlCompareUnicodeString( &prev_str, &name_str, TRUE ); 306 ok( res < 0, "wrong result %d %s %s\n", res, wine_dbgstr_w( prev ), wine_dbgstr_w( name )); 307 break; 308 } 309 count++; 310 lstrcpyW( prev, name ); 311 312 if (info->NextEntryOffset == 0) 313 { 314 U(io).Status = 0xdeadbeef; 315 status = pNtQueryDirectoryFile( handle, 0, NULL, NULL, &io, data, sizeof(data), 316 FileBothDirectoryInformation, FALSE, NULL, FALSE ); 317 ok (U(io).Status == status, "wrong status %x / %x\n", status, U(io).Status); 318 if (status == STATUS_NO_MORE_FILES) break; 319 ok( status == STATUS_SUCCESS, "failed to query directory; status %x\n", status ); 320 data_len = io.Information; 321 data_pos = 0; 322 } 323 else data_pos += info->NextEntryOffset; 324 } 325 326 pNtClose( handle ); 327 pRtlFreeUnicodeString( &ntdirname ); 328} 329 330static void test_NtQueryDirectoryFile_classes( HANDLE handle, UNICODE_STRING *mask ) 331{ 332 IO_STATUS_BLOCK io; 333 UINT data_size; 334 ULONG data[256]; 335 NTSTATUS status; 336 int class; 337 338 for (class = 0; class < FileMaximumInformation; class++) 339 { 340 U(io).Status = 0xdeadbeef; 341 U(io).Information = 0xdeadbeef; 342 data_size = 0; 343 memset( data, 0x55, sizeof(data) ); 344 345 status = pNtQueryDirectoryFile( handle, 0, NULL, NULL, &io, data, data_size, 346 class, FALSE, mask, TRUE ); 347 ok( U(io).Status == 0xdeadbeef, "%u: wrong status %x\n", class, U(io).Status ); 348 ok( U(io).Information == 0xdeadbeef, "%u: wrong info %lx\n", class, U(io).Information ); 349 ok(data[0] == 0x55555555, "%u: wrong offset %x\n", class, data[0] ); 350 351 switch (class) 352 { 353 case FileIdGlobalTxDirectoryInformation: 354 case FileIdExtdDirectoryInformation: 355 case FileIdExtdBothDirectoryInformation: 356 if (status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED) continue; 357 /* fall through */ 358 case FileDirectoryInformation: 359 case FileFullDirectoryInformation: 360 case FileBothDirectoryInformation: 361 case FileNamesInformation: 362 case FileIdBothDirectoryInformation: 363 case FileIdFullDirectoryInformation: 364 case FileObjectIdInformation: 365 case FileQuotaInformation: 366 case FileReparsePointInformation: 367 ok( status == STATUS_INFO_LENGTH_MISMATCH, "%u: wrong status %x\n", class, status ); 368 break; 369 default: 370 ok( status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED, 371 "%u: wrong status %x\n", class, status ); 372 continue; 373 } 374 375 for (data_size = 1; data_size < sizeof(data); data_size++) 376 { 377 status = pNtQueryDirectoryFile( handle, 0, NULL, NULL, &io, data, data_size, 378 class, FALSE, mask, TRUE ); 379 if (status == STATUS_BUFFER_OVERFLOW) 380 { 381 ok( U(io).Status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, U(io).Status ); 382 ok( U(io).Information == data_size, "%u: wrong info %lx\n", class, U(io).Information ); 383 ok(data[0] == 0, "%u: wrong offset %x\n", class, data[0] ); 384 } 385 else 386 { 387 ok( U(io).Status == 0xdeadbeef, "%u: wrong status %x\n", class, U(io).Status ); 388 ok( U(io).Information == 0xdeadbeef, "%u: wrong info %lx\n", class, U(io).Information ); 389 ok(data[0] == 0x55555555, "%u: wrong offset %x\n", class, data[0] ); 390 } 391 if (status != STATUS_INFO_LENGTH_MISMATCH) break; 392 } 393 394 switch (class) 395 { 396 case FileDirectoryInformation: 397 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status ); 398 ok( data_size == ((offsetof( FILE_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7), 399 "%u: wrong size %u\n", class, data_size ); 400 break; 401 case FileFullDirectoryInformation: 402 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status ); 403 ok( data_size == ((offsetof( FILE_FULL_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7), 404 "%u: wrong size %u\n", class, data_size ); 405 break; 406 case FileBothDirectoryInformation: 407 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status ); 408 ok( data_size == ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7), 409 "%u: wrong size %u\n", class, data_size ); 410 break; 411 case FileNamesInformation: 412 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status ); 413 ok( data_size == ((offsetof( FILE_NAMES_INFORMATION, FileName[1] ) + 7) & ~7), 414 "%u: wrong size %u\n", class, data_size ); 415 break; 416 case FileIdBothDirectoryInformation: 417 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status ); 418 ok( data_size == ((offsetof( FILE_ID_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7), 419 "%u: wrong size %u\n", class, data_size ); 420 break; 421 case FileIdFullDirectoryInformation: 422 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status ); 423 ok( data_size == ((offsetof( FILE_ID_FULL_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7), 424 "%u: wrong size %u\n", class, data_size ); 425 break; 426 case FileIdGlobalTxDirectoryInformation: 427 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status ); 428 ok( data_size == ((offsetof( FILE_ID_GLOBAL_TX_DIR_INFORMATION, FileName[1] ) + 7) & ~7), 429 "%u: wrong size %u\n", class, data_size ); 430 break; 431 case FileObjectIdInformation: 432 ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %x\n", class, status ); 433 ok( data_size == sizeof(FILE_OBJECTID_INFORMATION), "%u: wrong size %u\n", class, data_size ); 434 break; 435 case FileQuotaInformation: 436 ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %x\n", class, status ); 437 ok( data_size == sizeof(FILE_QUOTA_INFORMATION), "%u: wrong size %u\n", class, data_size ); 438 break; 439 case FileReparsePointInformation: 440 ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %x\n", class, status ); 441 ok( data_size == sizeof(FILE_REPARSE_POINT_INFORMATION), "%u: wrong size %u\n", class, data_size ); 442 break; 443 } 444 } 445} 446 447static void test_NtQueryDirectoryFile(void) 448{ 449 OBJECT_ATTRIBUTES attr; 450 UNICODE_STRING ntdirname, mask; |
|
232 char testdirA[MAX_PATH]; 233 WCHAR testdirW[MAX_PATH]; 234 int i; | 451 char testdirA[MAX_PATH]; 452 WCHAR testdirW[MAX_PATH]; 453 int i; |
454 IO_STATUS_BLOCK io; 455 WCHAR short_name[12]; 456 UINT data_size; 457 BYTE data[8192]; 458 FILE_BOTH_DIRECTORY_INFORMATION *next, *fbdi = (FILE_BOTH_DIRECTORY_INFORMATION*)data; 459 FILE_POSITION_INFORMATION pos_info; 460 FILE_NAMES_INFORMATION *names; 461 const WCHAR *filename = fbdi->FileName; 462 NTSTATUS status; 463 HANDLE dirh; |
|
235 236 /* Clean up from prior aborted run, if any, then set up test files */ 237 ok(GetTempPathA(MAX_PATH, testdirA), "couldn't get temp dir\n"); 238 strcat(testdirA, "NtQueryDirectoryFile.tmp"); | 464 465 /* Clean up from prior aborted run, if any, then set up test files */ 466 ok(GetTempPathA(MAX_PATH, testdirA), "couldn't get temp dir\n"); 467 strcat(testdirA, "NtQueryDirectoryFile.tmp"); |
239 tear_down_attribute_test(testdirA); 240 set_up_attribute_test(testdirA); 241 | |
242 pRtlMultiByteToUnicodeN(testdirW, sizeof(testdirW), NULL, testdirA, strlen(testdirA)+1); | 468 pRtlMultiByteToUnicodeN(testdirW, sizeof(testdirW), NULL, testdirA, strlen(testdirA)+1); |
469 tear_down_attribute_test(testdirW); 470 set_up_attribute_test(testdirW); 471 |
|
243 if (!pRtlDosPathNameToNtPathName_U(testdirW, &ntdirname, NULL, NULL)) 244 { 245 ok(0, "RtlDosPathNametoNtPathName_U failed\n"); 246 goto done; 247 } 248 InitializeObjectAttributes(&attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL); 249 250 test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, TRUE); 251 test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, FALSE); 252 test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, TRUE); 253 test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, FALSE); 254 | 472 if (!pRtlDosPathNameToNtPathName_U(testdirW, &ntdirname, NULL, NULL)) 473 { 474 ok(0, "RtlDosPathNametoNtPathName_U failed\n"); 475 goto done; 476 } 477 InitializeObjectAttributes(&attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL); 478 479 test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, TRUE); 480 test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, FALSE); 481 test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, TRUE); 482 test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, FALSE); 483 |
255 for (i = 0; testfiles[i].name; i++) | 484 for (i = 0; i < test_dir_count; i++) |
256 { | 485 { |
257 UNICODE_STRING mask; 258 259 if (testfiles[i].nameW[0] == '.') continue; /* . and .. as masks are broken on Windows */ 260 mask.Buffer = testfiles[i].nameW; 261 mask.Length = mask.MaximumLength = lstrlenW(testfiles[i].nameW) * sizeof(WCHAR); | 486 if (testfiles[i].name[0] == '.') continue; /* . and .. as masks are broken on Windows */ 487 mask.Buffer = testfiles[i].name; 488 mask.Length = mask.MaximumLength = lstrlenW(testfiles[i].name) * sizeof(WCHAR); |
262 test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, TRUE); 263 test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, FALSE); 264 test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, TRUE); 265 test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, FALSE); 266 } 267 | 489 test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, TRUE); 490 test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, FALSE); 491 test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, TRUE); 492 test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, FALSE); 493 } 494 |
495 /* short path passed as mask */ 496 status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, 497 FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); 498 ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA); 499 if (status != STATUS_SUCCESS) { 500 skip("can't test if we can't open the directory\n"); 501 return; 502 } 503 status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation ); 504 ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %x\n", status ); 505 ok( pos_info.CurrentByteOffset.QuadPart == 0, "wrong pos %s\n", 506 wine_dbgstr_longlong(pos_info.CurrentByteOffset.QuadPart)); 507 508 pos_info.CurrentByteOffset.QuadPart = 0xbeef; 509 status = pNtSetInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation ); 510 ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %x\n", status ); 511 512 status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation ); 513 ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %x\n", status ); 514 ok( pos_info.CurrentByteOffset.QuadPart == 0xbeef, "wrong pos %s\n", 515 wine_dbgstr_longlong(pos_info.CurrentByteOffset.QuadPart)); 516 517 mask.Buffer = testfiles[0].name; 518 mask.Length = mask.MaximumLength = lstrlenW(testfiles[0].name) * sizeof(WCHAR); 519 data_size = offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[256]); 520 U(io).Status = 0xdeadbeef; 521 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, 522 FileBothDirectoryInformation, TRUE, &mask, FALSE); 523 ok(status == STATUS_SUCCESS, "failed to query directory; status %x\n", status); 524 ok(U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status); 525 ok(fbdi->ShortName[0], "ShortName is empty\n"); 526 527 status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation ); 528 ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %x\n", status ); 529 ok( pos_info.CurrentByteOffset.QuadPart == 0xbeef, "wrong pos %s\n", 530 wine_dbgstr_longlong(pos_info.CurrentByteOffset.QuadPart) ); 531 532 mask.Length = mask.MaximumLength = fbdi->ShortNameLength; 533 memcpy(short_name, fbdi->ShortName, mask.Length); 534 mask.Buffer = short_name; 535 U(io).Status = 0xdeadbeef; 536 U(io).Information = 0xdeadbeef; 537 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, 538 FileBothDirectoryInformation, TRUE, &mask, TRUE); 539 ok(status == STATUS_SUCCESS, "failed to query directory status %x\n", status); 540 ok(U(io).Status == STATUS_SUCCESS, "failed to query directory status %x\n", U(io).Status); 541 ok(U(io).Information == offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[lstrlenW(testfiles[0].name)]), 542 "wrong info %lx\n", U(io).Information); 543 ok(fbdi->FileNameLength == lstrlenW(testfiles[0].name)*sizeof(WCHAR) && 544 !memcmp(fbdi->FileName, testfiles[0].name, fbdi->FileNameLength), 545 "incorrect long file name: %s\n", wine_dbgstr_wn(fbdi->FileName, 546 fbdi->FileNameLength/sizeof(WCHAR))); 547 548 status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation ); 549 ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %x\n", status ); 550 ok( pos_info.CurrentByteOffset.QuadPart == 0xbeef, "wrong pos %s\n", 551 wine_dbgstr_longlong(pos_info.CurrentByteOffset.QuadPart) ); 552 553 /* tests with short buffer */ 554 memset( data, 0x55, data_size ); 555 U(io).Status = 0xdeadbeef; 556 U(io).Information = 0xdeadbeef; 557 data_size = offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ); 558 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, 559 FileBothDirectoryInformation, TRUE, &mask, TRUE); 560 ok( status == STATUS_BUFFER_OVERFLOW, "wrong status %x\n", status ); 561 ok( U(io).Status == STATUS_BUFFER_OVERFLOW, "wrong status %x\n", U(io).Status ); 562 ok( U(io).Information == data_size || broken( U(io).Information == 0), 563 "wrong info %lx\n", U(io).Information ); 564 ok( fbdi->NextEntryOffset == 0, "wrong offset %x\n", fbdi->NextEntryOffset ); 565 ok( fbdi->FileNameLength == lstrlenW(testfiles[0].name) * sizeof(WCHAR), 566 "wrong length %x\n", fbdi->FileNameLength ); 567 ok( filename[0] == testfiles[0].name[0], "incorrect long file name: %s\n", 568 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR))); 569 ok( filename[1] == 0x5555, "incorrect long file name: %s\n", 570 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR))); 571 572 test_NtQueryDirectoryFile_classes( dirh, &mask ); 573 574 /* mask may or may not be ignored when restarting the search */ 575 pRtlInitUnicodeString( &mask, dummyW ); 576 U(io).Status = 0xdeadbeef; 577 data_size = offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[256] ); 578 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, 579 FileBothDirectoryInformation, TRUE, &mask, TRUE); 580 ok( status == STATUS_SUCCESS || status == STATUS_NO_MORE_FILES, "wrong status %x\n", status ); 581 ok( U(io).Status == status, "wrong status %x / %x\n", U(io).Status, status ); 582 if (!status) 583 ok( fbdi->FileNameLength == lstrlenW(testfiles[0].name)*sizeof(WCHAR) && 584 !memcmp(fbdi->FileName, testfiles[0].name, fbdi->FileNameLength), 585 "incorrect long file name: %s\n", 586 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR))); 587 588 pNtClose(dirh); 589 590 status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, 591 FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); 592 ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA); 593 594 memset( data, 0x55, data_size ); 595 data_size = sizeof(data); 596 U(io).Status = 0xdeadbeef; 597 U(io).Information = 0xdeadbeef; 598 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, 599 FileBothDirectoryInformation, FALSE, NULL, TRUE); 600 ok(status == STATUS_SUCCESS, "wrong status %x\n", status); 601 ok(U(io).Status == STATUS_SUCCESS, "wrong status %x\n", U(io).Status); 602 ok(U(io).Information > 0 && U(io).Information < data_size, "wrong info %lx\n", U(io).Information); 603 ok( fbdi->NextEntryOffset == ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7), 604 "wrong offset %x\n", fbdi->NextEntryOffset ); 605 ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %x\n", fbdi->FileNameLength ); 606 ok( fbdi->FileName[0] == '.', "incorrect long file name: %s\n", 607 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR))); 608 next = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + fbdi->NextEntryOffset); 609 ok( next->NextEntryOffset == ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[2] ) + 7) & ~7), 610 "wrong offset %x\n", next->NextEntryOffset ); 611 ok( next->FileNameLength == 2 * sizeof(WCHAR), "wrong length %x\n", next->FileNameLength ); 612 filename = next->FileName; 613 ok( filename[0] == '.' && filename[1] == '.', "incorrect long file name: %s\n", 614 wine_dbgstr_wn(next->FileName, next->FileNameLength/sizeof(WCHAR))); 615 616 data_size = fbdi->NextEntryOffset + offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ), 617 memset( data, 0x55, data_size ); 618 U(io).Status = 0xdeadbeef; 619 U(io).Information = 0xdeadbeef; 620 status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size, 621 FileBothDirectoryInformation, FALSE, NULL, TRUE ); 622 ok( status == STATUS_SUCCESS, "wrong status %x\n", status ); 623 ok( U(io).Status == STATUS_SUCCESS, "wrong status %x\n", U(io).Status ); 624 ok( U(io).Information == offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ), 625 "wrong info %lx\n", U(io).Information ); 626 ok( fbdi->NextEntryOffset == 0, "wrong offset %x\n", fbdi->NextEntryOffset ); 627 ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %x\n", fbdi->FileNameLength ); 628 ok( fbdi->FileName[0] == '.', "incorrect long file name: %s\n", 629 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR))); 630 next = (FILE_BOTH_DIRECTORY_INFORMATION *)&fbdi->FileName[1]; 631 ok( next->NextEntryOffset == 0x55555555, "wrong offset %x\n", next->NextEntryOffset ); 632 633 data_size = fbdi->NextEntryOffset + offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[2] ), 634 memset( data, 0x55, data_size ); 635 U(io).Status = 0xdeadbeef; 636 U(io).Information = 0xdeadbeef; 637 status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size, 638 FileBothDirectoryInformation, FALSE, NULL, TRUE ); 639 ok( status == STATUS_SUCCESS, "wrong status %x\n", status ); 640 ok( U(io).Status == STATUS_SUCCESS, "wrong status %x\n", U(io).Status ); 641 ok( U(io).Information == offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ), 642 "wrong info %lx\n", U(io).Information ); 643 ok( fbdi->NextEntryOffset == 0, "wrong offset %x\n", fbdi->NextEntryOffset ); 644 645 data_size = ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7) + 646 offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[2] ); 647 memset( data, 0x55, data_size ); 648 U(io).Status = 0xdeadbeef; 649 U(io).Information = 0xdeadbeef; 650 status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size, 651 FileBothDirectoryInformation, FALSE, NULL, TRUE ); 652 ok( status == STATUS_SUCCESS, "wrong status %x\n", status ); 653 ok( U(io).Status == STATUS_SUCCESS, "wrong status %x\n", U(io).Status ); 654 ok( U(io).Information == data_size, "wrong info %lx / %x\n", U(io).Information, data_size ); 655 ok( fbdi->NextEntryOffset == ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7), 656 "wrong offset %x\n", fbdi->NextEntryOffset ); 657 ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %x\n", fbdi->FileNameLength ); 658 ok( fbdi->FileName[0] == '.', "incorrect long file name: %s\n", 659 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR))); 660 next = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + fbdi->NextEntryOffset); 661 ok( next->NextEntryOffset == 0, "wrong offset %x\n", next->NextEntryOffset ); 662 ok( next->FileNameLength == 2 * sizeof(WCHAR), "wrong length %x\n", next->FileNameLength ); 663 filename = next->FileName; 664 ok( filename[0] == '.' && filename[1] == '.', "incorrect long file name: %s\n", 665 wine_dbgstr_wn(next->FileName, next->FileNameLength/sizeof(WCHAR))); 666 667 data_size = ((offsetof( FILE_NAMES_INFORMATION, FileName[1] ) + 7) & ~7) + 668 offsetof( FILE_NAMES_INFORMATION, FileName[2] ); 669 memset( data, 0x55, data_size ); 670 U(io).Status = 0xdeadbeef; 671 U(io).Information = 0xdeadbeef; 672 status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size, 673 FileNamesInformation, FALSE, NULL, TRUE ); 674 ok( status == STATUS_SUCCESS, "wrong status %x\n", status ); 675 ok( U(io).Status == STATUS_SUCCESS, "wrong status %x\n", U(io).Status ); 676 ok( U(io).Information == data_size, "wrong info %lx / %x\n", U(io).Information, data_size ); 677 names = (FILE_NAMES_INFORMATION *)data; 678 ok( names->NextEntryOffset == ((offsetof( FILE_NAMES_INFORMATION, FileName[1] ) + 7) & ~7), 679 "wrong offset %x\n", names->NextEntryOffset ); 680 ok( names->FileNameLength == sizeof(WCHAR), "wrong length %x\n", names->FileNameLength ); 681 ok( names->FileName[0] == '.', "incorrect long file name: %s\n", 682 wine_dbgstr_wn(names->FileName, names->FileNameLength/sizeof(WCHAR))); 683 names = (FILE_NAMES_INFORMATION *)(data + names->NextEntryOffset); 684 ok( names->NextEntryOffset == 0, "wrong offset %x\n", names->NextEntryOffset ); 685 ok( names->FileNameLength == 2 * sizeof(WCHAR), "wrong length %x\n", names->FileNameLength ); 686 filename = names->FileName; 687 ok( filename[0] == '.' && filename[1] == '.', "incorrect long file name: %s\n", 688 wine_dbgstr_wn(names->FileName, names->FileNameLength/sizeof(WCHAR))); 689 690 pNtClose(dirh); 691 692 /* create new handle to change mask */ 693 status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, 694 FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); 695 ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA); 696 697 pRtlInitUnicodeString( &mask, dummyW ); 698 U(io).Status = 0xdeadbeef; 699 data_size = sizeof(data); 700 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, 701 FileBothDirectoryInformation, TRUE, &mask, TRUE); 702 ok(status == STATUS_NO_SUCH_FILE, "wrong status %x\n", status); 703 ok(U(io).Status == 0xdeadbeef, "wrong status %x\n", U(io).Status); 704 705 U(io).Status = 0xdeadbeef; 706 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, 707 FileBothDirectoryInformation, TRUE, NULL, FALSE); 708 ok(status == STATUS_NO_MORE_FILES, "wrong status %x\n", status); 709 ok(U(io).Status == STATUS_NO_MORE_FILES, "wrong status %x\n", U(io).Status); 710 711 U(io).Status = 0xdeadbeef; 712 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, 713 FileBothDirectoryInformation, TRUE, NULL, TRUE); 714 ok(status == STATUS_NO_MORE_FILES, "wrong status %x\n", status); 715 ok(U(io).Status == STATUS_NO_MORE_FILES, "wrong status %x\n", U(io).Status); 716 717 pNtClose(dirh); 718 719 U(io).Status = 0xdeadbeef; 720 status = pNtQueryDirectoryFile( (HANDLE)0xbeef, 0, NULL, NULL, &io, data, data_size, 721 FileBothDirectoryInformation, TRUE, NULL, TRUE ); 722 ok(status == STATUS_INVALID_HANDLE, "wrong status %x\n", status); 723 ok(U(io).Status == 0xdeadbeef, "wrong status %x\n", U(io).Status); 724 |
|
268done: | 725done: |
269 tear_down_attribute_test(testdirA); | 726 test_directory_sort( testdirW ); 727 tear_down_attribute_test( testdirW ); |
270 pRtlFreeUnicodeString(&ntdirname); 271} 272 273static void set_up_case_test(const char *testdir) 274{ 275 BOOL ret; 276 char buf[MAX_PATH]; 277 HANDLE h; --- 120 unchanged lines hidden (view full) --- 398 status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur ); 399 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status ); 400 ok( !cur, "RtlWow64EnableFsRedirectionEx got %u\n", cur ); 401 402 status = pRtlWow64EnableFsRedirectionEx( TRUE, NULL ); 403 ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status ); 404 status = pRtlWow64EnableFsRedirectionEx( TRUE, (void*)1 ); 405 ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status ); | 728 pRtlFreeUnicodeString(&ntdirname); 729} 730 731static void set_up_case_test(const char *testdir) 732{ 733 BOOL ret; 734 char buf[MAX_PATH]; 735 HANDLE h; --- 120 unchanged lines hidden (view full) --- 856 status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur ); 857 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status ); 858 ok( !cur, "RtlWow64EnableFsRedirectionEx got %u\n", cur ); 859 860 status = pRtlWow64EnableFsRedirectionEx( TRUE, NULL ); 861 ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status ); 862 status = pRtlWow64EnableFsRedirectionEx( TRUE, (void*)1 ); 863 ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status ); |
864 status = pRtlWow64EnableFsRedirectionEx( TRUE, (void*)0xDEADBEEF ); 865 ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status ); |
|
406 407 status = pRtlWow64EnableFsRedirection( FALSE ); 408 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status ); 409 status = pRtlWow64EnableFsRedirectionEx( FALSE, &cur ); 410 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status ); 411 ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %u\n", cur ); 412 413 pRtlWow64EnableFsRedirectionEx( old, &cur ); 414} 415 416START_TEST(directory) 417{ | 866 867 status = pRtlWow64EnableFsRedirection( FALSE ); 868 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status ); 869 status = pRtlWow64EnableFsRedirectionEx( FALSE, &cur ); 870 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status ); 871 ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %u\n", cur ); 872 873 pRtlWow64EnableFsRedirectionEx( old, &cur ); 874} 875 876START_TEST(directory) 877{ |
878 WCHAR sysdir[MAX_PATH]; |
|
418 HMODULE hntdll = GetModuleHandleA("ntdll.dll"); 419 if (!hntdll) 420 { 421 skip("not running on NT, skipping test\n"); 422 return; 423 } 424 425 pNtClose = (void *)GetProcAddress(hntdll, "NtClose"); 426 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile"); 427 pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile"); | 879 HMODULE hntdll = GetModuleHandleA("ntdll.dll"); 880 if (!hntdll) 881 { 882 skip("not running on NT, skipping test\n"); 883 return; 884 } 885 886 pNtClose = (void *)GetProcAddress(hntdll, "NtClose"); 887 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile"); 888 pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile"); |
889 pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile"); 890 pNtSetInformationFile = (void *)GetProcAddress(hntdll, "NtSetInformationFile"); |
|
428 pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz"); 429 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U"); 430 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); 431 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); | 891 pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz"); 892 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U"); 893 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); 894 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); |
895 pRtlCompareUnicodeString = (void *)GetProcAddress(hntdll, "RtlCompareUnicodeString"); |
|
432 pRtlMultiByteToUnicodeN = (void *)GetProcAddress(hntdll,"RtlMultiByteToUnicodeN"); 433 pRtlWow64EnableFsRedirection = (void *)GetProcAddress(hntdll,"RtlWow64EnableFsRedirection"); 434 pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll,"RtlWow64EnableFsRedirectionEx"); 435 | 896 pRtlMultiByteToUnicodeN = (void *)GetProcAddress(hntdll,"RtlMultiByteToUnicodeN"); 897 pRtlWow64EnableFsRedirection = (void *)GetProcAddress(hntdll,"RtlWow64EnableFsRedirection"); 898 pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll,"RtlWow64EnableFsRedirectionEx"); 899 |
900 GetSystemDirectoryW( sysdir, MAX_PATH ); 901 test_directory_sort( sysdir ); |
|
436 test_NtQueryDirectoryFile(); 437 test_NtQueryDirectoryFile_case(); 438 test_redirection(); 439} | 902 test_NtQueryDirectoryFile(); 903 test_NtQueryDirectoryFile_case(); 904 test_redirection(); 905} |