mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 11:04:10 +00:00
ntdll/tests: Add a bunch of tests for creating kernel objects with the names containing '\0'.
As the tests show after creating a kernel object with name "wine_test\0" it's possible to only open it as "wine_test\0", an attempt opening it as "wine_test" fails with STATUS_OBJECT_NAME_NOT_FOUND, and vice versa. Also the tests show that "wine\0test" is a valid kernel object name. Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bfec2a6637
commit
9d9b564e4b
|
@ -1580,7 +1580,8 @@ static void _test_object_name( unsigned line, HANDLE handle, const WCHAR *expect
|
|||
ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status );
|
||||
ok_(__FILE__,line)( len >= sizeof(OBJECT_NAME_INFORMATION) + str->Length, "unexpected len %lu\n", len );
|
||||
todo_wine_if (todo)
|
||||
ok_(__FILE__,line)(compare_unicode_string( str, expected_name ), "wrong name %s\n", debugstr_w( str->Buffer ));
|
||||
ok_(__FILE__,line)(compare_unicode_string( str, expected_name ), "got %s, expected %s\n",
|
||||
debugstr_w(str->Buffer), debugstr_w(expected_name));
|
||||
}
|
||||
|
||||
static void test_query_object(void)
|
||||
|
@ -2722,6 +2723,352 @@ static void test_query_directory(void)
|
|||
pNtClose( dir );
|
||||
}
|
||||
|
||||
#define test_object_name_with_null(a,b) _test_object_name_with_null(__LINE__,a,b)
|
||||
static void _test_object_name_with_null(unsigned line, HANDLE handle, UNICODE_STRING *expect)
|
||||
{
|
||||
char buffer[1024];
|
||||
UNICODE_STRING *str = (UNICODE_STRING *)buffer;
|
||||
ULONG len = 0;
|
||||
NTSTATUS status;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
status = pNtQueryObject(handle, ObjectNameInformation, buffer, sizeof(buffer), &len);
|
||||
ok_(__FILE__,line)(status == STATUS_SUCCESS, "got %08lx\n", status);
|
||||
ok_(__FILE__,line)(len >= sizeof(OBJECT_NAME_INFORMATION) + str->Length, "got %lu\n", len);
|
||||
ok_(__FILE__,line)(str->Length == expect->Length, "got %u, expected %u\n", str->Length, expect->Length);
|
||||
ok_(__FILE__,line)(!wcsnicmp(str->Buffer, expect->Buffer, str->Length/sizeof(WCHAR)), "got %s, expected %s\n",
|
||||
debugstr_w(str->Buffer), debugstr_w(expect->Buffer));
|
||||
}
|
||||
|
||||
static void test_null_in_object_name(void)
|
||||
{
|
||||
WCHAR name[256], name3[256], *p, *name_exp, *name3_exp;
|
||||
HANDLE handle, handle2;
|
||||
NTSTATUS status;
|
||||
OBJECT_ATTRIBUTES attr, attr2, attr3;
|
||||
UNICODE_STRING nameU, name2U, name3U, name2U_exp, name3U_exp;
|
||||
LARGE_INTEGER size;
|
||||
#ifndef _WIN64
|
||||
BOOL is_wow64 = FALSE;
|
||||
#endif
|
||||
|
||||
trace("running as %d bit\n", (int)sizeof(void *) * 8);
|
||||
|
||||
swprintf(name, ARRAY_SIZE(name), L"\\Sessions\\%u\\BaseNamedObjects\\wine_test", NtCurrentTeb()->Peb->SessionId);
|
||||
swprintf(name3, ARRAY_SIZE(name3), L"\\Sessions\\%u\\BaseNamedObjects\\wine_test", NtCurrentTeb()->Peb->SessionId);
|
||||
p = wcsrchr(name3, '\\');
|
||||
p[5] = 0; /* => \\wine\0test */
|
||||
|
||||
RtlInitUnicodeString(&nameU, name);
|
||||
InitializeObjectAttributes(&attr, &nameU, 0, 0, NULL);
|
||||
|
||||
name2U = nameU;
|
||||
name2U.Length += sizeof(WCHAR); /* add terminating \0 to string length */
|
||||
InitializeObjectAttributes(&attr2, &name2U, 0, 0, NULL);
|
||||
|
||||
name3U = nameU;
|
||||
name3U.Buffer = name3;
|
||||
InitializeObjectAttributes(&attr3, &name3U, 0, 0, NULL);
|
||||
|
||||
status = pNtCreateEvent(&handle, GENERIC_ALL, &attr, NotificationEvent, FALSE);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle, name, FALSE);
|
||||
status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle2, name, FALSE);
|
||||
pNtClose(handle2);
|
||||
status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateEvent(&handle, GENERIC_ALL, &attr2, NotificationEvent, FALSE);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U);
|
||||
status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name2U);
|
||||
pNtClose(handle2);
|
||||
status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr);
|
||||
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateEvent(&handle, GENERIC_ALL, &attr3, NotificationEvent, FALSE);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U);
|
||||
status = pNtOpenEvent(&handle2, GENERIC_ALL, &attr3);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name3U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
|
||||
status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle, name, FALSE);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr2, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateDebugObject(&handle, GENERIC_ALL, &attr3, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U);
|
||||
pNtClose(handle);
|
||||
|
||||
status = pNtCreateMutant(&handle, GENERIC_ALL, &attr, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle, name, FALSE);
|
||||
status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle2, name, FALSE);
|
||||
pNtClose(handle2);
|
||||
status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateMutant(&handle, GENERIC_ALL, &attr2, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U);
|
||||
status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name2U);
|
||||
pNtClose(handle2);
|
||||
status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr);
|
||||
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateMutant(&handle, GENERIC_ALL, &attr3, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U);
|
||||
status = pNtOpenMutant(&handle2, GENERIC_ALL, &attr3);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name3U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
|
||||
status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr, 1, 2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle, name, FALSE);
|
||||
status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle2, name, FALSE);
|
||||
pNtClose(handle2);
|
||||
status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr2, 1, 2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U);
|
||||
status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name2U);
|
||||
pNtClose(handle2);
|
||||
status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr);
|
||||
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateSemaphore(&handle, GENERIC_ALL, &attr3, 1, 2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U);
|
||||
status = pNtOpenSemaphore(&handle2, GENERIC_ALL, &attr3);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name3U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
|
||||
status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle, name, FALSE);
|
||||
status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle2, name, FALSE);
|
||||
pNtClose(handle2);
|
||||
status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr2, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U);
|
||||
status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name2U);
|
||||
pNtClose(handle2);
|
||||
status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr);
|
||||
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateKeyedEvent(&handle, GENERIC_ALL, &attr3, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U);
|
||||
status = pNtOpenKeyedEvent(&handle2, GENERIC_ALL, &attr3);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name3U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
|
||||
status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle, name, FALSE);
|
||||
status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle2, name, FALSE);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr2, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U);
|
||||
status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name2U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateIoCompletion(&handle, GENERIC_ALL, &attr3, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U);
|
||||
status = pNtOpenIoCompletion(&handle2, GENERIC_ALL, &attr3);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name3U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
|
||||
status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle, name, FALSE);
|
||||
status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle2, name, FALSE);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U);
|
||||
status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name2U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateJobObject(&handle, GENERIC_ALL, &attr3);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U);
|
||||
status = pNtOpenJobObject(&handle2, GENERIC_ALL, &attr3);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name3U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
|
||||
status = pNtCreateTimer(&handle, GENERIC_ALL, &attr, NotificationTimer);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle, name, FALSE);
|
||||
status = pNtOpenTimer(&handle2, GENERIC_ALL, &attr);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle2, name, FALSE);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateTimer(&handle, GENERIC_ALL, &attr2, NotificationTimer);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U);
|
||||
status = pNtOpenTimer(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name2U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateTimer(&handle, GENERIC_ALL, &attr3, NotificationTimer);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U);
|
||||
status = pNtOpenTimer(&handle2, GENERIC_ALL, &attr3);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name3U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
|
||||
size.QuadPart = 4096;
|
||||
status = pNtCreateSection(&handle, GENERIC_ALL, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle, name, FALSE);
|
||||
status = pNtOpenSection(&handle2, GENERIC_ALL, &attr);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle2, name, FALSE);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateSection(&handle, GENERIC_ALL, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U);
|
||||
status = pNtOpenSection(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name2U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateSection(&handle, GENERIC_ALL, &attr3, &size, PAGE_READWRITE, SEC_COMMIT, 0);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U);
|
||||
status = pNtOpenSection(&handle2, GENERIC_ALL, &attr3);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle2, &name3U);
|
||||
pNtClose(handle2);
|
||||
pNtClose(handle);
|
||||
|
||||
wcscpy(name, L"\\Registry\\Machine\\Software\\wine_test");
|
||||
wcscpy(name3, L"\\Registry\\Machine\\Software\\wine_test");
|
||||
p = wcsrchr(name3, '\\');
|
||||
p[5] = 0; /* => \\wine\0test */
|
||||
|
||||
RtlInitUnicodeString(&nameU, name);
|
||||
name2U = nameU;
|
||||
name3U = nameU;
|
||||
name3U.Buffer = name3;
|
||||
#ifdef _WIN64
|
||||
name_exp = name;
|
||||
name3_exp = name3;
|
||||
name2U_exp = name2U;
|
||||
#else
|
||||
if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)
|
||||
{
|
||||
name_exp = (WCHAR *)L"\\Registry\\Machine\\Software\\WOW6432Node\\wine_test";
|
||||
name3_exp =(WCHAR *) L"\\Registry\\Machine\\Software\\WOW6432Node\\wine\0test";
|
||||
}
|
||||
else
|
||||
{
|
||||
name_exp = name;
|
||||
name3_exp = name3;
|
||||
}
|
||||
RtlInitUnicodeString(&name2U_exp, name_exp);
|
||||
#endif
|
||||
name3U_exp = name2U_exp;
|
||||
name3U_exp.Buffer = name3_exp;
|
||||
name2U.Length += sizeof(WCHAR); /* add terminating \0 to string length */
|
||||
name2U_exp.Length += sizeof(WCHAR); /* add terminating \0 to string length */
|
||||
|
||||
status = pNtCreateKey(&handle, GENERIC_ALL, &attr, 0, NULL, 0, NULL);
|
||||
ok(!status || status == STATUS_ACCESS_DENIED || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* win8 */, "got %08lx\n", status);
|
||||
if (!status)
|
||||
{
|
||||
test_object_name(handle, name_exp, FALSE);
|
||||
status = pNtOpenKey(&handle2, GENERIC_ALL, &attr);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name(handle2, name_exp, FALSE);
|
||||
pNtClose(handle2);
|
||||
status = pNtOpenKey(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
|
||||
pNtDeleteKey(handle);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateKey(&handle, GENERIC_ALL, &attr2, 0, NULL, 0, NULL);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U_exp);
|
||||
status = pNtOpenKey(&handle2, GENERIC_ALL, &attr2);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name2U_exp);
|
||||
pNtClose(handle2);
|
||||
status = pNtOpenKey(&handle2, GENERIC_ALL, &attr);
|
||||
ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %08lx\n", status);
|
||||
pNtDeleteKey(handle);
|
||||
pNtClose(handle);
|
||||
status = pNtCreateKey(&handle, GENERIC_ALL, &attr3, 0, NULL, 0, NULL);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U_exp);
|
||||
status = pNtOpenKey(&handle2, GENERIC_ALL, &attr3);
|
||||
ok(!status, "got %08lx\n", status);
|
||||
test_object_name_with_null(handle, &name3U_exp);
|
||||
pNtClose(handle2);
|
||||
pNtDeleteKey(handle);
|
||||
pNtClose(handle);
|
||||
}
|
||||
else
|
||||
skip("Limited access to \\Registry\\Machine\\Software key, skipping the tests\n");
|
||||
}
|
||||
|
||||
START_TEST(om)
|
||||
{
|
||||
HMODULE hntdll = GetModuleHandleA("ntdll.dll");
|
||||
|
@ -2767,6 +3114,7 @@ START_TEST(om)
|
|||
pNtDuplicateObject = (void *)GetProcAddress(hntdll, "NtDuplicateObject");
|
||||
pNtCompareObjects = (void *)GetProcAddress(hntdll, "NtCompareObjects");
|
||||
|
||||
test_null_in_object_name();
|
||||
test_case_sensitive();
|
||||
test_namespace_pipe();
|
||||
test_name_collisions();
|
||||
|
|
Loading…
Reference in a new issue