From c7f16d62204c86ed66c216125448d6678b5ad42e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 18 Jul 2016 15:34:08 +0900 Subject: [PATCH] server: Add a helper function to create a symlink to an existing object. Signed-off-by: Alexandre Julliard --- server/device.c | 5 ++-- server/directory.c | 56 +++++++++++++++++++++------------------------ server/file.h | 6 ++--- server/mailslot.c | 4 ++-- server/named_pipe.c | 4 ++-- server/object.h | 6 ++--- server/symlink.c | 31 ++++++++++++++++++++++--- 7 files changed, 66 insertions(+), 46 deletions(-) diff --git a/server/device.c b/server/device.c index 22ade88e0e6..e4f55c7154c 100644 --- a/server/device.c +++ b/server/device.c @@ -618,7 +618,7 @@ static struct device *create_device( struct object *root, const struct unicode_s return device; } -struct device *create_unix_device( struct object *root, const struct unicode_str *name, +struct object *create_unix_device( struct object *root, const struct unicode_str *name, const char *unix_path ) { struct device *device; @@ -628,9 +628,8 @@ struct device *create_unix_device( struct object *root, const struct unicode_str device->unix_path = strdup( unix_path ); device->manager = NULL; /* no manager, requests go straight to the Unix device */ list_init( &device->files ); - make_object_static( &device->obj ); } - return device; + return &device->obj; } diff --git a/server/directory.c b/server/directory.c index 9368421c47f..ec1426edab5 100644 --- a/server/directory.c +++ b/server/directory.c @@ -252,10 +252,7 @@ void init_directories(void) static const WCHAR dir_globalW[] = {'\\','?','?'}; static const WCHAR dir_driverW[] = {'D','r','i','v','e','r'}; static const WCHAR dir_deviceW[] = {'D','e','v','i','c','e'}; - static const WCHAR dir_nullW[] = {'\\','D','e','v','i','c','e','\\','N','u','l','l'}; static const WCHAR dir_basenamedW[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s'}; - static const WCHAR dir_named_pipeW[] = {'\\','D','e','v','i','c','e','\\','N','a','m','e','d','P','i','p','e'}; - static const WCHAR dir_mailslotW[] = {'\\','D','e','v','i','c','e','\\','M','a','i','l','S','l','o','t'}; static const WCHAR dir_objtypeW[] = {'O','b','j','e','c','t','T','y','p','e','s'}; static const WCHAR dir_sessionsW[] = {'S','e','s','s','i','o','n','s'}; static const WCHAR dir_1W[] = {'1'}; @@ -265,10 +262,7 @@ void init_directories(void) static const struct unicode_str dir_global_str = {dir_globalW, sizeof(dir_globalW)}; static const struct unicode_str dir_driver_str = {dir_driverW, sizeof(dir_driverW)}; static const struct unicode_str dir_device_str = {dir_deviceW, sizeof(dir_deviceW)}; - static const struct unicode_str dir_null_str = {dir_nullW, sizeof(dir_nullW)}; static const struct unicode_str dir_basenamed_str = {dir_basenamedW, sizeof(dir_basenamedW)}; - static const struct unicode_str dir_named_pipe_str = {dir_named_pipeW, sizeof(dir_named_pipeW)}; - static const struct unicode_str dir_mailslot_str = {dir_mailslotW, sizeof(dir_mailslotW)}; static const struct unicode_str dir_objtype_str = {dir_objtypeW, sizeof(dir_objtypeW)}; static const struct unicode_str dir_sessions_str = {dir_sessionsW, sizeof(dir_sessionsW)}; static const struct unicode_str dir_1_str = {dir_1W, sizeof(dir_1W)}; @@ -285,7 +279,6 @@ void init_directories(void) static const WCHAR link_mailslotW[] = {'M','A','I','L','S','L','O','T'}; static const WCHAR link_basenamedW[] = {'B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s'}; static const WCHAR link_sessionW[] = {'S','e','s','s','i','o','n'}; - static const WCHAR link_sessionsW[] = {'\\','S','e','s','s','i','o','n','s'}; static const struct unicode_str link_dosdev_str = {link_dosdevW, sizeof(link_dosdevW)}; static const struct unicode_str link_global_str = {link_globalW, sizeof(link_globalW)}; static const struct unicode_str link_local_str = {link_localW, sizeof(link_localW)}; @@ -294,7 +287,6 @@ void init_directories(void) static const struct unicode_str link_mailslot_str = {link_mailslotW, sizeof(link_mailslotW)}; static const struct unicode_str link_basenamed_str = {link_basenamedW, sizeof(link_basenamedW)}; static const struct unicode_str link_session_str = {link_sessionW, sizeof(link_sessionW)}; - static const struct unicode_str link_sessions_str = {link_sessionsW, sizeof(link_sessionsW)}; /* devices */ static const WCHAR named_pipeW[] = {'N','a','m','e','d','P','i','p','e'}; @@ -324,7 +316,8 @@ void init_directories(void) static const struct unicode_str keyed_event_crit_sect_str = {keyed_event_crit_sectW, sizeof(keyed_event_crit_sectW)}; struct directory *dir_driver, *dir_device, *dir_global, *dir_basenamed, *dir_sessions, *dir_1, *dir_kernel, *dir_windows, *dir_winstation; - struct symlink *link_dosdev, *link_global1, *link_global2, *link_local, *link_nul, *link_pipe, *link_mailslot, *link_basenamed, *link_session; + struct object *link_dosdev, *link_global1, *link_global2, *link_local, *link_nul, *link_pipe, *link_mailslot, *link_basenamed, *link_session; + struct object *named_pipe_device, *mailslot_device, *null_device; struct keyed_event *keyed_event; unsigned int i; @@ -347,29 +340,32 @@ void init_directories(void) dir_basenamed = create_directory( NULL, &dir_basenamed_str, 0, 37, NULL ); /* devices */ - create_named_pipe_device( &dir_device->obj, &named_pipe_str ); - create_mailslot_device( &dir_device->obj, &mailslot_str ); - create_unix_device( &dir_device->obj, &null_str, "/dev/null" ); + named_pipe_device = create_named_pipe_device( &dir_device->obj, &named_pipe_str ); + mailslot_device = create_mailslot_device( &dir_device->obj, &mailslot_str ); + null_device = create_unix_device( &dir_device->obj, &null_str, "/dev/null" ); + make_object_static( named_pipe_device ); + make_object_static( mailslot_device ); + make_object_static( null_device ); /* symlinks */ - link_dosdev = create_symlink( &root_directory->obj, &link_dosdev_str, 0, &dir_global_str, NULL ); - link_global1 = create_symlink( &dir_global->obj, &link_global_str, 0, &dir_global_str, NULL ); - link_global2 = create_symlink( &dir_basenamed->obj, &link_global_str, 0, &dir_basenamed_str, NULL ); - link_local = create_symlink( &dir_basenamed->obj, &link_local_str, 0, &dir_basenamed_str, NULL ); - link_nul = create_symlink( &dir_global->obj, &link_nul_str, 0, &dir_null_str, NULL ); - link_pipe = create_symlink( &dir_global->obj, &link_pipe_str, 0, &dir_named_pipe_str, NULL ); - link_mailslot = create_symlink( &dir_global->obj, &link_mailslot_str, 0, &dir_mailslot_str, NULL ); - link_basenamed = create_symlink( &dir_1->obj, &link_basenamed_str, 0, &dir_basenamed_str, NULL ); - link_session = create_symlink( &dir_basenamed->obj, &link_session_str, 0, &link_sessions_str, NULL ); - make_object_static( (struct object *)link_dosdev ); - make_object_static( (struct object *)link_global1 ); - make_object_static( (struct object *)link_global2 ); - make_object_static( (struct object *)link_local ); - make_object_static( (struct object *)link_nul ); - make_object_static( (struct object *)link_pipe ); - make_object_static( (struct object *)link_mailslot ); - make_object_static( (struct object *)link_basenamed ); - make_object_static( (struct object *)link_session ); + link_dosdev = create_obj_symlink( &root_directory->obj, &link_dosdev_str, 0, &dir_global->obj, NULL ); + link_global1 = create_obj_symlink( &dir_global->obj, &link_global_str, 0, &dir_global->obj, NULL ); + link_global2 = create_obj_symlink( &dir_basenamed->obj, &link_global_str, 0, &dir_basenamed->obj, NULL ); + link_local = create_obj_symlink( &dir_basenamed->obj, &link_local_str, 0, &dir_basenamed->obj, NULL ); + link_nul = create_obj_symlink( &dir_global->obj, &link_nul_str, 0, null_device, NULL ); + link_pipe = create_obj_symlink( &dir_global->obj, &link_pipe_str, 0, named_pipe_device, NULL ); + link_mailslot = create_obj_symlink( &dir_global->obj, &link_mailslot_str, 0, mailslot_device, NULL ); + link_basenamed = create_obj_symlink( &dir_1->obj, &link_basenamed_str, 0, &dir_basenamed->obj, NULL ); + link_session = create_obj_symlink( &dir_basenamed->obj, &link_session_str, 0, &dir_sessions->obj, NULL ); + make_object_static( link_dosdev ); + make_object_static( link_global1 ); + make_object_static( link_global2 ); + make_object_static( link_local ); + make_object_static( link_nul ); + make_object_static( link_pipe ); + make_object_static( link_mailslot ); + make_object_static( link_basenamed ); + make_object_static( link_session ); /* events */ for (i = 0; i < sizeof(kernel_events)/sizeof(kernel_events[0]); i++) diff --git a/server/file.h b/server/file.h index 2a72568276c..b643d944e93 100644 --- a/server/file.h +++ b/server/file.h @@ -141,9 +141,9 @@ extern int get_page_size(void); /* device functions */ -extern void create_named_pipe_device( struct object *root, const struct unicode_str *name ); -extern void create_mailslot_device( struct object *root, const struct unicode_str *name ); -extern struct device *create_unix_device( struct object *root, const struct unicode_str *name, +extern struct object *create_named_pipe_device( struct object *root, const struct unicode_str *name ); +extern struct object *create_mailslot_device( struct object *root, const struct unicode_str *name ); +extern struct object *create_unix_device( struct object *root, const struct unicode_str *name, const char *unix_path ); /* change notification functions */ diff --git a/server/mailslot.c b/server/mailslot.c index ea28825f600..13e67031c16 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -397,7 +397,7 @@ static enum server_fd_type mailslot_device_get_fd_type( struct fd *fd ) return FD_TYPE_DEVICE; } -void create_mailslot_device( struct object *root, const struct unicode_str *name ) +struct object *create_mailslot_device( struct object *root, const struct unicode_str *name ) { struct mailslot_device *dev; @@ -412,7 +412,7 @@ void create_mailslot_device( struct object *root, const struct unicode_str *name dev = NULL; } } - if (dev) make_object_static( &dev->obj ); + return &dev->obj; } static struct mailslot *create_mailslot( struct object *root, diff --git a/server/named_pipe.c b/server/named_pipe.c index 0661c12af7b..cfee4d56d57 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -500,7 +500,7 @@ static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd ) return FD_TYPE_DEVICE; } -void create_named_pipe_device( struct object *root, const struct unicode_str *name ) +struct object *create_named_pipe_device( struct object *root, const struct unicode_str *name ) { struct named_pipe_device *dev; @@ -515,7 +515,7 @@ void create_named_pipe_device( struct object *root, const struct unicode_str *na dev = NULL; } } - if (dev) make_object_static( &dev->obj ); + return &dev->obj; } static int pipe_data_remaining( struct pipe_server *server ) diff --git a/server/object.h b/server/object.h index 687f73050b5..b5c50e1cee8 100644 --- a/server/object.h +++ b/server/object.h @@ -235,9 +235,9 @@ extern void init_directories(void); /* symbolic link functions */ -extern struct symlink *create_symlink( struct object *root, const struct unicode_str *name, - unsigned int attr, const struct unicode_str *target, - const struct security_descriptor *sd ); +extern struct object *create_obj_symlink( struct object *root, const struct unicode_str *name, + unsigned int attr, struct object *target, + const struct security_descriptor *sd ); /* global variables */ diff --git a/server/symlink.c b/server/symlink.c index e176267040f..9199bc559d7 100644 --- a/server/symlink.c +++ b/server/symlink.c @@ -133,9 +133,9 @@ static void symlink_destroy( struct object *obj ) free( symlink->target ); } -struct symlink *create_symlink( struct object *root, const struct unicode_str *name, - unsigned int attr, const struct unicode_str *target, - const struct security_descriptor *sd ) +static struct symlink *create_symlink( struct object *root, const struct unicode_str *name, + unsigned int attr, const struct unicode_str *target, + const struct security_descriptor *sd ) { struct symlink *symlink; @@ -160,6 +160,31 @@ struct symlink *create_symlink( struct object *root, const struct unicode_str *n return symlink; } +/* create a symlink pointing to an existing object */ +struct object *create_obj_symlink( struct object *root, const struct unicode_str *name, + unsigned int attr, struct object *target, + const struct security_descriptor *sd ) +{ + struct symlink *symlink; + data_size_t len; + WCHAR *target_name; + + if (!(target_name = get_object_full_name( target, &len ))) + { + set_error( STATUS_INVALID_PARAMETER ); + return NULL; + } + if ((symlink = create_named_object( root, &symlink_ops, name, attr, sd )) && + (get_error() != STATUS_OBJECT_NAME_EXISTS)) + { + symlink->target = target_name; + symlink->len = len; + } + else free( target_name ); + + return &symlink->obj; +} + /* create a symbolic link object */ DECL_HANDLER(create_symlink)