From: Paul Gofman Subject: [PATCH v3 3/4] server: Allow client pipe creation with server pipe as root directory. Message-Id: <20201118131231.138372-3-pgofman@codeweavers.com> Date: Wed, 18 Nov 2020 16:12:30 +0300 In-Reply-To: <20201118131231.138372-1-pgofman@codeweavers.com> References: <20201118131231.138372-1-pgofman@codeweavers.com> Signed-off-by: Paul Gofman --- v2: - Remove todo_wine from now succeeding tests in kernel32/tests/file.c. dlls/kernel32/tests/file.c | 13 +++++-------- dlls/ntdll/tests/pipe.c | 31 ++++++++++++++++++++----------- server/named_pipe.c | 25 +++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 9327d0319dd..2814ab194b2 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -4565,17 +4565,14 @@ static void test_ReOpenFile(void) ok(file != INVALID_HANDLE_VALUE, "failed to create pipe, error %u\n", GetLastError()); new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0); - todo_wine ok(new != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + ok(new != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); ret = WriteFile(file, "foo", 4, &size, NULL); - todo_wine ok(ret, "failed to write file, error %u\n", GetLastError()); + ok(ret, "failed to write file, error %u\n", GetLastError()); ret = ReadFile(new, buffer, sizeof(buffer), &size, NULL); - todo_wine ok(ret, "failed to read file, error %u\n", GetLastError()); - if (ret) - { - ok(size == 4, "got size %u\n", size); - ok(!strcmp(buffer, "foo"), "got wrong data\n"); - } + ok(ret, "failed to read file, error %u\n", GetLastError()); + ok(size == 4, "got size %u\n", size); + ok(!strcmp(buffer, "foo"), "got wrong data\n"); CloseHandle(new); CloseHandle(file); diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index 1230fecfda7..42bd825dc3c 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -2487,39 +2487,48 @@ static void test_empty_name(void) todo_wine ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "Got unexpected status %#x.\n", status); attr.RootDirectory = hpipe; + pRtlInitUnicodeString(&name, L"a"); status = NtCreateFile(&hwrite, GENERIC_WRITE | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); - todo_wine ok(!status, "Got unexpected status %#x.\n", status); + ok(status == STATUS_OBJECT_NAME_INVALID, "Got unexpected status %#x.\n", status); + + name.Buffer = NULL; + name.Length = 0; + name.MaximumLength = 0; + attr.RootDirectory = hpipe; + status = NtCreateFile(&hwrite, GENERIC_WRITE | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, &attr, &io, NULL, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); + ok(!status, "Got unexpected status %#x.\n", status); type_info->TypeName.Buffer = NULL; status = pNtQueryObject(hwrite, ObjectTypeInformation, type_info, sizeof(buffer), NULL); - todo_wine ok(!status, "Got unexpected status %#x.\n", status); - todo_wine ok(type_info->TypeName.Buffer && !wcscmp(type_info->TypeName.Buffer, L"File"), + ok(!status, "Got unexpected status %#x.\n", status); + ok(type_info->TypeName.Buffer && !wcscmp(type_info->TypeName.Buffer, L"File"), "Got unexpected type %s.\n", debugstr_w(type_info->TypeName.Buffer)); status = pNtQueryObject(hwrite, ObjectNameInformation, name_info, sizeof(buffer), NULL); - todo_wine ok(status == STATUS_OBJECT_PATH_INVALID, "Got unexpected status %#x.\n", status); + ok(status == STATUS_OBJECT_PATH_INVALID, "Got unexpected status %#x.\n", status); attr.RootDirectory = hpipe; status = NtCreateFile(&handle, GENERIC_READ | SYNCHRONIZE, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); - todo_wine ok(status == STATUS_PIPE_NOT_AVAILABLE, "Got unexpected status %#x.\n", status); + ok(status == STATUS_PIPE_NOT_AVAILABLE, "Got unexpected status %#x.\n", status); attr.RootDirectory = hpipe; status = NtCreateFile(&handle, GENERIC_WRITE | SYNCHRONIZE, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); - todo_wine ok(status == STATUS_PIPE_NOT_AVAILABLE, "Got unexpected status %#x.\n", status); + ok(status == STATUS_PIPE_NOT_AVAILABLE, "Got unexpected status %#x.\n", status); data = 0xdeadbeef; ret = WriteFile(hwrite, &data, sizeof(data), &length, NULL); - todo_wine ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); - todo_wine ok(length == sizeof(data), "Got unexpected length %#x.\n", length); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + ok(length == sizeof(data), "Got unexpected length %#x.\n", length); data = 0; ret = ReadFile(hpipe, &data, sizeof(data), &length, NULL); - todo_wine ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); - todo_wine ok(length == sizeof(data), "Got unexpected length %#x.\n", length); - todo_wine ok(data == 0xdeadbeef, "Got unexpected data %#x.\n", data); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + ok(length == sizeof(data), "Got unexpected length %#x.\n", length); + ok(data == 0xdeadbeef, "Got unexpected data %#x.\n", data); CloseHandle(hwrite); CloseHandle(hpipe); diff --git a/server/named_pipe.c b/server/named_pipe.c index a3b684138ab..73ebd3ff30e 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -152,6 +152,10 @@ static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned /* server end functions */ static void pipe_server_dump( struct object *obj, int verbose ); +static struct object *pipe_server_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr ); +static struct object *pipe_server_open_file( struct object *obj, unsigned int access, + unsigned int sharing, unsigned int options ); static void pipe_server_destroy( struct object *obj); static int pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ); @@ -170,10 +174,10 @@ static const struct object_ops pipe_server_ops = pipe_end_get_sd, /* get_sd */ pipe_end_set_sd, /* set_sd */ pipe_end_get_full_name, /* get_full_name */ - no_lookup_name, /* lookup_name */ + pipe_server_lookup_name, /* lookup_name */ no_link_name, /* link_name */ NULL, /* unlink_name */ - no_open_file, /* open_file */ + pipe_server_open_file, /* open_file */ no_kernel_obj_list, /* get_kernel_obj_list */ fd_close_handle, /* close_handle */ pipe_server_destroy /* destroy */ @@ -449,6 +453,23 @@ static void pipe_end_destroy( struct object *obj ) if (pipe_end->pipe) release_object( pipe_end->pipe ); } +static struct object *pipe_server_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr ) +{ + if (name && name->len) + set_error( STATUS_OBJECT_NAME_INVALID ); + + return NULL; +} + +static struct object *pipe_server_open_file( struct object *obj, unsigned int access, + unsigned int sharing, unsigned int options ) +{ + struct pipe_server *server = (struct pipe_server *)obj; + + return server->pipe_end.pipe->obj.ops->open_file( &server->pipe_end.pipe->obj, access, sharing, options ); +} + static void pipe_server_destroy( struct object *obj ) { struct pipe_server *server = (struct pipe_server *)obj; -- 2.28.0