diff --git a/server/device.c b/server/device.c
index 22ade88e0e6dadb3ea91a1daeb8755982dd84d04..e4f55c7154c6c904aaff12882cb13c78fd0f007d 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 9368421c47fd8155de611486e8cc2398befc5a0f..ec1426edab53d969761ab5d96767c5890c1e7af9 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 2a72568276c1f3132edd2bdcd5eebb1531a27f7e..b643d944e9362ebf2570cc1f1b0e77d3713ad361 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 ea28825f60083ff2878a8ef8a205aa3b4065538e..13e67031c16f607be6696b814c3c0c2aa03a49d3 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 0661c12af7b7342c452dcd595890ad978740cb24..cfee4d56d5711541c3ba242e6ee325e6f14fe131 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 687f73050b5a2b3d0bae4337b8ea7d63da3e995b..b5c50e1cee8aec829e31bbd5ab921f547c489c31 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 e176267040f2133b6cc67270ca178046a195c82b..9199bc559d7d6c7acf0226aed1f2181cc8c844b9 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)