Hi Vitaliy, This patch looks pretty good, but needs some finishing touches. Are you planning to continue the directory work to get objects to start supporting it? Vitaliy Margolen wrote:
diff --git a/server/object.h b/server/object.h index 0c2ee1a..1154e0a 100644 --- a/server/object.h +++ b/server/object.h @@ -193,6 +193,11 @@ extern obj_handle_t open_object_dir( str extern void init_directories(void); extern void close_directories(void);
+/* sybmolic link functions */ + +extern void init_syboliclinks(void); +extern void close_syboliclinks(void);
Multiple spelling mistakes.
+ /* global variables */
/* command-line options */
diff --git a/server/symlink.c b/server/symlink.c new file mode 100644 index 0000000..5a07df3 --- /dev/null +++ b/server/symlink.c @@ -0,0 +1,225 @@ +/* + * Server-side symbolic link object management + * + * Copyright (C) 2005 Vitaliy Margolen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include <assert.h> +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "winternl.h" +#include "ddk/wdm.h" + +#include "handle.h" +#include "request.h" +#include "object.h" +#include "unicode.h" + +struct syboliclink +{ + struct object obj; /* object header */ + struct unicode_str target; /* target of the symlink */ +};
Spelling mistake. In the server the name of the object struct typically mirrors the name of the file. So in this case it would be "struct symlink"
+ +static void syboliclink_dump( struct object *obj, int verbose ); +static struct object *symlink_lookup_name( struct object *obj, struct unicode_str *name, + unsigned int attr ); +static void syboliclink_destroy( struct object *obj );
Spelling mistakes and lack of consistency with the naming. They should have the name of the object as a prefix: symlink_dump, symlink_lookup_name, symlink_destroy.
+struct syboliclink *create_syboliclink( struct directory *root, const struct unicode_str *name, + unsigned int attr, const struct unicode_str *target )
Spelling mistake again. Also, should match whatever name is decided for the name of the object.
+ +/* Global initialization */ + +static struct syboliclink *link_dosdev, *link_global1, *link_global2, *link_local; + +void init_syboliclinks(void) +{ + static const WCHAR dir_globalW[] = {'\\','?','?'}; + static const WCHAR dir_basenamedW[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s'}; + static const struct unicode_str dir_global_str = {dir_globalW, sizeof(dir_globalW)}; + static const struct unicode_str dir_basenamed_str = {dir_basenamedW, sizeof(dir_basenamedW)}; + + static const WCHAR link_dosdevW[] = {'\\','D','o','s','D','e','v','i','c','e','s'}; + static const WCHAR link_global1W[] = {'\\','?','?','\\','G','l','o','b','a','l'}; + static const WCHAR link_global2W[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','G','l','o','b','a','l'}; + static const WCHAR link_localW[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','L','o','c','a','l'}; + static const struct unicode_str link_dosdev_str = {link_dosdevW, sizeof(link_dosdevW)}; + static const struct unicode_str link_global1_str = {link_global1W, sizeof(link_global1W)}; + static const struct unicode_str link_global2_str = {link_global2W, sizeof(link_global2W)}; + static const struct unicode_str link_local_str = {link_localW, sizeof(link_localW)}; + + link_dosdev = create_syboliclink( NULL, &link_dosdev_str, 0, &dir_global_str ); + link_global1 = create_syboliclink( NULL, &link_global1_str, 0, &dir_global_str ); + link_global2 = create_syboliclink( NULL, &link_global2_str, 0, &dir_basenamed_str ); + link_local = create_syboliclink( NULL, &link_local_str, 0, &dir_basenamed_str ); +} + +void close_syboliclinks(void) +{ + release_object( link_dosdev ); + release_object( link_global1 ); + release_object( link_global2 ); + release_object( link_local ); +}
It would probably be nicer to have all of the namespace initialisation done in one place, e.g. directory.c That would mean exporting the create_symlink function, but then init_symboliclinks and close_symboliclinks would no longer have to be exported.
+ + +/* create a symbolic link object */ +DECL_HANDLER(create_symlink) +{ + struct syboliclink *symlink; + struct unicode_str name, target; + struct directory *root = NULL; + + get_req_unicode_str( &name ); + target.str = name.str + req->symlink_name_len / sizeof(WCHAR); + target.len = name.len - req->symlink_name_len; + name.len = req->symlink_name_len; + + if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) + return;
Does NT really allow you to open a directory without having any specific access rights? -- Rob Shearman