Signed-off-by: Paul Gofman pgofman@codeweavers.com --- Supersedes 196150 - 196153.
dlls/ntdll/tests/om.c | 64 ++++++++++++++++++++++++++++++++++++++++++- server/console.c | 24 ++++++++++------ server/directory.c | 4 +-- server/file.c | 6 ++-- server/mailslot.c | 4 +-- server/named_pipe.c | 4 +-- server/object.c | 5 ++-- server/object.h | 5 ++-- server/sock.c | 6 ++-- server/symlink.c | 5 ++-- server/winstation.c | 4 +-- 11 files changed, 104 insertions(+), 27 deletions(-)
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index d3b932bec1d..99c77839b7c 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -1081,7 +1081,7 @@ static void test_symboliclink(void) NTSTATUS status; UNICODE_STRING str, target; OBJECT_ATTRIBUTES attr; - HANDLE dir, link, h; + HANDLE dir, link, h, h2; IO_STATUS_BLOCK iosb;
/* No name and/or no attributes */ @@ -1178,6 +1178,68 @@ static void test_symboliclink(void) pNtClose(h); pNtClose(link); pNtClose(dir); + + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + RtlInitUnicodeString(&str, L"\BaseNamedObjects\om.c-test"); + status = pNtCreateDirectoryObject(&dir, DIRECTORY_QUERY, &attr); + ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status); + + RtlInitUnicodeString(&str, L"\DosDevices\test_link"); + RtlInitUnicodeString(&target, L"\BaseNamedObjects"); + status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target); + ok(status == STATUS_SUCCESS && !!link, "Got unexpected status %#x.\n", status); + + status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 ); + ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#x.\n", status); + + status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr ); + ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status); + pNtClose(h); + + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + RtlInitUnicodeString( &str, L"\BaseNamedObjects\om.c-test\" ); + status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 ); + ok(status == STATUS_OBJECT_NAME_INVALID, "Got unexpected status %#x.\n", status); + + InitializeObjectAttributes(&attr, &str, 0, link, NULL); + RtlInitUnicodeString( &str, L"om.c-test\test_object" ); + status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE ); + ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#x.\n", status); + + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + RtlInitUnicodeString( &str, L"\DosDevices\test_link\om.c-test\test_object" ); + status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE ); + ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status); + status = pNtOpenMutant( &h2, GENERIC_ALL, &attr ); + ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status); + pNtClose(h2); + RtlInitUnicodeString( &str, L"\BaseNamedObjects\om.c-test\test_object" ); + status = pNtCreateMutant( &h2, GENERIC_ALL, &attr, FALSE ); + ok(status == STATUS_OBJECT_NAME_COLLISION, "Got unexpected status %#x.\n", status); + + InitializeObjectAttributes(&attr, &str, 0, link, NULL); + RtlInitUnicodeString( &str, L"om.c-test\test_object" ); + status = pNtOpenMutant( &h2, GENERIC_ALL, &attr ); + ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#x.\n", status); + + pNtClose(h); + + status = pNtOpenMutant( &h, GENERIC_ALL, &attr ); + ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#x.\n", status); + + InitializeObjectAttributes(&attr, &str, 0, dir, NULL); + RtlInitUnicodeString( &str, L"test_object" ); + status = pNtCreateMutant( &h, GENERIC_ALL, &attr, FALSE ); + ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status); + status = pNtOpenMutant( &h2, GENERIC_ALL, &attr ); + ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status); + pNtClose(h); + pNtClose(h2); + + pNtClose(link); + pNtClose(dir); }
#define test_file_info(a) _test_file_info(__LINE__,a) diff --git a/server/console.c b/server/console.c index 9190dcc02dd..eeb2a21fffb 100644 --- a/server/console.c +++ b/server/console.c @@ -69,7 +69,8 @@ static void console_input_dump( struct object *obj, int verbose ); static void console_input_destroy( struct object *obj ); static int console_input_signaled( struct object *obj, struct wait_queue_entry *entry ); static struct fd *console_input_get_fd( struct object *obj ); -static struct object *console_input_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); +static struct object *console_input_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ); static struct object *console_input_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options );
@@ -143,7 +144,8 @@ static void console_server_dump( struct object *obj, int verbose ); static void console_server_destroy( struct object *obj ); static int console_server_signaled( struct object *obj, struct wait_queue_entry *entry ); static struct fd *console_server_get_fd( struct object *obj ); -static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); +static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ); static struct object *console_server_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options );
@@ -259,7 +261,8 @@ static const struct fd_ops screen_buffer_fd_ops =
static struct object_type *console_device_get_type( struct object *obj ); static void console_device_dump( struct object *obj, int verbose ); -static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); +static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ); static struct object *console_device_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options );
@@ -355,7 +358,8 @@ struct console_connection
static void console_connection_dump( struct object *obj, int verbose ); static struct fd *console_connection_get_fd( struct object *obj ); -static struct object *console_connection_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); +static struct object *console_connection_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ); static struct object *console_connection_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); static int console_connection_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); @@ -709,7 +713,8 @@ static struct object *create_console_connection( struct console_input *console ) return &connection->obj; }
-static struct object *console_input_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ) +static struct object *console_input_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ) { struct console_input *console = (struct console_input *)obj; static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n'}; @@ -793,7 +798,8 @@ static void console_server_destroy( struct object *obj ) if (server->fd) release_object( server->fd ); }
-static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ) +static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ) { struct console_server *server = (struct console_server*)obj; static const WCHAR referenceW[] = {'R','e','f','e','r','e','n','c','e'}; @@ -1117,7 +1123,8 @@ static struct fd *console_connection_get_fd( struct object *obj ) return (struct fd *)grab_object( connection->fd ); }
-static struct object *console_connection_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ) +static struct object *console_connection_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ) { static const WCHAR referenceW[] = {'R','e','f','e','r','e','n','c','e'};
@@ -1165,7 +1172,8 @@ static void console_device_dump( struct object *obj, int verbose ) fputs( "Console device\n", stderr ); }
-static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ) +static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ) { static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n'}; static const WCHAR consoleW[] = {'C','o','n','s','o','l','e'}; diff --git a/server/directory.c b/server/directory.c index 6f8fb179808..cd9afb3c457 100644 --- a/server/directory.c +++ b/server/directory.c @@ -83,7 +83,7 @@ struct directory static void directory_dump( struct object *obj, int verbose ); static struct object_type *directory_get_type( struct object *obj ); static struct object *directory_lookup_name( struct object *obj, struct unicode_str *name, - unsigned int attr ); + unsigned int attr, struct object *root ); static void directory_destroy( struct object *obj );
static const struct object_ops directory_ops = @@ -139,7 +139,7 @@ static struct object_type *directory_get_type( struct object *obj ) }
static struct object *directory_lookup_name( struct object *obj, struct unicode_str *name, - unsigned int attr ) + unsigned int attr, struct object *root ) { struct directory *dir = (struct directory *)obj; struct object *found; diff --git a/server/file.c b/server/file.c index 4690af2424e..2cc4a9d978c 100644 --- a/server/file.c +++ b/server/file.c @@ -68,7 +68,8 @@ static void file_dump( struct object *obj, int verbose ); static struct fd *file_get_fd( struct object *obj ); static struct security_descriptor *file_get_sd( struct object *obj ); static int file_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info ); -static struct object *file_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); +static struct object *file_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ); static struct object *file_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); static struct list *file_get_kernel_obj_list( struct object *obj ); @@ -603,7 +604,8 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd return 1; }
-static struct object *file_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ) +static struct object *file_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ) { if (!name || !name->len) return NULL; /* open the file itself */
diff --git a/server/mailslot.c b/server/mailslot.c index e0294d946e4..5d26c606080 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -186,7 +186,7 @@ struct mailslot_device_file static void mailslot_device_dump( struct object *obj, int verbose ); static struct object_type *mailslot_device_get_type( struct object *obj ); static struct object *mailslot_device_lookup_name( struct object *obj, struct unicode_str *name, - unsigned int attr ); + unsigned int attr, struct object *root ); static struct object *mailslot_device_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); static void mailslot_device_destroy( struct object *obj ); @@ -395,7 +395,7 @@ static struct object_type *mailslot_device_get_type( struct object *obj ) }
static struct object *mailslot_device_lookup_name( struct object *obj, struct unicode_str *name, - unsigned int attr ) + unsigned int attr, struct object *root ) { struct mailslot_device *device = (struct mailslot_device*)obj; struct object *found; diff --git a/server/named_pipe.c b/server/named_pipe.c index 60bd059d93d..14868fad63a 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -239,7 +239,7 @@ static const struct fd_ops pipe_client_fd_ops = static void named_pipe_device_dump( struct object *obj, int verbose ); static struct object_type *named_pipe_device_get_type( struct object *obj ); static struct object *named_pipe_device_lookup_name( struct object *obj, - struct unicode_str *name, unsigned int attr ); + struct unicode_str *name, unsigned int attr, struct object *root ); static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); static void named_pipe_device_destroy( struct object *obj ); @@ -468,7 +468,7 @@ static struct object_type *named_pipe_device_get_type( struct object *obj ) }
static struct object *named_pipe_device_lookup_name( struct object *obj, struct unicode_str *name, - unsigned int attr ) + unsigned int attr, struct object *root ) { struct named_pipe_device *device = (struct named_pipe_device*)obj; struct object *found; diff --git a/server/object.c b/server/object.c index 9f26a6fea36..c4772a57823 100644 --- a/server/object.c +++ b/server/object.c @@ -248,7 +248,8 @@ struct object *lookup_named_object( struct object *root, const struct unicode_st
clear_error();
- while ((obj = parent->ops->lookup_name( parent, ptr, attr ))) + root = parent; + while ((obj = parent->ops->lookup_name( parent, ptr, attr, root ))) { /* move to the next element */ release_object ( parent ); @@ -670,7 +671,7 @@ WCHAR *no_get_full_name( struct object *obj, data_size_t *ret_len ) }
struct object *no_lookup_name( struct object *obj, struct unicode_str *name, - unsigned int attr ) + unsigned int attr, struct object *root ) { if (!name) set_error( STATUS_OBJECT_TYPE_MISMATCH ); return NULL; diff --git a/server/object.h b/server/object.h index 394a4aac463..3b3e9084798 100644 --- a/server/object.h +++ b/server/object.h @@ -83,7 +83,7 @@ struct object_ops /* get the object full name */ WCHAR *(*get_full_name)(struct object *, data_size_t *); /* lookup a name if an object has a namespace */ - struct object *(*lookup_name)(struct object *, struct unicode_str *,unsigned int); + struct object *(*lookup_name)(struct object *, struct unicode_str *,unsigned int,struct object *); /* link an object's name into a parent object */ int (*link_name)(struct object *, struct object_name *, struct object *); /* unlink an object's name from its parent */ @@ -165,7 +165,8 @@ extern int default_set_sd( struct object *obj, const struct security_descriptor extern int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd, unsigned int set_info, struct token *token ); extern WCHAR *no_get_full_name( struct object *obj, data_size_t *ret_len ); -extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes ); +extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attributes, struct object *root ); extern int no_link_name( struct object *obj, struct object_name *name, struct object *parent ); extern void default_unlink_name( struct object *obj, struct object_name *name ); extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing, diff --git a/server/sock.c b/server/sock.c index 8f500adc68b..1ff56f7bbe5 100644 --- a/server/sock.c +++ b/server/sock.c @@ -1735,7 +1735,8 @@ static void sock_release_ifchange( struct sock *sock )
static struct object_type *socket_device_get_type( struct object *obj ); static void socket_device_dump( struct object *obj, int verbose ); -static struct object *socket_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); +static struct object *socket_device_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ); static struct object *socket_device_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options );
@@ -1775,7 +1776,8 @@ static void socket_device_dump( struct object *obj, int verbose ) fputs( "Socket device\n", stderr ); }
-static struct object *socket_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ) +static struct object *socket_device_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr, struct object *root ) { return NULL; } diff --git a/server/symlink.c b/server/symlink.c index b620f2accb9..0b85350e1a5 100644 --- a/server/symlink.c +++ b/server/symlink.c @@ -49,7 +49,7 @@ static void symlink_dump( struct object *obj, int verbose ); static struct object_type *symlink_get_type( struct object *obj ); static unsigned int symlink_map_access( struct object *obj, unsigned int access ); static struct object *symlink_lookup_name( struct object *obj, struct unicode_str *name, - unsigned int attr ); + unsigned int attr, struct object *root ); static void symlink_destroy( struct object *obj );
static const struct object_ops symlink_ops = @@ -94,7 +94,7 @@ static struct object_type *symlink_get_type( struct object *obj ) }
static struct object *symlink_lookup_name( struct object *obj, struct unicode_str *name, - unsigned int attr ) + unsigned int attr, struct object *root ) { struct symlink *symlink = (struct symlink *)obj; struct unicode_str target_str, name_left; @@ -104,6 +104,7 @@ static struct object *symlink_lookup_name( struct object *obj, struct unicode_st
if (!name) return NULL; if (!name->len && (attr & OBJ_OPENLINK)) return NULL; + if (obj == root) return NULL;
target_str.str = symlink->target; target_str.len = symlink->len; diff --git a/server/winstation.c b/server/winstation.c index c9c85e50fff..95e5c0c7d0d 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -46,7 +46,7 @@ static void winstation_dump( struct object *obj, int verbose ); static struct object_type *winstation_get_type( struct object *obj ); static int winstation_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); static struct object *winstation_lookup_name( struct object *obj, struct unicode_str *name, - unsigned int attr ); + unsigned int attr, struct object *root ); static void winstation_destroy( struct object *obj ); static unsigned int winstation_map_access( struct object *obj, unsigned int access ); static void desktop_dump( struct object *obj, int verbose ); @@ -155,7 +155,7 @@ static int winstation_close_handle( struct object *obj, struct process *process, }
static struct object *winstation_lookup_name( struct object *obj, struct unicode_str *name, - unsigned int attr ) + unsigned int attr, struct object *root ) { struct winstation *winstation = (struct winstation *)obj; struct object *found;
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntdll/tests/pipe.c | 34 ++++++++++++++++++++++++++++++++-- server/named_pipe.c | 2 +- server/object.h | 1 - server/request.c | 3 ++- 4 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index 9e8b623d75b..bfc8dc0b3be 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -65,6 +65,7 @@ typedef struct { #endif
static NTSTATUS (WINAPI *pNtFsControlFile) (HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, PVOID apc_context, PIO_STATUS_BLOCK io, ULONG code, PVOID in_buffer, ULONG in_size, PVOID out_buffer, ULONG out_size); +static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *); static NTSTATUS (WINAPI *pNtCreateNamedPipeFile) (PHANDLE handle, ULONG access, POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK iosb, ULONG sharing, ULONG dispo, ULONG options, @@ -73,6 +74,7 @@ static NTSTATUS (WINAPI *pNtCreateNamedPipeFile) (PHANDLE handle, ULONG access, ULONG inbound_quota, ULONG outbound_quota, PLARGE_INTEGER timeout); static NTSTATUS (WINAPI *pNtQueryInformationFile) (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass); +static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE, OBJECT_INFORMATION_CLASS, void *, ULONG, ULONG *); static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(HANDLE handle, PIO_STATUS_BLOCK io, void *buffer, ULONG length, FS_INFORMATION_CLASS info_class); static NTSTATUS (WINAPI *pNtSetInformationFile) (HANDLE handle, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class); static NTSTATUS (WINAPI *pNtCancelIoFile) (HANDLE hFile, PIO_STATUS_BLOCK io_status); @@ -94,8 +96,10 @@ static BOOL init_func_ptrs(void) }
loadfunc(NtFsControlFile) + loadfunc(NtCreateDirectoryObject) loadfunc(NtCreateNamedPipeFile) loadfunc(NtQueryInformationFile) + loadfunc(NtQueryObject) loadfunc(NtQueryVolumeInformationFile) loadfunc(NtSetInformationFile) loadfunc(NtCancelIoFile) @@ -2405,14 +2409,20 @@ static void test_security_info(void) static void test_empty_name(void) { HANDLE hdirectory, hpipe, hwrite, handle; + OBJECT_TYPE_INFORMATION *type_info; + OBJECT_NAME_INFORMATION *name_info; OBJECT_ATTRIBUTES attr; LARGE_INTEGER timeout; UNICODE_STRING name; IO_STATUS_BLOCK io; DWORD data, length; + char buffer[1024]; NTSTATUS status; BOOL ret;
+ type_info = (OBJECT_TYPE_INFORMATION *)buffer; + name_info = (OBJECT_NAME_INFORMATION *)buffer; + hpipe = hwrite = NULL;
attr.Length = sizeof(attr); @@ -2438,13 +2448,17 @@ static void test_empty_name(void) &io, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, 0, 0, 0, 3, 4096, 4096, &timeout); todo_wine ok(status == STATUS_OBJECT_NAME_INVALID, "Got unexpected status %#x.\n", status); - + if (!status) + CloseHandle(hpipe); CloseHandle(hdirectory);
pRtlInitUnicodeString(&name, L"\Device\NamedPipe\"); attr.RootDirectory = 0; attr.ObjectName = &name;
+ status = pNtCreateDirectoryObject(&hdirectory, GENERIC_READ | SYNCHRONIZE, &attr); + todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#x.\n", status); + status = NtCreateFile(&hdirectory, GENERIC_READ | SYNCHRONIZE, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0 ); ok(!status, "Got unexpected status %#x.\n", status); @@ -2454,10 +2468,18 @@ static void test_empty_name(void) name.MaximumLength = 0; attr.RootDirectory = hdirectory;
+ hpipe = NULL; status = pNtCreateNamedPipeFile(&hpipe, GENERIC_READ | SYNCHRONIZE, &attr, &io, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, 0, 0, 0, 3, 4096, 4096, &timeout); - todo_wine ok(!status, "Got unexpected status %#x.\n", status); + ok(!status, "Got unexpected status %#x.\n", status); + type_info->TypeName.Buffer = NULL; + status = pNtQueryObject(hpipe, ObjectTypeInformation, type_info, sizeof(buffer), NULL); + 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(hpipe, ObjectNameInformation, name_info, sizeof(buffer), NULL); + todo_wine ok(status == STATUS_OBJECT_PATH_INVALID, "Got unexpected status %#x.\n", status);
status = pNtCreateNamedPipeFile(&handle, GENERIC_READ | SYNCHRONIZE, &attr, &io, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, @@ -2469,6 +2491,14 @@ static void test_empty_name(void) FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); todo_wine 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"), + "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); + attr.RootDirectory = hpipe; status = NtCreateFile(&handle, GENERIC_READ | SYNCHRONIZE, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, diff --git a/server/named_pipe.c b/server/named_pipe.c index 14868fad63a..6e65f3e364a 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -1371,7 +1371,7 @@ DECL_HANDLER(create_named_pipe) set_error( STATUS_OBJECT_PATH_SYNTAX_BAD ); return; } - if (!(root = get_directory_obj( current->process, objattr->rootdir ))) return; + if (!(root = get_handle_obj( current->process, objattr->rootdir, 0, NULL ))) return; }
pipe = create_named_object( root, &named_pipe_ops, &name, objattr->attributes | OBJ_OPENIF, NULL ); diff --git a/server/object.h b/server/object.h index 3b3e9084798..1b902dbac1e 100644 --- a/server/object.h +++ b/server/object.h @@ -254,7 +254,6 @@ extern struct object *create_obj_symlink( struct object *root, const struct unic extern struct object *create_symlink( struct object *root, const struct unicode_str *name, unsigned int attr, const struct unicode_str *target, const struct security_descriptor *sd ); - /* global variables */
/* command-line options */ diff --git a/server/request.c b/server/request.c index 97bf1a746d2..24cfda26110 100644 --- a/server/request.c +++ b/server/request.c @@ -66,6 +66,7 @@ #include "process.h" #include "thread.h" #include "security.h" +#include "handle.h" #define WANT_REQUEST_HANDLERS #include "request.h"
@@ -205,7 +206,7 @@ const struct object_attributes *get_req_object_attributes( const struct security } if (root && attr->rootdir && attr->name_len) { - if (!(*root = get_directory_obj( current->process, attr->rootdir ))) return NULL; + if (!(*root = get_handle_obj( current->process, attr->rootdir, 0, NULL ))) return NULL; } *sd = attr->sd_len ? (const struct security_descriptor *)(attr + 1) : NULL; name->len = attr->name_len;
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntdll/tests/pipe.c | 2 +- server/named_pipe.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index bfc8dc0b3be..1230fecfda7 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -2479,7 +2479,7 @@ static void test_empty_name(void) 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(hpipe, 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);
status = pNtCreateNamedPipeFile(&handle, GENERIC_READ | SYNCHRONIZE, &attr, &io, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, diff --git a/server/named_pipe.c b/server/named_pipe.c index 6e65f3e364a..5adfd444ada 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -105,6 +105,7 @@ struct named_pipe_device_file
static void named_pipe_dump( struct object *obj, int verbose ); static unsigned int named_pipe_map_access( struct object *obj, unsigned int access ); +static WCHAR *named_pipe_get_full_name( struct object *obj, data_size_t *ret_len ); static int named_pipe_link_name( struct object *obj, struct object_name *name, struct object *parent ); static struct object *named_pipe_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); @@ -124,7 +125,7 @@ static const struct object_ops named_pipe_ops = named_pipe_map_access, /* map_access */ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ - default_get_full_name, /* get_full_name */ + named_pipe_get_full_name, /* get_full_name */ no_lookup_name, /* lookup_name */ named_pipe_link_name, /* link_name */ default_unlink_name, /* unlink_name */ @@ -328,6 +329,15 @@ static unsigned int named_pipe_map_access( struct object *obj, unsigned int acce return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); }
+static WCHAR *named_pipe_get_full_name( struct object *obj, data_size_t *ret_len ) +{ + WCHAR *ret; + + if (!(ret = default_get_full_name( obj, ret_len ))) + set_error( STATUS_OBJECT_PATH_INVALID ); + return ret; +} + static void pipe_server_dump( struct object *obj, int verbose ) { struct pipe_server *server = (struct pipe_server *) obj;
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- 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 5adfd444ada..ff1fdbe3f07 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, struct object *root ); +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, struct object *root ) +{ + 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;
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntdll/tests/pipe.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index 42bd825dc3c..662dc1d55cb 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -2408,7 +2408,7 @@ static void test_security_info(void)
static void test_empty_name(void) { - HANDLE hdirectory, hpipe, hwrite, handle; + HANDLE hdirectory, hpipe, hpipe2, hwrite, hwrite2, handle; OBJECT_TYPE_INFORMATION *type_info; OBJECT_NAME_INFORMATION *name_info; OBJECT_ATTRIBUTES attr; @@ -2486,6 +2486,11 @@ static void test_empty_name(void) 0, 0, 0, 1, 4096, 4096, &timeout); todo_wine ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "Got unexpected status %#x.\n", status);
+ status = pNtCreateNamedPipeFile(&hpipe2, GENERIC_READ | SYNCHRONIZE, &attr, + &io, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, + 0, 0, 0, 3, 4096, 4096, &timeout); + ok(!status, "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, @@ -2519,20 +2524,38 @@ static void test_empty_name(void) FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); ok(status == STATUS_PIPE_NOT_AVAILABLE, "Got unexpected status %#x.\n", status);
+ attr.RootDirectory = hpipe2; + status = NtCreateFile(&hwrite2, 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); + data = 0xdeadbeef; ret = WriteFile(hwrite, &data, sizeof(data), &length, NULL); ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); ok(length == sizeof(data), "Got unexpected length %#x.\n", length);
+ data = 0xfeedcafe; + ret = WriteFile(hwrite2, &data, sizeof(data), &length, NULL); + 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); 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);
+ data = 0; + ret = ReadFile(hpipe2, &data, sizeof(data), &length, NULL); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + ok(length == sizeof(data), "Got unexpected length %#x.\n", length); + ok(data == 0xfeedcafe, "Got unexpected data %#x.\n", data); + CloseHandle(hwrite); CloseHandle(hpipe); CloseHandle(hdirectory); + CloseHandle(hpipe2); + CloseHandle(hwrite2); }
START_TEST(pipe)