Skip to content

Commit

Permalink
10.0-rc3-4 patchset
Browse files Browse the repository at this point in the history
Added ntsync7 (+esync/fsync)
 - Removed a few incompatible/hard to rebase patches (goodbye again threaded server)
 - Thank you @loathingKernel for much of the hard work
WINE_DISABLE_FAST_SYNC=1 to use esync/fsync instead
 - Need WINEFSYNC=0 and WINEESYNC=0 explicitly set as well to use wineserver sync
Add WIP WoW64 MR for some 32-bit games

Merry Christmas :)
  • Loading branch information
whrvt committed Dec 25, 2024
1 parent 0044162 commit 67022f1
Show file tree
Hide file tree
Showing 295 changed files with 12,723 additions and 3,628 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
From 58aef4d41bbf3ed4e1335346ed508f1bebf8bca7 Mon Sep 17 00:00:00 2001
From: Eugene McArdle <[email protected]>
Date: Thu, 19 Dec 2024 09:59:53 +1000
Subject: [PATCH] ntdll: Test updated NtQueryDirectoryFile mask reset behaviour

---
dlls/ntdll/tests/directory.c | 240 +++++++++++++++++++++++++++++++++++
1 file changed, 240 insertions(+)

diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c
index 52ff9936560..6aec2ff6408 100644
--- a/dlls/ntdll/tests/directory.c
+++ b/dlls/ntdll/tests/directory.c
@@ -964,6 +964,245 @@ done:
pRtlFreeUnicodeString(&ntdirname);
}

+static void set_up_mask_test(const char *testdir)
+{
+ BOOL ret;
+ char buf[MAX_PATH + 5];
+ HANDLE h;
+
+ ret = CreateDirectoryA(testdir, NULL);
+ ok( ret, "couldn't create dir '%s', error %ld\n", testdir, GetLastError() );
+
+ sprintf(buf, "%s\\%s", testdir, "a-file.h");
+ h = CreateFileA(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ ok( h != INVALID_HANDLE_VALUE, "failed to create temp file '%s'\n", buf );
+ CloseHandle(h);
+
+ sprintf(buf, "%s\\%s", testdir, "another-file.h");
+ h = CreateFileA(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ ok( h != INVALID_HANDLE_VALUE, "failed to create temp file '%s'\n", buf );
+ CloseHandle(h);
+}
+
+static void tear_down_mask_test(const char *testdir)
+{
+ int ret;
+ char buf[MAX_PATH];
+
+ sprintf(buf, "%s\\%s", testdir, "a-file.h");
+ ret = DeleteFileA(buf);
+ ok( ret || (GetLastError() == ERROR_FILE_NOT_FOUND) || (GetLastError() == ERROR_PATH_NOT_FOUND),
+ "Failed to rm %s, error %ld\n", buf, GetLastError() );
+
+ sprintf(buf, "%s\\%s", testdir, "another-file.h");
+ ret = DeleteFileA(buf);
+ ok( ret || (GetLastError() == ERROR_FILE_NOT_FOUND) || (GetLastError() == ERROR_PATH_NOT_FOUND),
+ "Failed to rm %s, error %ld\n", buf, GetLastError() );
+
+ RemoveDirectoryA(testdir);
+}
+
+
+/* Performs a query with NtQueryDirectoryFile() */
+static BOOL test_NtQueryDirectoryFile_mask(HANDLE handle, BOOL restart_scan, UNICODE_STRING *mask,
+ NTSTATUS expected_status, BOOL check_name_and_length, BOOL validate_only)
+{
+ NTSTATUS status;
+ IO_STATUS_BLOCK io;
+ UINT data_size = sizeof(FILE_DIRECTORY_INFORMATION) + (MAX_PATH * sizeof(wchar_t));
+ BYTE data[8192];
+ FILE_DIRECTORY_INFORMATION *dir_info;
+ WCHAR *name;
+ ULONG name_len;
+ WCHAR *mask_value = {0};
+ ULONG mask_len = 0;
+
+ if (mask)
+ {
+ mask_len = mask->Length / sizeof(WCHAR);
+ mask_value = mask->Buffer;
+ }
+
+ /* Perform the query */
+ status = pNtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, data, data_size,
+ FileDirectoryInformation, TRUE, mask, restart_scan );
+
+ if (validate_only && status != expected_status) return FALSE;
+
+ todo_wine
+ ok( status == expected_status, "unexpected status : 0x%lx Test settings: file mask: '%s', restart: %d, expected status: 0x%lx\n",
+ status, wine_dbgstr_wn(mask_value, mask_len), restart_scan, expected_status );
+
+ /* Verify the results if required */
+ if (status == 0 && check_name_and_length)
+ {
+ dir_info = (FILE_DIRECTORY_INFORMATION *)data;
+ name = dir_info->FileName;
+ name_len = dir_info->FileNameLength / sizeof(WCHAR);
+
+ todo_wine
+ ok( name_len == mask_len, "unexpected filename length %lu, expected %lu\n", name_len, mask_len );
+ todo_wine
+ ok( !memcmp(name, mask_value, mask_len), "unexpected filename %s, expected %s\n",
+ wine_dbgstr_wn(name, name_len), wine_dbgstr_wn(mask_value, mask_len) );
+ }
+ return TRUE;
+}
+
+static void test_NtQueryDirectoryFile_change_mask(void)
+{
+ NTSTATUS status;
+ HANDLE dirh;
+ HANDLE dirh_test_multiple_handles;
+ HANDLE dirh_test_fresh_null;
+ HANDLE dirh_test_fresh_empty;
+ char testdir[MAX_PATH];
+ OBJECT_ATTRIBUTES attr;
+ IO_STATUS_BLOCK io;
+ UNICODE_STRING ntdirname;
+ WCHAR testdir_w[MAX_PATH];
+
+ UNICODE_STRING atestfile;
+ UNICODE_STRING anothertestfile;
+ UNICODE_STRING notatestfile;
+ UNICODE_STRING testmask;
+ UNICODE_STRING emptymask;
+
+ pRtlInitUnicodeString(&atestfile, L"a-file.h");
+ pRtlInitUnicodeString(&anothertestfile, L"another-file.h");
+ pRtlInitUnicodeString(&notatestfile, L"not-a-file.h");
+ pRtlInitUnicodeString(&testmask, L"*.h");
+ pRtlInitUnicodeString(&emptymask, L"");
+
+ /* Clean up from prior aborted run, if any, then set up test files */
+ ok( GetTempPathA(MAX_PATH, testdir), "couldn't get temp dir\n" );
+ strcat(testdir, "mask.tmp");
+ tear_down_mask_test(testdir);
+ set_up_mask_test(testdir);
+
+ pRtlMultiByteToUnicodeN(testdir_w, sizeof(testdir_w), NULL, testdir, strlen(testdir) + 1);
+ if (!pRtlDosPathNameToNtPathName_U(testdir_w, &ntdirname, NULL, NULL))
+ {
+ ok( 0, "RtlDosPathNametoNtPathName_U failed\n" );
+ goto done;
+ }
+ InitializeObjectAttributes(&attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL);
+
+ /* Open a handle for our test directory */
+ status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE);
+ ok( status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%lx, error %ld\n", testdir, status, GetLastError() );
+ if (status != STATUS_SUCCESS)
+ {
+ skip("can't test if we can't open the directory\n");
+ goto done;
+ }
+
+ /* Open a handle for our test directory to test multiple handles */
+ status = pNtOpenFile(&dirh_test_multiple_handles, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE);
+ ok( status == STATUS_SUCCESS, "failed to open second handle to dir '%s', ret 0x%lx, error %ld\n", testdir, status, GetLastError() );
+ if (status != STATUS_SUCCESS)
+ {
+ skip("can't test if we can't open a second handle to the directory\n");
+ goto done;
+ }
+
+ /* Open a handle for our test directory to test null masks with a fresh handle */
+ status = pNtOpenFile(&dirh_test_fresh_null, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE);
+ ok( status == STATUS_SUCCESS, "failed to open handle to dir '%s' for testing NULL masks, ret 0x%lx, error %ld\n", testdir, status, GetLastError() );
+ if (status != STATUS_SUCCESS)
+ {
+ skip("can't test NULL masks if we can't open an additional handle to the directory\n");
+ goto done;
+ }
+
+ /* Open a handle for our test directory to test empty masks with a fresh handle */
+ status = pNtOpenFile(&dirh_test_fresh_empty, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE);
+ ok( status == STATUS_SUCCESS, "failed to open handle to dir '%s' for testing empty masks, ret 0x%lx, error %ld\n", testdir, status, GetLastError() );
+ if (status != STATUS_SUCCESS)
+ {
+ skip("can't test empty masks if we can't open an additional handle to the directory\n");
+ goto done;
+ }
+
+ /* Verify that NtQueryDirectoryFile mask reset behaviour introduced in Windows 8 is supported */
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &atestfile, STATUS_SUCCESS, TRUE, TRUE);
+ if (!winetest_platform_is_wine && !test_NtQueryDirectoryFile_mask(dirh, TRUE, &notatestfile, STATUS_NO_MORE_FILES, TRUE, TRUE))
+ {
+ skip("Win8+ NtQueryDirectoryFile mask reset behaviour not supported\n");
+ goto done;
+ }
+
+ /* Test that caches for two handles to a single directory do not interfere with each other*/
+ /* Search for a non-existent file, putting it into a state with an empty cache */
+ /* This also confirms that using a non-existent mask with a fresh handle returns a different status*/
+ test_NtQueryDirectoryFile_mask(dirh_test_multiple_handles, TRUE, &notatestfile, STATUS_NO_SUCH_FILE, TRUE, FALSE);
+ /* Confirm that handle is in a state where it fails to find atestfile */
+ test_NtQueryDirectoryFile_mask(dirh_test_multiple_handles, FALSE, &atestfile, STATUS_NO_MORE_FILES, TRUE, FALSE);
+ /* Confirm that another handle is able to find atestfile */
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &atestfile, STATUS_SUCCESS, TRUE, FALSE);
+
+ /* All searches for `notatestfile` are expected to fail */
+ /* Tests should also fail if the scan is not reset, and the mask changes to an incompatible one */
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &atestfile, STATUS_SUCCESS, TRUE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &anothertestfile, STATUS_SUCCESS, TRUE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &notatestfile, STATUS_NO_MORE_FILES, TRUE, FALSE);
+
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &atestfile, STATUS_SUCCESS, TRUE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, FALSE, &notatestfile, STATUS_NO_MORE_FILES, TRUE, FALSE);
+
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &atestfile, STATUS_SUCCESS, TRUE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, FALSE, &anothertestfile, STATUS_NO_MORE_FILES, TRUE, FALSE);
+
+ /* Test mask that matches multiple files, do not check results against the mask */
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &testmask, STATUS_SUCCESS, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, FALSE, &notatestfile, STATUS_SUCCESS, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &notatestfile, STATUS_NO_MORE_FILES, FALSE, FALSE);
+
+ /* Test NULL mask with a previously used handle that last returned an error */
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, NULL, STATUS_NO_MORE_FILES, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, FALSE, NULL, STATUS_NO_MORE_FILES, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, NULL, STATUS_NO_MORE_FILES, FALSE, FALSE);
+
+ /* Test NULL mask with a previously used handle that last returned STATUS_SUCCESS */
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &testmask, STATUS_SUCCESS, FALSE, TRUE);
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, NULL, STATUS_SUCCESS, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, FALSE, NULL, STATUS_SUCCESS, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, NULL, STATUS_SUCCESS, FALSE, FALSE);
+
+ /* Test NULL mask with a fresh handle */
+ test_NtQueryDirectoryFile_mask(dirh_test_fresh_null, TRUE, NULL, STATUS_SUCCESS, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh_test_fresh_null, FALSE, NULL, STATUS_SUCCESS, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh_test_fresh_null, TRUE, NULL, STATUS_SUCCESS, FALSE, FALSE);
+
+ /* Test empty mask with a previously used handle that last returned an error */
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &notatestfile, STATUS_NO_MORE_FILES, FALSE, TRUE);
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &emptymask, STATUS_NO_MORE_FILES, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, FALSE, &emptymask, STATUS_NO_MORE_FILES, FALSE, FALSE);
+
+ /* Test empty mask with a previously used handle that last returned STATUS_SUCCESS */
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &testmask, STATUS_SUCCESS, FALSE, TRUE);
+ test_NtQueryDirectoryFile_mask(dirh, TRUE, &emptymask, STATUS_SUCCESS, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh, FALSE, &emptymask, STATUS_SUCCESS, FALSE, FALSE);
+
+ /* Test empty mask with a fresh handle */
+ test_NtQueryDirectoryFile_mask(dirh_test_fresh_empty, TRUE, &emptymask, STATUS_SUCCESS, FALSE, FALSE);
+ test_NtQueryDirectoryFile_mask(dirh_test_fresh_empty, FALSE, &emptymask, STATUS_SUCCESS, FALSE, FALSE);
+
+ /* Cleanup */
+done:
+ tear_down_mask_test(testdir);
+ pRtlFreeUnicodeString(&ntdirname);
+ pRtlFreeUnicodeString(&atestfile);
+ pRtlFreeUnicodeString(&anothertestfile);
+ pRtlFreeUnicodeString(&notatestfile);
+}
+
static NTSTATUS get_file_id( FILE_INTERNAL_INFORMATION *info, const WCHAR *root, const WCHAR *name )
{
OBJECT_ATTRIBUTES attr;
@@ -1157,5 +1396,6 @@ START_TEST(directory)
test_directory_sort( sysdir );
test_NtQueryDirectoryFile();
test_NtQueryDirectoryFile_case();
+ test_NtQueryDirectoryFile_change_mask();
test_redirection();
}
--
GitLab

Loading

0 comments on commit 67022f1

Please sign in to comment.