From: Jinoh Kang jinoh.kang.kr@gmail.com
--- dlls/ntdll/tests/pipe.c | 137 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+)
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index 0ad09daaa82..d85678f1226 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -2658,6 +2658,142 @@ static void test_empty_name(void) CloseHandle(hdirectory); }
+struct pipe_name_test { + const WCHAR *name; + NTSTATUS status; + const WCHAR *no_open_name; +}; + +struct pipe_name_test_modifier { + ULONG attributes; +}; + +static void subtest_exotic_pipe_name(PUNICODE_STRING name_prefix, + const struct pipe_name_test_modifier *pntm, + const struct pipe_name_test *pnt) +{ + OBJECT_ATTRIBUTES attr; + LARGE_INTEGER timeout; + IO_STATUS_BLOCK iosb; + HANDLE pipe, client; + UNICODE_STRING name; + WCHAR namebuf[512]; + NTSTATUS status; + + name.Length = 0; + name.MaximumLength = sizeof(namebuf); + name.Buffer = namebuf; + + status = RtlAppendUnicodeStringToString(&name, name_prefix); + ok(status == STATUS_SUCCESS, "Expected success, got %#lx\n", status); + + if (pnt->name) + { + status = RtlAppendUnicodeToString(&name, L"\"); + ok(status == STATUS_SUCCESS, "Expected success, got %#lx\n", status); + + status = RtlAppendUnicodeToString(&name, pnt->name); + ok(status == STATUS_SUCCESS, "Expected success, got %#lx\n", status); + } + + InitializeObjectAttributes(&attr, &name, pntm->attributes, NULL, NULL); + timeout.QuadPart = -100000000; + pipe = NULL; + status = pNtCreateNamedPipeFile(&pipe, + GENERIC_READ | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, + &attr, &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, + 0, 0, 0, 3, 4096, 4096, &timeout); + todo_wine_if(!pnt->name || !pnt->name[0]) + ok(status == pnt->status, "Expected status %#lx, got %#lx\n", pnt->status, status); + + if (!NT_SUCCESS(status)) + { + ok(pipe == NULL, "expected NULL handle, got %p\n", pipe); + return; + } + + ok(pipe != NULL, "expected non-NULL handle, got %p\n", client); + + client = NULL; + status = NtCreateFile(&client, SYNCHRONIZE, &attr, &iosb, NULL, 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0); + ok(status == STATUS_SUCCESS, "Expected success, got %#lx\n", status); + ok(client != NULL, "expected non-NULL handle, got %p\n", client); + NtClose(client); + + if (pnt->no_open_name) + { + OBJECT_ATTRIBUTES no_open_attr; + UNICODE_STRING no_open_name; + WCHAR no_open_namebuf[512]; + + no_open_name.Length = 0; + no_open_name.MaximumLength = sizeof(namebuf); + no_open_name.Buffer = no_open_namebuf; + + status = RtlAppendUnicodeStringToString(&no_open_name, name_prefix); + ok(status == STATUS_SUCCESS, "Expected success, got %#lx\n", status); + + status = RtlAppendUnicodeToString(&no_open_name, L"\"); + ok(status == STATUS_SUCCESS, "Expected success, got %#lx\n", status); + + status = RtlAppendUnicodeToString(&no_open_name, pnt->no_open_name); + ok(status == STATUS_SUCCESS, "Expected success, got %#lx\n", status); + + InitializeObjectAttributes(&no_open_attr, &no_open_name, pntm->attributes, NULL, NULL); + client = NULL; + status = NtCreateFile(&client, SYNCHRONIZE, &no_open_attr, &iosb, NULL, 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0); + ok(status == STATUS_OBJECT_NAME_NOT_FOUND, + "Expected STATUS_OBJECT_NAME_NOT_FOUND opening %s, got %#lx\n", + debugstr_wn(no_open_name.Buffer, no_open_name.Length / sizeof(WCHAR)), status); + ok(client == NULL, "expected NULL handle, got %p\n", client); + } + + NtClose(pipe); +} + +static void test_exotic_pipe_names(void) +{ + static const struct pipe_name_test_modifier modifiers[] = { + { OBJ_CASE_INSENSITIVE }, + { OBJ_CASE_INSENSITIVE | OBJ_OPENIF }, + { 0 }, + { OBJ_OPENIF }, + }; + static const struct pipe_name_test tests[] = { + { NULL , STATUS_OBJECT_NAME_INVALID }, + { L"" , STATUS_OBJECT_NAME_INVALID }, + { L"\" , STATUS_SUCCESS }, + { L"wine-test\" , STATUS_SUCCESS, L"wine-test" }, + { L"wine/test" , STATUS_SUCCESS, L"wine\test" }, + { L"wine:test" , STATUS_SUCCESS }, + { L"wine\.\test" , STATUS_SUCCESS, L"wine\test" }, + { L"wine\..\test" , STATUS_SUCCESS, L"test" }, + { L"..\wine-test" , STATUS_SUCCESS }, + { L"!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~", STATUS_SUCCESS }, + }; + UNICODE_STRING name_prefix; + size_t i, j; + + RtlInitUnicodeString(&name_prefix, L"\Device\NamedPipe"); + + for (i = 0; i < ARRAY_SIZE(modifiers); i++) + { + const struct pipe_name_test_modifier *pntm = &modifiers[i]; + + for (j = 0; j < ARRAY_SIZE(tests); j++) + { + const struct pipe_name_test *pnt = &tests[j]; + + winetest_push_context("test %Iu/%Iu: %s", i, j, debugstr_w(pnt->name)); + subtest_exotic_pipe_name(&name_prefix, pntm, pnt); + winetest_pop_context(); + } + } +} + START_TEST(pipe) { if (!init_func_ptrs()) @@ -2712,6 +2848,7 @@ START_TEST(pipe) test_file_info(); test_security_info(); test_empty_name(); + test_exotic_pipe_names();
pipe_for_each_state(create_pipe_server, connect_pipe, test_pipe_state); pipe_for_each_state(create_pipe_server, connect_and_write_pipe, test_pipe_with_data_state);