ReactOS 0.4.17-dev-116-ga4b6fe9
directory.c
Go to the documentation of this file.
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
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 "winnls.h"
38#include "winternl.h"
39
40static NTSTATUS (WINAPI *pNtClose)( PHANDLE );
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 );
51static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
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 */
60 WCHAR name[20]; /* filename to use */
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) */
64} testfiles[] = {
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_NORMAL, {'e','a'}, "normal" },
74 { 0, FILE_ATTRIBUTE_DIRECTORY, {'.'}, ". directory" },
75 { 0, FILE_ATTRIBUTE_DIRECTORY, {'.','.'}, ".. directory" },
76 { 0, FILE_ATTRIBUTE_NORMAL, {'e','a','.','t','m','p','.','t','m','p'}, "normal" },
77 { 0, FILE_ATTRIBUTE_NORMAL, {'.','a'}, "normal" },
78 { 0, FILE_ATTRIBUTE_NORMAL, {'.','a','.','a'}, "normal" },
79 { 0, FILE_ATTRIBUTE_NORMAL, {'a','.'}, "normal" },
80 { 0, FILE_ATTRIBUTE_NORMAL, {'.','.','a'}, "normal" },
81 { 0, FILE_ATTRIBUTE_NORMAL, {'.','a','a'}, "normal" },
82 { 0, FILE_ATTRIBUTE_NORMAL, {'a','.', '.'}, "normal" },
83};
85static const int max_test_dir_size = ARRAY_SIZE(testfiles) + 5; /* size of above plus some for .. etc */
86
87static const WCHAR dummyW[] = {'d','u','m','m','y',0};
88static const WCHAR dotW[] = {'.',0};
89static const WCHAR dotdotW[] = {'.','.',0};
90static const WCHAR backslashW[] = {'\\',0};
91
92/* Create a test directory full of attribute test files, clear counts */
93static void set_up_attribute_test(const WCHAR *testdir)
94{
95 int i;
96 BOOL ret;
97
98 ret = CreateDirectoryW(testdir, NULL);
99 ok(ret, "couldn't create dir %s, error %ld\n", wine_dbgstr_w(testdir), GetLastError());
100
101 for (i=0; i < test_dir_count; i++) {
103
104 if (lstrcmpW(testfiles[i].name, dotW) == 0 || lstrcmpW(testfiles[i].name, dotdotW) == 0)
105 continue;
106 lstrcpyW( buf, L"\\\\?\\" );
107 lstrcatW( buf, testdir );
112 ok(ret, "couldn't create dir %s, error %ld\n", wine_dbgstr_w(buf), GetLastError());
113 } else {
117 testfiles[i].attr, 0);
118 ok( h != INVALID_HANDLE_VALUE, "failed to create temp file %s\n", wine_dbgstr_w(buf) );
119 CloseHandle(h);
120 }
121 }
122}
123
124static void reset_found_files(void)
125{
126 int i;
127
128 for (i = 0; i < test_dir_count; i++)
129 testfiles[i].nfound = 0;
130}
131
132/* Remove the given test directory and the attribute test files, if any */
133static void tear_down_attribute_test(const WCHAR *testdir)
134{
135 int i;
136
137 for (i = 0; i < test_dir_count; i++) {
138 int ret;
140 if (lstrcmpW(testfiles[i].name, dotW) == 0 || lstrcmpW(testfiles[i].name, dotdotW) == 0)
141 continue;
142 lstrcpyW( buf, L"\\\\?\\" );
143 lstrcatW( buf, testdir );
149 "Failed to rmdir %s, error %ld\n", wine_dbgstr_w(buf), GetLastError());
150 } else {
153 "Failed to rm %s, error %ld\n", wine_dbgstr_w(buf), GetLastError());
154 }
155 }
156 RemoveDirectoryW(testdir);
157}
158
159/* Match one found file against testfiles[], increment count if found */
161{
162 int i;
163 DWORD attribmask =
165 DWORD attrib = dir_info->FileAttributes & attribmask;
166 WCHAR *nameW = dir_info->FileName;
167 int namelen = dir_info->FileNameLength / sizeof(WCHAR);
168
169 for (i = 0; i < test_dir_count; i++) {
170 int len = lstrlenW(testfiles[i].name);
171 if (namelen != len || memcmp(nameW, testfiles[i].name, len*sizeof(WCHAR)))
172 continue;
173 if (!testfiles[i].attr_done) {
174 ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%lx), got %lx\n",
176 testfiles[i].attr_done = TRUE;
177 }
178 testfiles[i].nfound++;
179 break;
180 }
181 ok(i < test_dir_count, "unexpected file found %s\n", wine_dbgstr_wn(dir_info->FileName, namelen));
182}
183
184static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char *testdirA,
186 BOOLEAN single_entry, BOOLEAN restart_flag, BOOLEAN expect_empty)
187{
188 UNICODE_STRING dummy_mask;
189 HANDLE dirh, new_dirh;
191 UINT data_pos, data_size;
192 UINT data_len; /* length of dir data */
193 BYTE data[8192]; /* directory data */
196 int numfiles;
197 int i;
198
200 pRtlInitUnicodeString( &dummy_mask, dummyW );
201
202 data_size = mask ? offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[256] ) : sizeof(data);
203
204 /* Read the directory and note which files are found */
205 status = pNtOpenFile( &dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, attr, &io, FILE_SHARE_READ,
207 ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%lx, error %ld\n", testdirA, status, GetLastError());
208 if (status != STATUS_SUCCESS) {
209 skip("can't test if we can't open the directory\n");
210 return;
211 }
212
213 io.Status = 0xdeadbeef;
214 status = pNtQueryDirectoryFile( dirh, NULL, NULL, NULL, &io, data, data_size,
215 FileBothDirectoryInformation, single_entry, mask, restart_flag );
216 if (expect_empty)
217 {
218 ok( status == STATUS_NO_SUCH_FILE, "got %#lx.\n", status );
219 pNtClose( dirh );
220 return;
221 }
222 ok (status == STATUS_SUCCESS, "failed to query directory; status %lx\n", status);
223 ok (io.Status == STATUS_SUCCESS, "failed to query directory; status %lx\n", io.Status);
224 data_len = io.Information;
225 ok (data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n");
226
229 pNtClose(dirh);
230
231 data_pos = 0;
232 numfiles = 0;
233 while ((data_pos < data_len) && (numfiles < max_test_dir_size)) {
234 dir_info = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + data_pos);
235
236 tally_test_file(dir_info);
237
238 if (dir_info->NextEntryOffset == 0) {
239 io.Status = 0xdeadbeef;
240 status = pNtQueryDirectoryFile( new_dirh, 0, NULL, NULL, &io, data, data_size,
241 FileBothDirectoryInformation, single_entry, &dummy_mask, FALSE );
242 ok (io.Status == status, "wrong status %lx / %lx\n", status, io.Status);
243 if (status == STATUS_NO_MORE_FILES) break;
244 ok (status == STATUS_SUCCESS, "failed to query directory; status %lx\n", status);
245 data_len = io.Information;
246 if (data_len < sizeof(FILE_BOTH_DIRECTORY_INFORMATION))
247 break;
248 data_pos = 0;
249 } else {
250 data_pos += dir_info->NextEntryOffset;
251 }
252 numfiles++;
253 }
254 ok(numfiles < max_test_dir_size, "too many loops\n");
255
256 if (mask && !wcspbrk( mask->Buffer, L"*?<\">" ))
257 for (i = 0; i < test_dir_count; i++)
258 ok(testfiles[i].nfound == (testfiles[i].name == mask->Buffer),
259 "Wrong number %d of %s files found (single_entry=%d,mask=%s)\n",
260 testfiles[i].nfound, testfiles[i].description, single_entry,
261 wine_dbgstr_wn(mask->Buffer, mask->Length/sizeof(WCHAR) ));
262 else if (!mask)
263 for (i = 0; i < test_dir_count; i++)
264 ok(testfiles[i].nfound == 1, "Wrong number %d of %s files found (single_entry=%d,restart=%d)\n",
265 testfiles[i].nfound, testfiles[i].description, single_entry, restart_flag);
266 pNtClose(new_dirh);
267}
268
269static void test_directory_sort( const WCHAR *testdir )
270{
272 UNICODE_STRING ntdirname;
274 UINT data_pos, data_len, count;
275 BYTE data[8192];
276 WCHAR prev[MAX_PATH], name[MAX_PATH];
277 UNICODE_STRING prev_str, name_str;
281 int res;
282
283 if (!pRtlDosPathNameToNtPathName_U( testdir, &ntdirname, NULL, NULL ))
284 {
285 ok(0, "RtlDosPathNametoNtPathName_U failed\n");
286 return;
287 }
291 ok(status == STATUS_SUCCESS, "failed to open dir %s\n", wine_dbgstr_w(testdir) );
292
293 io.Status = 0xdeadbeef;
294 status = pNtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, data, sizeof(data),
296 ok( status == STATUS_SUCCESS, "failed to query directory; status %lx\n", status );
297 ok( io.Status == STATUS_SUCCESS, "failed to query directory; status %lx\n", io.Status );
298 data_len = io.Information;
299 ok( data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n" );
300 data_pos = 0;
301 count = 0;
302
303 while (data_pos < data_len)
304 {
305 info = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + data_pos);
306
307 memcpy( name, info->FileName, info->FileNameLength );
308 name[info->FileNameLength / sizeof(WCHAR)] = 0;
309 switch (count)
310 {
311 case 0: /* first entry must be '.' */
312 ok( !lstrcmpW( name, dotW ), "wrong name %s\n", wine_dbgstr_w( name ));
313 break;
314 case 1: /* second entry must be '..' */
315 ok( !lstrcmpW( name, dotdotW ), "wrong name %s\n", wine_dbgstr_w( name ));
316 break;
317 case 2: /* nothing to compare against */
318 break;
319 default:
320 pRtlInitUnicodeString( &prev_str, prev );
321 pRtlInitUnicodeString( &name_str, name );
322 res = pRtlCompareUnicodeString( &prev_str, &name_str, TRUE );
323 ok( res < 0, "wrong result %d %s %s\n", res, wine_dbgstr_w( prev ), wine_dbgstr_w( name ));
324 break;
325 }
326 count++;
327 lstrcpyW( prev, name );
328
329 if (info->NextEntryOffset == 0)
330 {
331 io.Status = 0xdeadbeef;
332 status = pNtQueryDirectoryFile( handle, 0, NULL, NULL, &io, data, sizeof(data),
334 ok (io.Status == status, "wrong status %lx / %lx\n", status, io.Status);
335 if (status == STATUS_NO_MORE_FILES) break;
336 ok( status == STATUS_SUCCESS, "failed to query directory; status %lx\n", status );
337 data_len = io.Information;
338 data_pos = 0;
339 }
340 else data_pos += info->NextEntryOffset;
341 }
342
343 pNtClose( handle );
344 pRtlFreeUnicodeString( &ntdirname );
345}
346
348{
350 UINT data_size;
351 ULONG data[256];
353 int class;
354
355 for (class = 0; class < FileMaximumInformation; class++)
356 {
357 io.Status = 0xdeadbeef;
358 io.Information = 0xdeadbeef;
359 data_size = 0;
360 memset( data, 0x55, sizeof(data) );
361
362 status = pNtQueryDirectoryFile( handle, 0, NULL, NULL, &io, data, data_size,
363 class, FALSE, mask, TRUE );
364 ok( io.Status == 0xdeadbeef, "%u: wrong status %lx\n", class, io.Status );
365 ok( io.Information == 0xdeadbeef, "%u: wrong info %Ix\n", class, io.Information );
366 ok(data[0] == 0x55555555, "%u: wrong offset %lx\n", class, data[0] );
367
368 switch (class)
369 {
374 /* fall through */
384 ok( status == STATUS_INFO_LENGTH_MISMATCH, "%u: wrong status %lx\n", class, status );
385 break;
386 default:
388 "%u: wrong status %lx\n", class, status );
389 continue;
390 }
391
392 for (data_size = 1; data_size < sizeof(data); data_size++)
393 {
394 status = pNtQueryDirectoryFile( handle, 0, NULL, NULL, &io, data, data_size,
395 class, FALSE, mask, TRUE );
397 {
398 ok( io.Status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, io.Status );
399 ok( io.Information == data_size || broken(!io.Information), /* win10 1709 */
400 "%u: wrong info %Ix\n", class, io.Information );
401 if (io.Information) ok(data[0] == 0, "%u: wrong offset %lx\n", class, data[0] );
402 }
403 else
404 {
405 ok( io.Status == 0xdeadbeef || io.Status == status, "%u: wrong status %lx\n", class, io.Status );
406 ok( io.Information == (io.Status == 0xdeadbeef ? 0xdeadbeef : 0), "%u: wrong info %Ix\n", class, io.Information );
407 ok(data[0] == 0x55555555, "%u: wrong offset %lx\n", class, data[0] );
408 }
410 }
411
412 switch (class)
413 {
415 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
416 ok( data_size == ((offsetof( FILE_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
417 "%u: wrong size %u\n", class, data_size );
418 break;
420 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
421 ok( data_size == ((offsetof( FILE_FULL_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
422 "%u: wrong size %u\n", class, data_size );
423 break;
425 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
426 ok( data_size == ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
427 "%u: wrong size %u\n", class, data_size );
428 break;
430 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
431 ok( data_size == ((offsetof( FILE_NAMES_INFORMATION, FileName[1] ) + 7) & ~7),
432 "%u: wrong size %u\n", class, data_size );
433 break;
435 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
436 ok( data_size == ((offsetof( FILE_ID_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
437 "%u: wrong size %u\n", class, data_size );
438 break;
440 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
441 ok( data_size == ((offsetof( FILE_ID_FULL_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
442 "%u: wrong size %u\n", class, data_size );
443 break;
445 ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
446 ok( data_size == ((offsetof( FILE_ID_GLOBAL_TX_DIR_INFORMATION, FileName[1] ) + 7) & ~7),
447 "%u: wrong size %u\n", class, data_size );
448 break;
450 ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %lx\n", class, status );
451 ok( data_size == sizeof(FILE_OBJECTID_INFORMATION), "%u: wrong size %u\n", class, data_size );
452 break;
454 ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %lx\n", class, status );
455 ok( data_size == sizeof(FILE_QUOTA_INFORMATION), "%u: wrong size %u\n", class, data_size );
456 break;
458 ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %lx\n", class, status );
459 ok( data_size == sizeof(FILE_REPARSE_POINT_INFORMATION), "%u: wrong size %u\n", class, data_size );
460 break;
461 }
462 }
463}
464
466{
467 static const struct
468 {
469 const WCHAR *mask;
470 int found[ARRAY_SIZE(testfiles)];
471 }
472 mask_tests[] =
473 {
474 {L"*.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1}},
475 {L"*. ", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
476 {L"* .", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
477 {L" *.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
478 {L"*.*", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
479 {L"* *", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
480 {L"*.**", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
481 {L"*", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
482 {L"**", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
483 {L"?", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
484 {L"?.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}},
485 {L"?..", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
486 {L"??", {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0}},
487 {L"??.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
488 {L"??.???", {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
489 {L"<", {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1}},
490 {L"*<a", {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0}},
491 {L"<.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1}},
492 {L"<..", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
493 {L"<.\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1}},
494 {L".<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0}},
495 {L"..<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
496 {L"..*", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
497 {L"*..*", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}},
498 {L"*..", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
499 {L"..?", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
500 {L"..\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
501 {L"\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
502 {L"\"\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
503 {L"\"\"\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
504 {L"a.<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1}},
505 {L"ea.tmp.tmp<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}},
506 {L"<tmp", {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}},
507 {L"<.tmp", {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}},
508 {L"<name.tmp", {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
509 {L"<nam<tmp", {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
510 {L"<name.<", {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
511 {L"<name<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
512 {L"<\"", {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1}},
513 {L"*\"", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
514 {L"*\"tmp\"tmp\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}},
515 {L"n\"tmp", {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
516 {L"ea\"", {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
517 {L"\"a", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}},
518 {L"\"\"a", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
519 {L"e\"a", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
520 {L"*\"tmp", {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}},
521 {L"<.<", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
522 {L"<\"<", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
523 {L"<\"<\"", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
524 {L"<\"<.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
525 {L"<.<\"", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
526 {L"<<", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
527 {L"<a", {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0}},
528 {L"*a", {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0}},
529 {L"<aa", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}},
530 {L"<.a", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0}},
531 {L"<..a", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
532 {L"<.<.<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1}},
533 {L".<.<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0}},
534 {L"<<.<", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
535 {L"<.<<", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
536 {L"<<<", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
537 {L"< ..", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
538 {L"< .", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
539 {L"<\"\"", {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1}},
540 {L">", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
541 {L">.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0}},
542 {L">..", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
543 {L">>", {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0}},
544 {L">>.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0}},
545 {L">>>", {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0}},
546 {L">>.>>>", {0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1}},
547 {L">.>", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1}},
548 {L">>.tmp", {0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
549 {L">>tmp", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
550 {L">>>tmp", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
551 };
552
554 UNICODE_STRING ntdirname, mask;
555 char testdirA[MAX_PATH], buffer[MAX_PATH];
556 WCHAR testdirW[MAX_PATH];
557 int i, j;
559 WCHAR short_name[12];
560 UINT data_size;
561 BYTE data[8192];
565 const WCHAR *filename = fbdi->FileName;
568 HANDLE dirh, h;
569
570 /* Clean up from prior aborted run, if any, then set up test files */
571 ok(GetTempPathA(MAX_PATH, testdirA), "couldn't get temp dir\n");
572 strcat(testdirA, "NtQueryDirectoryFile.tmp");
573 pRtlMultiByteToUnicodeN(testdirW, sizeof(testdirW), NULL, testdirA, strlen(testdirA)+1);
574 tear_down_attribute_test(testdirW);
575 set_up_attribute_test(testdirW);
576
577 if (!pRtlDosPathNameToNtPathName_U(testdirW, &ntdirname, NULL, NULL))
578 {
579 ok(0, "RtlDosPathNametoNtPathName_U failed\n");
580 goto done;
581 }
583
588
589 for (i = 0; i < test_dir_count; i++)
590 {
591 if (testfiles[i].name[0] == '.') continue; /* . and .. as masks are broken on Windows */
592 mask.Buffer = testfiles[i].name;
593 mask.Length = mask.MaximumLength = lstrlenW(testfiles[i].name) * sizeof(WCHAR);
598 }
599
600 for (i = 0; i < ARRAY_SIZE(mask_tests); ++i)
601 {
602 winetest_push_context("mask %s", debugstr_w(mask_tests[i].mask));
603 RtlInitUnicodeString(&mask, mask_tests[i].mask);
605 for (j = 0; j < ARRAY_SIZE(mask_tests[i].found); ++j)
606 {
607 if (mask_tests[i].found[j])
608 {
610 break;
611 }
612 }
614 for (j = 0; j < test_dir_count; j++)
615 ok(testfiles[j].nfound == mask_tests[i].found[j], "%S, got %d.\n", testfiles[j].name, testfiles[j].nfound);
617 }
618
619 /* short path passed as mask */
620 status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
622 ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA);
623 if (status != STATUS_SUCCESS) {
624 skip("can't test if we can't open the directory\n");
625 return;
626 }
627 status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation );
628 ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", status );
629 ok( pos_info.CurrentByteOffset.QuadPart == 0, "wrong pos %s\n",
631
632 pos_info.CurrentByteOffset.QuadPart = 0xbeef;
633 status = pNtSetInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation );
634 ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", status );
635
636 status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation );
637 ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", status );
638 ok( pos_info.CurrentByteOffset.QuadPart == 0xbeef, "wrong pos %s\n",
640
641 mask.Buffer = testfiles[0].name;
642 mask.Length = mask.MaximumLength = lstrlenW(testfiles[0].name) * sizeof(WCHAR);
644 io.Status = 0xdeadbeef;
645 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
647 ok(status == STATUS_SUCCESS, "failed to query directory; status %lx\n", status);
648 ok(io.Status == STATUS_SUCCESS, "failed to query directory; status %lx\n", io.Status);
649 ok(fbdi->ShortName[0], "ShortName is empty\n");
650
651 status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation );
652 ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", status );
653 ok( pos_info.CurrentByteOffset.QuadPart == 0xbeef, "wrong pos %s\n",
655
656 mask.Length = mask.MaximumLength = fbdi->ShortNameLength;
657 memcpy(short_name, fbdi->ShortName, mask.Length);
658 mask.Buffer = short_name;
659 io.Status = 0xdeadbeef;
660 io.Information = 0xdeadbeef;
661 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
663 ok(status == STATUS_SUCCESS, "failed to query directory status %lx\n", status);
664 ok(io.Status == STATUS_SUCCESS, "failed to query directory status %lx\n", io.Status);
666 "wrong info %Ix\n", io.Information);
667 ok(fbdi->FileNameLength == lstrlenW(testfiles[0].name)*sizeof(WCHAR) &&
668 !memcmp(fbdi->FileName, testfiles[0].name, fbdi->FileNameLength),
669 "incorrect long file name: %s\n", wine_dbgstr_wn(fbdi->FileName,
670 fbdi->FileNameLength/sizeof(WCHAR)));
671
672 status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation );
673 ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", status );
674 ok( pos_info.CurrentByteOffset.QuadPart == 0xbeef, "wrong pos %s\n",
676
677 /* tests with short buffer */
678 memset( data, 0x55, data_size );
679 io.Status = 0xdeadbeef;
680 io.Information = 0xdeadbeef;
682 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
684 ok( status == STATUS_BUFFER_OVERFLOW, "wrong status %lx\n", status );
685 ok( io.Status == STATUS_BUFFER_OVERFLOW, "wrong status %lx\n", io.Status );
686 ok( io.Information == data_size || broken( io.Information == 0),
687 "wrong info %Ix\n", io.Information );
688 ok( fbdi->NextEntryOffset == 0 || fbdi->NextEntryOffset == 0x55555555, /* win10 >= 1709 */
689 "wrong offset %lx\n", fbdi->NextEntryOffset );
690 if (!fbdi->NextEntryOffset)
691 {
692 ok( fbdi->FileNameLength == lstrlenW(testfiles[0].name) * sizeof(WCHAR),
693 "wrong length %lx\n", fbdi->FileNameLength );
694 ok( filename[0] == testfiles[0].name[0], "incorrect long file name: %s\n",
695 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
696 ok( filename[1] == 0x5555, "incorrect long file name: %s\n",
697 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
698 }
699
701
702 /* mask may or may not be ignored when restarting the search */
703 pRtlInitUnicodeString( &mask, dummyW );
704 io.Status = 0xdeadbeef;
706 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
708 ok( status == STATUS_SUCCESS || status == STATUS_NO_MORE_FILES, "wrong status %lx\n", status );
709 ok( io.Status == status, "wrong status %lx / %lx\n", io.Status, status );
710 if (!status)
711 ok( fbdi->FileNameLength == lstrlenW(testfiles[0].name)*sizeof(WCHAR) &&
712 !memcmp(fbdi->FileName, testfiles[0].name, fbdi->FileNameLength),
713 "incorrect long file name: %s\n",
714 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
715
716 pNtClose(dirh);
717
718 status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
720 ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA);
721
722 memset( data, 0x55, data_size );
723 data_size = sizeof(data);
724 io.Status = 0xdeadbeef;
725 io.Information = 0xdeadbeef;
726 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
728 ok(status == STATUS_SUCCESS, "wrong status %lx\n", status);
729 ok(io.Status == STATUS_SUCCESS, "wrong status %lx\n", io.Status);
730 ok(io.Information > 0 && io.Information < data_size, "wrong info %Ix\n", io.Information);
732 "wrong offset %lx\n", fbdi->NextEntryOffset );
733 ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %lx\n", fbdi->FileNameLength );
734 ok( fbdi->FileName[0] == '.', "incorrect long file name: %s\n",
735 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
737 ok( next->NextEntryOffset == ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[2] ) + 7) & ~7),
738 "wrong offset %lx\n", next->NextEntryOffset );
739 ok( next->FileNameLength == 2 * sizeof(WCHAR), "wrong length %lx\n", next->FileNameLength );
740 filename = next->FileName;
741 ok( filename[0] == '.' && filename[1] == '.', "incorrect long file name: %s\n",
742 wine_dbgstr_wn(next->FileName, next->FileNameLength/sizeof(WCHAR)));
743
745 memset( data, 0x55, data_size );
746 io.Status = 0xdeadbeef;
747 io.Information = 0xdeadbeef;
748 status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size,
750 ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
751 ok( io.Status == STATUS_SUCCESS, "wrong status %lx\n", io.Status );
753 "wrong info %Ix\n", io.Information );
754 ok( fbdi->NextEntryOffset == 0, "wrong offset %lx\n", fbdi->NextEntryOffset );
755 ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %lx\n", fbdi->FileNameLength );
756 ok( fbdi->FileName[0] == '.', "incorrect long file name: %s\n",
757 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
759 ok( next->NextEntryOffset == 0x55555555, "wrong offset %lx\n", next->NextEntryOffset );
760
762 memset( data, 0x55, data_size );
763 io.Status = 0xdeadbeef;
764 io.Information = 0xdeadbeef;
765 status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size,
767 ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
768 ok( io.Status == STATUS_SUCCESS, "wrong status %lx\n", io.Status );
770 "wrong info %Ix\n", io.Information );
771 ok( fbdi->NextEntryOffset == 0, "wrong offset %lx\n", fbdi->NextEntryOffset );
772
773 data_size = ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7) +
775 memset( data, 0x55, data_size );
776 io.Status = 0xdeadbeef;
777 io.Information = 0xdeadbeef;
778 status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size + 32,
780 ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
781 ok( io.Status == STATUS_SUCCESS, "wrong status %lx\n", io.Status );
782 ok( io.Information == data_size || io.Information == ((data_size + 7) & ~7),
783 "wrong info %Ix / %x\n", io.Information, data_size );
785 "wrong offset %lx\n", fbdi->NextEntryOffset );
786 ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %lx\n", fbdi->FileNameLength );
787 ok( fbdi->FileName[0] == '.', "incorrect long file name: %s\n",
788 wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
790 ok( next->NextEntryOffset == 0, "wrong offset %lx\n", next->NextEntryOffset );
791 ok( next->FileNameLength == 2 * sizeof(WCHAR), "wrong length %lx\n", next->FileNameLength );
792 filename = next->FileName;
793 ok( filename[0] == '.' && filename[1] == '.', "incorrect long file name: %s\n",
794 wine_dbgstr_wn(next->FileName, next->FileNameLength/sizeof(WCHAR)));
795
796 data_size = ((offsetof( FILE_NAMES_INFORMATION, FileName[1] ) + 7) & ~7) +
798 memset( data, 0x55, data_size );
799 io.Status = 0xdeadbeef;
800 io.Information = 0xdeadbeef;
801 status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size,
803 ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
804 ok( io.Status == STATUS_SUCCESS, "wrong status %lx\n", io.Status );
805 ok( io.Information == data_size, "wrong info %Ix / %x\n", io.Information, data_size );
807 ok( names->NextEntryOffset == ((offsetof( FILE_NAMES_INFORMATION, FileName[1] ) + 7) & ~7),
808 "wrong offset %lx\n", names->NextEntryOffset );
809 ok( names->FileNameLength == sizeof(WCHAR), "wrong length %lx\n", names->FileNameLength );
810 ok( names->FileName[0] == '.', "incorrect long file name: %s\n",
811 wine_dbgstr_wn(names->FileName, names->FileNameLength/sizeof(WCHAR)));
812 names = (FILE_NAMES_INFORMATION *)(data + names->NextEntryOffset);
813 ok( names->NextEntryOffset == 0, "wrong offset %lx\n", names->NextEntryOffset );
814 ok( names->FileNameLength == 2 * sizeof(WCHAR), "wrong length %lx\n", names->FileNameLength );
815 filename = names->FileName;
816 ok( filename[0] == '.' && filename[1] == '.', "incorrect long file name: %s\n",
817 wine_dbgstr_wn(names->FileName, names->FileNameLength/sizeof(WCHAR)));
818
819 pNtClose(dirh);
820
821 /* create new handle to change mask */
822 status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
824 ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA);
825
826 pRtlInitUnicodeString( &mask, dummyW );
827 io.Status = 0xdeadbeef;
828 data_size = sizeof(data);
829 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
831 ok(status == STATUS_NO_SUCH_FILE, "wrong status %lx\n", status);
832 ok(io.Status == 0xdeadbeef, "wrong status %lx\n", io.Status);
833
834 io.Status = 0xdeadbeef;
835 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
837 ok(status == STATUS_NO_MORE_FILES, "wrong status %lx\n", status);
838 ok(io.Status == STATUS_NO_MORE_FILES, "wrong status %lx\n", io.Status);
839
840 io.Status = 0xdeadbeef;
841 status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
843 ok(status == STATUS_NO_MORE_FILES, "wrong status %lx\n", status);
844 ok(io.Status == STATUS_NO_MORE_FILES, "wrong status %lx\n", io.Status);
845
846 pNtClose(dirh);
847
848 io.Status = 0xdeadbeef;
849 status = pNtQueryDirectoryFile( (HANDLE)0xbeef, 0, NULL, NULL, &io, data, data_size,
851 ok(status == STATUS_INVALID_HANDLE, "wrong status %lx\n", status);
852 ok(io.Status == 0xdeadbeef, "wrong status %lx\n", io.Status);
853
854 GetModuleFileNameA( 0, buffer, sizeof(buffer) );
856 if (h != INVALID_HANDLE_VALUE)
857 {
858 io.Status = 0xdeadbeef;
859 status = pNtQueryDirectoryFile( h, 0, NULL, NULL, &io, data, data_size,
861 ok(status == STATUS_INVALID_PARAMETER, "wrong status %lx\n", status);
862 ok(io.Status == 0xdeadbeef, "wrong status %lx\n", io.Status);
863 CloseHandle ( h );
864 }
865
866done:
867 test_directory_sort( testdirW );
868 tear_down_attribute_test( testdirW );
869 pRtlFreeUnicodeString(&ntdirname);
870}
871
872static void set_up_case_test(const char *testdir)
873{
874 BOOL ret;
875 char buf[MAX_PATH + 5];
876 HANDLE h;
877
878 ret = CreateDirectoryA(testdir, NULL);
879 ok(ret, "couldn't create dir '%s', error %ld\n", testdir, GetLastError());
880
881 sprintf(buf, "%s\\%s", testdir, "TesT");
884 ok(h != INVALID_HANDLE_VALUE, "failed to create temp file '%s'\n", buf);
885 CloseHandle(h);
886}
887
888static void tear_down_case_test(const char *testdir)
889{
890 int ret;
891 char buf[MAX_PATH];
892
893 sprintf(buf, "%s\\%s", testdir, "TesT");
896 "Failed to rm %s, error %ld\n", buf, GetLastError());
897 RemoveDirectoryA(testdir);
898}
899
901{
902 static const char testfile[] = "TesT";
903 static const WCHAR testfile_w[] = {'T','e','s','T'};
904 static int testfile_len = sizeof(testfile) - 1;
905 static WCHAR testmask[] = {'t','e','s','t'};
907 UNICODE_STRING ntdirname;
908 char testdir[MAX_PATH];
909 WCHAR testdir_w[MAX_PATH];
910 HANDLE dirh;
913 UINT data_size, data_len;
914 BYTE data[8192];
917 WCHAR *name;
918 ULONG name_len;
919
920 /* Clean up from prior aborted run, if any, then set up test files */
921 ok(GetTempPathA(MAX_PATH, testdir), "couldn't get temp dir\n");
922 strcat(testdir, "case.tmp");
923 tear_down_case_test(testdir);
924 set_up_case_test(testdir);
925
926 pRtlMultiByteToUnicodeN(testdir_w, sizeof(testdir_w), NULL, testdir, strlen(testdir) + 1);
927 if (!pRtlDosPathNameToNtPathName_U(testdir_w, &ntdirname, NULL, NULL))
928 {
929 ok(0, "RtlDosPathNametoNtPathName_U failed\n");
930 goto done;
931 }
933
935
936 status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
938 ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%lx, error %ld\n", testdir, status, GetLastError());
939 if (status != STATUS_SUCCESS)
940 {
941 skip("can't test if we can't open the directory\n");
942 return;
943 }
944
945 mask.Buffer = testmask;
946 mask.Length = mask.MaximumLength = sizeof(testmask);
947 pNtQueryDirectoryFile(dirh, NULL, NULL, NULL, &io, data, data_size,
949 ok(io.Status == STATUS_SUCCESS, "failed to query directory; status %lx\n", io.Status);
950 data_len = io.Information;
951 ok(data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n");
952
953 name = dir_info->FileName;
954 name_len = dir_info->FileNameLength / sizeof(WCHAR);
955
956 ok(name_len == testfile_len, "unexpected filename length %lu\n", name_len);
957 ok(!memcmp(name, testfile_w, testfile_len * sizeof(WCHAR)), "unexpected filename %s\n",
958 wine_dbgstr_wn(name, name_len));
959
960 pNtClose(dirh);
961
962done:
963 tear_down_case_test(testdir);
964 pRtlFreeUnicodeString(&ntdirname);
965}
966
968{
974
976 if (root)
977 {
979 status = pNtOpenFile( &attr.RootDirectory, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io,
982 if (status) return status;
983 }
984 if (name)
985 {
989 if (attr.RootDirectory) NtClose( attr.RootDirectory );
990 }
991 else handle = attr.RootDirectory;
992
993 if (!status)
994 {
995 status = pNtQueryInformationFile( handle, &io, info, sizeof(*info), FileInternalInformation );
996 NtClose( handle );
997 }
998 return status;
999}
1000
1001static void test_redirection(void)
1002{
1003 ULONG old, cur;
1005 ULONGLONG *tls64 = NULL;
1006
1007 if (!pRtlWow64EnableFsRedirection || !pRtlWow64EnableFsRedirectionEx)
1008 {
1009 skip( "Wow64 redirection not supported\n" );
1010 return;
1011 }
1012 status = pRtlWow64EnableFsRedirectionEx( FALSE, &old );
1014 {
1015 skip( "Wow64 redirection not supported\n" );
1016 return;
1017 }
1018 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
1019
1020#ifndef _WIN64
1021 if (NtCurrentTeb()->GdiBatchCount)
1022 tls64 = ((TEB64 *)NtCurrentTeb()->GdiBatchCount)->TlsSlots + WOW64_TLS_FILESYSREDIR;
1023#endif
1024
1025 status = pRtlWow64EnableFsRedirectionEx( FALSE, &cur );
1026 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
1027 ok( !cur, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
1028 if (tls64) ok( *tls64 == FALSE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
1029
1030 status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
1031 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
1032 status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
1033 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
1034 ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
1035 if (tls64) ok( *tls64 == TRUE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
1036
1037 status = pRtlWow64EnableFsRedirection( TRUE );
1038 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
1039 status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
1040 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
1041 ok( !cur, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
1042 if (tls64) ok( *tls64 == TRUE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
1043
1044 status = pRtlWow64EnableFsRedirectionEx( 123, &cur );
1045 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
1046 ok( cur == TRUE, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
1047 if (tls64) ok( *tls64 == 123, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
1048
1049 status = pRtlWow64EnableFsRedirectionEx( 0xdeadbeef, &cur );
1050 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
1051 ok( cur == 123, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
1052 if (tls64) ok( *tls64 == 0xdeadbeef, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
1053
1054 status = pRtlWow64EnableFsRedirectionEx( TRUE, NULL );
1055 ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %lx\n", status );
1056 status = pRtlWow64EnableFsRedirectionEx( TRUE, (void*)1 );
1057 ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %lx\n", status );
1058 status = pRtlWow64EnableFsRedirectionEx( TRUE, (void*)0xDEADBEEF );
1059 ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %lx\n", status );
1060
1061 status = pRtlWow64EnableFsRedirection( FALSE );
1062 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
1063 status = pRtlWow64EnableFsRedirectionEx( FALSE, &cur );
1064 ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
1065 ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
1066 if (tls64) ok( *tls64 == FALSE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
1067
1068 if (tls64)
1069 {
1070 static const struct
1071 {
1072 const WCHAR *root, *name;
1074 BOOL redirected;
1075 NTSTATUS alt;
1076 } tests[] =
1077 {
1078 { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll", STATUS_SUCCESS, TRUE },
1079 { NULL, L"\\??\\C:\\\\windows\\system32\\kernel32.dll", STATUS_SUCCESS, FALSE, STATUS_OBJECT_NAME_INVALID },
1080 { L"\\??\\C:\\", L"windows\\system32\\kernel32.dll", STATUS_SUCCESS, FALSE },
1081 { L"\\??\\C:\\windows", L"system32\\kernel32.dll", STATUS_SUCCESS, TRUE },
1082 { L"\\??\\C:\\\\windows", L"system32\\kernel32.dll", STATUS_SUCCESS, TRUE, STATUS_OBJECT_NAME_INVALID },
1083 { L"\\??\\C:\\windows\\system32", L"kernel32.dll", STATUS_SUCCESS, TRUE },
1084 { L"\\??\\C:\\windows\\system32", NULL, STATUS_SUCCESS, TRUE },
1085 { L"\\??\\C:\\windows\\system32", L"drivers\\ndis.sys", STATUS_OBJECT_NAME_NOT_FOUND, FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
1086 { L"\\??\\C:\\windows\\system32", L"drivers\\etc\\hosts", STATUS_OBJECT_PATH_NOT_FOUND },
1087 { L"\\??\\C:\\windows\\system32\\drivers", NULL, STATUS_SUCCESS, TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
1088 { L"\\??\\C:\\windows\\system32\\drivers\\etc", L"hosts", STATUS_SUCCESS, FALSE },
1089 { NULL, L"\\DosDevices\\C:\\windows\\system32\\kernel32.dll", STATUS_SUCCESS, FALSE },
1090 { L"\\DosDevices\\C:\\", L"windows\\system32\\kernel32.dll", STATUS_SUCCESS, FALSE },
1091 { L"\\DosDevices\\C:\\windows", L"system32\\kernel32.dll", STATUS_SUCCESS, TRUE },
1092 { L"\\DosDevices\\C:\\windows\\system32", L"kernel32.dll", STATUS_SUCCESS, TRUE },
1093 { L"\\DosDevices\\C:\\windows\\system32", NULL, STATUS_SUCCESS, FALSE },
1094 { L"\\DosDevices\\C:\\windows\\system32", L"drivers\\ndis.sys", STATUS_OBJECT_NAME_NOT_FOUND, FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
1095 { L"\\DosDevices\\C:\\windows\\system32", L"drivers\\etc\\hosts", STATUS_SUCCESS, FALSE },
1096 { L"\\DosDevices\\C:\\windows\\system32\\drivers", NULL, STATUS_SUCCESS, FALSE },
1097 { L"\\DosDevices\\C:\\windows\\system32\\drivers\\etc", NULL, STATUS_SUCCESS, FALSE },
1098 { NULL, L"\\??\\C:\\windows\\sysnative\\kernel32.dll", STATUS_SUCCESS, FALSE },
1099 { L"\\??\\C:\\", L"windows\\sysnative\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
1100 { L"\\??\\C:\\windows", L"sysnative\\kernel32.dll", STATUS_SUCCESS, FALSE },
1101 { L"\\??\\C:\\windows\\sysnative", L"kernel32.dll" , STATUS_SUCCESS, TRUE },
1102 { L"\\??\\C:\\windows\\sysnative", NULL, STATUS_SUCCESS, FALSE },
1103 { NULL, L"\\DosDevices\\C:\\windows\\sysnative\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
1104 { L"\\DosDevices\\C:\\", L"windows\\sysnative\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
1105 { L"\\DosDevices\\C:\\windows", L"sysnative\\kernel32.dll", STATUS_SUCCESS, FALSE },
1106 { L"\\DosDevices\\C:\\windows\\sysnative", L"kernel32.dll" , STATUS_OBJECT_NAME_NOT_FOUND },
1107 { L"\\DosDevices\\C:\\windows\\sysnative", NULL, STATUS_OBJECT_NAME_NOT_FOUND },
1108 };
1109 FILE_INTERNAL_INFORMATION info, info_redir;
1110 unsigned int i;
1111
1112 for (i = 0; i < ARRAY_SIZE(tests); i++)
1113 {
1114 pRtlWow64EnableFsRedirection( FALSE );
1116 ok( !status || status == tests[i].expect || (tests[i].alt && status == tests[i].alt),
1117 "%u: got %lx / %lx for %s + %s without redirect\n", i, status, tests[i].expect,
1119 if (status) memset( &info, 0xcc, sizeof(info) );
1120 pRtlWow64EnableFsRedirection( TRUE );
1121 status = get_file_id( &info_redir, tests[i].root, tests[i].name );
1122 ok( status == tests[i].expect || (tests[i].alt && status == tests[i].alt),
1123 "%u: got %lx / %lx for %s + %s\n", i, status, tests[i].expect,
1125 if (!status)
1126 {
1127 BOOL redirected = memcmp( &info_redir, &info, sizeof(info) );
1128 ok( !redirected == !tests[i].redirected,
1129 "%u: was %sredirected for %s + %s\n", i, redirected ? "" : "not ",
1131 }
1132 }
1133 }
1134 pRtlWow64EnableFsRedirectionEx( old, &cur );
1135}
1136
1138{
1139 WCHAR sysdir[MAX_PATH];
1140 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
1141
1142 pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
1143 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
1144 pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile");
1145 pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
1146 pNtSetInformationFile = (void *)GetProcAddress(hntdll, "NtSetInformationFile");
1147 pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
1148 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
1149 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
1150 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
1151 pRtlCompareUnicodeString = (void *)GetProcAddress(hntdll, "RtlCompareUnicodeString");
1152 pRtlMultiByteToUnicodeN = (void *)GetProcAddress(hntdll,"RtlMultiByteToUnicodeN");
1153 pRtlWow64EnableFsRedirection = (void *)GetProcAddress(hntdll,"RtlWow64EnableFsRedirection");
1154 pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll,"RtlWow64EnableFsRedirectionEx");
1155
1156 GetSystemDirectoryW( sysdir, MAX_PATH );
1157 test_directory_sort( sysdir );
1161}
#define expect_empty
Definition: CComVariant.cpp:60
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
const WCHAR * short_name
Definition: reg.c:29
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR nameW[]
Definition: main.c:49
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FileIdExtdDirectoryInformation
Definition: dirctrl.c:24
#define FileIdExtdBothDirectoryInformation
Definition: dirctrl.c:25
struct _root root
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NTSTATUS
Definition: precomp.h:19
#define CloseHandle
Definition: compat.h:739
#define OPEN_EXISTING
Definition: compat.h:775
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define lstrcpyW
Definition: compat.h:749
#define FILE_SHARE_READ
Definition: compat.h:136
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:682
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:58
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:700
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2232
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:1973
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
_ACRTIMP wchar_t *__cdecl wcspbrk(const wchar_t *, const wchar_t *)
Definition: wcs.c:2016
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_ACCESS_VIOLATION
@ FilePositionInformation
Definition: from_kernel.h:75
@ FileMaximumInformation
Definition: from_kernel.h:112
@ FileIdGlobalTxDirectoryInformation
Definition: from_kernel.h:111
@ FileQuotaInformation
Definition: from_kernel.h:93
@ FileInternalInformation
Definition: from_kernel.h:67
@ FileDirectoryInformation
Definition: from_kernel.h:62
@ FileReparsePointInformation
Definition: from_kernel.h:94
@ FileObjectIdInformation
Definition: from_kernel.h:90
@ FileIdBothDirectoryInformation
Definition: from_kernel.h:98
@ FileNamesInformation
Definition: from_kernel.h:73
@ FileFullDirectoryInformation
Definition: from_kernel.h:63
@ FileBothDirectoryInformation
Definition: from_kernel.h:64
@ FileIdFullDirectoryInformation
Definition: from_kernel.h:99
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
FxCollectionEntry * cur
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint res
Definition: glext.h:9613
GLuint GLuint * names
Definition: glext.h:11545
GLuint buffer
Definition: glext.h:5915
GLint namelen
Definition: glext.h:7232
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLboolean enable
Definition: glext.h:11120
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
const char * filename
Definition: ioapi.h:137
#define NtCurrentTeb
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define CREATE_ALWAYS
Definition: disk.h:72
static struct test_info tests[]
#define sprintf
Definition: sprintf.c:45
static ULONG
Definition: directory.c:29
static PVOID
Definition: directory.c:29
static HINSTANCE hntdll
Definition: process.c:68
static ACCESS_MASK
Definition: directory.c:41
static POBJECT_ATTRIBUTES
Definition: directory.c:41
static void tear_down_attribute_test(const WCHAR *testdir)
Definition: directory.c:133
static void test_NtQueryDirectoryFile_case(void)
Definition: directory.c:900
static ULONG * old_value
Definition: directory.c:54
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:52
static DWORD LPDWORD reslen
Definition: directory.c:51
static struct testfile_s testfiles[]
static void test_NtQueryDirectoryFile(void)
Definition: directory.c:465
static void test_redirection(void)
Definition: directory.c:1001
static const WCHAR dotdotW[]
Definition: directory.c:89
static const WCHAR dummyW[]
Definition: directory.c:87
static void reset_found_files(void)
Definition: directory.c:124
static const int max_test_dir_size
Definition: directory.c:85
static const int test_dir_count
Definition: directory.c:84
static const WCHAR dotW[]
Definition: directory.c:88
static PUNICODE_STRING
Definition: directory.c:43
static void tear_down_case_test(const char *testdir)
Definition: directory.c:888
static void test_NtQueryDirectoryFile_classes(HANDLE handle, UNICODE_STRING *mask)
Definition: directory.c:347
static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char *testdirA, UNICODE_STRING *mask, BOOLEAN single_entry, BOOLEAN restart_flag, BOOLEAN expect_empty)
Definition: directory.c:184
static const WCHAR backslashW[]
Definition: directory.c:90
static void set_up_case_test(const char *testdir)
Definition: directory.c:872
static DWORD dstlen
Definition: directory.c:51
static NTSTATUS get_file_id(FILE_INTERNAL_INFORMATION *info, const WCHAR *root, const WCHAR *name)
Definition: directory.c:967
static DWORD LPDWORD LPCSTR src
Definition: directory.c:52
static PIO_APC_ROUTINE
Definition: directory.c:42
static void set_up_attribute_test(const WCHAR *testdir)
Definition: directory.c:93
static FILE_INFORMATION_CLASS
Definition: directory.c:43
static LPCSTR
Definition: directory.c:46
static LONG
Definition: directory.c:44
static void test_directory_sort(const WCHAR *testdir)
Definition: directory.c:269
static PWSTR CURDIR *static LPCWSTR
Definition: directory.c:48
static BOOLEAN
Definition: directory.c:43
static PIO_STATUS_BLOCK
Definition: directory.c:41
static void tally_test_file(FILE_BOTH_DIRECTORY_INFORMATION *dir_info)
Definition: directory.c:160
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:72
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
int disable
Definition: msacm.c:1365
unsigned int UINT
Definition: ndis.h:50
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define BOOL
Definition: nt_native.h:43
#define GENERIC_WRITE
Definition: nt_native.h:90
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
short WCHAR
Definition: pedump.c:58
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static unsigned __int64 next
Definition: rand_nt.c:6
#define wine_dbgstr_wn
Definition: testlist.c:2
#define offsetof(TYPE, MEMBER)
strcat
Definition: string.h:92
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
WCHAR FileName[ANYSIZE_ARRAY]
Definition: winternl.h:1515
LARGE_INTEGER CurrentByteOffset
Definition: nt_native.h:958
Definition: cookie.c:202
Definition: name.c:39
Definition: ps.c:97
const char * description
Definition: directory.c:62
const char * target
Definition: directory.c:61
int nfound
Definition: directory.c:63
BOOL attr_done
Definition: directory.c:58
const DWORD attr
Definition: directory.c:59
uint16_t * PWSTR
Definition: typedefs.h:56
const char * LPCSTR
Definition: typedefs.h:52
uint16_t * LPWSTR
Definition: typedefs.h:56
PVOID HANDLE
Definition: typedefs.h:73
uint32_t * LPDWORD
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_NO_MORE_FILES
Definition: udferr_usr.h:128
LONGLONG QuadPart
Definition: typedefs.h:114
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define WOW64_TLS_FILESYSREDIR
Definition: winternl.h:1366
const char * description
Definition: directx.c:2497
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define DUPLICATE_SAME_ACCESS
unsigned char BYTE
Definition: xxhash.c:193