[PATCH 1/6] ntdll/tests: Add some tests for NtQueryDirectoryObject().

Zebediah Figura zfigura at codeweavers.com
Mon Apr 4 20:27:22 CDT 2022


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/ntdll/tests/om.c | 170 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 170 insertions(+)

diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index a0702a580b7..f18afa05ae9 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -78,6 +78,16 @@ static NTSTATUS (WINAPI *pNtCompareObjects)(HANDLE,HANDLE);
 #define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
 #define DESKTOP_ALL_ACCESS    0x01ff
 
+#define check_unicode_string(a, b) check_unicode_string_(__LINE__, a, b)
+static void check_unicode_string_( int line, const UNICODE_STRING *string, const WCHAR *expect )
+{
+    size_t len = wcslen( expect ) * sizeof(WCHAR);
+
+    ok_(__FILE__, line)( !wcscmp( string->Buffer, expect ), "got string %s\n", debugstr_w( string->Buffer ));
+    ok_(__FILE__, line)( string->Length == len, "got length %u\n", string->Length );
+    ok_(__FILE__, line)( string->MaximumLength == len + sizeof(WCHAR), "got max length %u\n", string->MaximumLength );
+}
+
 static void test_case_sensitive (void)
 {
     NTSTATUS status;
@@ -2500,6 +2510,165 @@ static void test_object_identity(void)
     pNtClose( h1 );
 }
 
+static void test_query_directory(void)
+{
+    char buffer[200];
+    DIRECTORY_BASIC_INFORMATION *info = (void *)buffer;
+    ULONG context, size, needed_size;
+    HANDLE dir, child1, child2;
+    OBJECT_ATTRIBUTES attr;
+    UNICODE_STRING string;
+    NTSTATUS status;
+
+    RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest" );
+    InitializeObjectAttributes( &attr, &string, 0, 0, NULL );
+    status = NtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
+    ok( !status, "got %#x\n", status );
+
+    context = 0xdeadbeef;
+    size = 0xdeadbeef;
+    status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
+    ok( status == STATUS_NO_MORE_ENTRIES, "got %#x\n", status );
+    todo_wine ok( context == 0xdeadbeef, "got context %#x\n", context );
+    todo_wine ok( !size, "got size %u\n", size );
+
+    RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest\\Telamon" );
+    status = NtCreateMutant( &child1, GENERIC_ALL, &attr, FALSE );
+    ok( !status, "got %#x\n", status );
+
+    RtlInitUnicodeString( &string, L"\\BaseNamedObjects\\winetest\\Oileus" );
+    status = NtCreateMutant( &child2, GENERIC_ALL, &attr, FALSE );
+    ok( !status, "got %#x\n", status );
+
+    status = NtQueryDirectoryObject( NULL, info, sizeof(buffer), TRUE, TRUE, &context, &size );
+    ok( status == STATUS_INVALID_HANDLE, "got %#x\n", status );
+
+    status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, NULL, &size );
+    ok( status == STATUS_ACCESS_VIOLATION, "got %#x\n", status );
+
+    context = 0xdeadbeef;
+    size = 0xdeadbeef;
+    memset( buffer, 0xcc, sizeof(buffer) );
+    status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
+    ok( !status, "got %#x\n", status );
+    ok( context == 1, "got context %#x\n", context );
+    ok( size && size < sizeof(buffer), "got size %u\n", size );
+    check_unicode_string( &info[0].ObjectName, L"Oileus" );
+    check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
+    todo_wine
+    {
+        ok( !info[1].ObjectName.Buffer, "got string %p\n", info[1].ObjectName.Buffer );
+        ok( !info[1].ObjectName.Length, "got length %u\n", info[1].ObjectName.Length );
+        ok( !info[1].ObjectName.MaximumLength, "got max length %u\n", info[1].ObjectName.MaximumLength );
+        ok( !info[1].ObjectTypeName.Buffer, "got string %p\n", info[1].ObjectName.Buffer );
+        ok( !info[1].ObjectTypeName.Length, "got length %u\n", info[1].ObjectTypeName.Length );
+        ok( !info[1].ObjectTypeName.MaximumLength, "got max length %u\n", info[1].ObjectTypeName.MaximumLength );
+    }
+
+    memset( buffer, 0xcc, sizeof(buffer) );
+    status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
+    ok( !status, "got %#x\n", status );
+    ok( context == 2, "got context %#x\n", context );
+    check_unicode_string( &info[0].ObjectName, L"Telamon" );
+    check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
+    todo_wine ok( !info[1].ObjectName.Buffer, "got string %p\n", info[1].ObjectName.Buffer );
+
+    size = 0xdeadbeef;
+    memset( buffer, 0xcc, sizeof(buffer) );
+    status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
+    ok( status == STATUS_NO_MORE_ENTRIES, "got %#x\n", status );
+    ok( context == 2, "got context %#x\n", context );
+    todo_wine ok( !size, "got size %u\n", size );
+
+    memset( buffer, 0xcc, sizeof(buffer) );
+    status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, &size );
+    ok( !status, "got %#x\n", status );
+    ok( context == 1, "got context %#x\n", context );
+    check_unicode_string( &info[0].ObjectName, L"Oileus" );
+    check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
+    todo_wine ok( !info[1].ObjectName.Buffer, "got string %p\n", info[1].ObjectName.Buffer );
+
+    needed_size = size;
+
+    size = 0xdeadbeef;
+    context = 0xdeadbeef;
+    status = NtQueryDirectoryObject( dir, info, 0, TRUE, TRUE, &context, &size );
+    todo_wine ok( status == STATUS_BUFFER_TOO_SMALL, "got %#x\n", status );
+    todo_wine ok( context == 0xdeadbeef, "got context %#x\n", context );
+    todo_wine ok( size == needed_size, "expected size %u, got %u\n", needed_size, size );
+
+    size = 0xdeadbeef;
+    memset( buffer, 0xcc, sizeof(buffer) );
+    status = NtQueryDirectoryObject( dir, info, needed_size - 1, TRUE, TRUE, &context, &size );
+    todo_wine ok( status == STATUS_BUFFER_TOO_SMALL, "got %#x\n", status );
+    todo_wine ok( size == needed_size, "expected size %u, got %u\n", needed_size, size );
+    ok( info[0].ObjectName.Length == 0xcccc, "got length %u\n", info[0].ObjectName.Length );
+
+    status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, TRUE, &context, NULL );
+    ok( !status, "got %#x\n", status );
+
+    context = 0;
+    memset( buffer, 0xcc, sizeof(buffer) );
+    status = NtQueryDirectoryObject( dir, info, sizeof(buffer), TRUE, FALSE, &context, &size );
+    ok( !status, "got %#x\n", status );
+    ok( context == 1, "got context %#x\n", context );
+    check_unicode_string( &info[0].ObjectName, L"Oileus" );
+    check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
+    todo_wine ok( !info[1].ObjectName.Buffer, "got string %p\n", info[1].ObjectName.Buffer );
+
+    memset( buffer, 0xcc, sizeof(buffer) );
+    status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, TRUE, &context, &size );
+    todo_wine ok( !status, "got %#x\n", status );
+    if (!status)
+    {
+        ok( context == 2, "got context %#x\n", context );
+        check_unicode_string( &info[0].ObjectName, L"Oileus" );
+        check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
+        check_unicode_string( &info[1].ObjectName, L"Telamon" );
+        check_unicode_string( &info[1].ObjectTypeName, L"Mutant" );
+        ok( !info[2].ObjectName.Buffer, "got string %p\n", info[2].ObjectName.Buffer );
+    }
+
+    needed_size = size;
+    size = 0xdeadbeef;
+    context = 0xdeadbeef;
+    memset( buffer, 0xcc, sizeof(buffer) );
+    status = NtQueryDirectoryObject( dir, info, needed_size - 1, FALSE, TRUE, &context, &size );
+    todo_wine ok( status == STATUS_MORE_ENTRIES, "got %#x\n", status );
+    if (status == STATUS_MORE_ENTRIES)
+    {
+        ok( context == 1, "got context %#x\n", context );
+        ok( size > 0 && size < needed_size, "got size %u\n", size );
+        check_unicode_string( &info[0].ObjectName, L"Oileus" );
+        check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
+        ok( !info[1].ObjectName.Buffer, "got string %p\n", info[1].ObjectName.Buffer );
+
+        context = 0xdeadbeef;
+        memset( buffer, 0xcc, sizeof(buffer) );
+        status = NtQueryDirectoryObject( dir, info, size - 1, FALSE, TRUE, &context, &size );
+        todo_wine ok( status == STATUS_BUFFER_TOO_SMALL, "got %#x\n", status );
+        todo_wine ok( context == 0xdeadbeef, "got context %#x\n", context );
+        todo_wine ok( size == needed_size, "expected size %u, got %u\n", needed_size, size );
+        ok( info[0].ObjectName.Length == 0xcccc, "got length %u\n", info[0].ObjectName.Length );
+    }
+
+    context = 1;
+    memset( buffer, 0xcc, sizeof(buffer) );
+    status = NtQueryDirectoryObject( dir, info, sizeof(buffer), FALSE, FALSE, &context, &size );
+    todo_wine ok( !status, "got %#x\n", status );
+    if (!status)
+    {
+        ok( context == 2, "got context %#x\n", context );
+        check_unicode_string( &info[0].ObjectName, L"Telamon" );
+        check_unicode_string( &info[0].ObjectTypeName, L"Mutant" );
+        ok( !info[1].ObjectName.Buffer, "got string %p\n", info[1].ObjectName.Buffer );
+    }
+
+    NtClose( child1 );
+    NtClose( child2 );
+    NtClose( dir );
+}
+
 START_TEST(om)
 {
     HMODULE hntdll = GetModuleHandleA("ntdll.dll");
@@ -2561,4 +2730,5 @@ START_TEST(om)
     test_get_next_thread();
     test_globalroot();
     test_object_identity();
+    test_query_directory();
 }
-- 
2.35.1




More information about the wine-devel mailing list