server: Pass full object attributes in the create_symlink request.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
82800f513c
commit
426c4a2f08
@ -636,35 +636,31 @@ NTSTATUS WINAPI NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, IN ACCESS_MASK
|
|||||||
* Failure: An NTSTATUS error code.
|
* Failure: An NTSTATUS error code.
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle,IN ACCESS_MASK DesiredAccess,
|
NTSTATUS WINAPI NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle,IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
POBJECT_ATTRIBUTES attr, PUNICODE_STRING TargetName)
|
||||||
IN PUNICODE_STRING TargetName)
|
|
||||||
{
|
{
|
||||||
NTSTATUS ret;
|
NTSTATUS ret;
|
||||||
|
data_size_t len;
|
||||||
|
struct object_attributes *objattr;
|
||||||
|
|
||||||
if (!SymbolicLinkHandle || !TargetName) return STATUS_ACCESS_VIOLATION;
|
if (!SymbolicLinkHandle || !TargetName) return STATUS_ACCESS_VIOLATION;
|
||||||
if (!TargetName->Buffer) return STATUS_INVALID_PARAMETER;
|
if (!TargetName->Buffer) return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
TRACE("(%p,0x%08x,%s -> %s)\n", SymbolicLinkHandle, DesiredAccess,
|
TRACE("(%p,0x%08x,%s -> %s)\n", SymbolicLinkHandle, DesiredAccess,
|
||||||
debugstr_ObjectAttributes(ObjectAttributes), debugstr_us(TargetName));
|
debugstr_ObjectAttributes(attr), debugstr_us(TargetName));
|
||||||
|
|
||||||
|
if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
|
||||||
|
|
||||||
SERVER_START_REQ(create_symlink)
|
SERVER_START_REQ(create_symlink)
|
||||||
{
|
{
|
||||||
req->access = DesiredAccess;
|
req->access = DesiredAccess;
|
||||||
req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
|
wine_server_add_data( req, objattr, len );
|
||||||
req->rootdir = wine_server_obj_handle( ObjectAttributes ? ObjectAttributes->RootDirectory : 0 );
|
|
||||||
if (ObjectAttributes && ObjectAttributes->ObjectName)
|
|
||||||
{
|
|
||||||
req->name_len = ObjectAttributes->ObjectName->Length;
|
|
||||||
wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
|
|
||||||
ObjectAttributes->ObjectName->Length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
req->name_len = 0;
|
|
||||||
wine_server_add_data(req, TargetName->Buffer, TargetName->Length);
|
wine_server_add_data(req, TargetName->Buffer, TargetName->Length);
|
||||||
ret = wine_server_call( req );
|
ret = wine_server_call( req );
|
||||||
*SymbolicLinkHandle = wine_server_ptr_handle( reply->handle );
|
*SymbolicLinkHandle = wine_server_ptr_handle( reply->handle );
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, objattr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4760,12 +4760,8 @@ struct create_symlink_request
|
|||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
unsigned int access;
|
unsigned int access;
|
||||||
unsigned int attributes;
|
/* VARARG(objattr,object_attributes); */
|
||||||
obj_handle_t rootdir;
|
|
||||||
data_size_t name_len;
|
|
||||||
/* VARARG(name,unicode_str,name_len); */
|
|
||||||
/* VARARG(target_name,unicode_str); */
|
/* VARARG(target_name,unicode_str); */
|
||||||
char __pad_28[4];
|
|
||||||
};
|
};
|
||||||
struct create_symlink_reply
|
struct create_symlink_reply
|
||||||
{
|
{
|
||||||
|
@ -463,15 +463,15 @@ void init_directories(void)
|
|||||||
create_unix_device( dir_device, &null_str, "/dev/null" );
|
create_unix_device( dir_device, &null_str, "/dev/null" );
|
||||||
|
|
||||||
/* symlinks */
|
/* symlinks */
|
||||||
link_dosdev = create_symlink( root_directory, &link_dosdev_str, 0, &dir_global_str );
|
link_dosdev = create_symlink( root_directory, &link_dosdev_str, 0, &dir_global_str, NULL );
|
||||||
link_global1 = create_symlink( dir_global, &link_global_str, 0, &dir_global_str );
|
link_global1 = create_symlink( dir_global, &link_global_str, 0, &dir_global_str, NULL );
|
||||||
link_global2 = create_symlink( dir_basenamed, &link_global_str, 0, &dir_basenamed_str );
|
link_global2 = create_symlink( dir_basenamed, &link_global_str, 0, &dir_basenamed_str, NULL );
|
||||||
link_local = create_symlink( dir_basenamed, &link_local_str, 0, &dir_basenamed_str );
|
link_local = create_symlink( dir_basenamed, &link_local_str, 0, &dir_basenamed_str, NULL );
|
||||||
link_nul = create_symlink( dir_global, &link_nul_str, 0, &dir_null_str );
|
link_nul = create_symlink( dir_global, &link_nul_str, 0, &dir_null_str, NULL );
|
||||||
link_pipe = create_symlink( dir_global, &link_pipe_str, 0, &dir_named_pipe_str );
|
link_pipe = create_symlink( dir_global, &link_pipe_str, 0, &dir_named_pipe_str, NULL );
|
||||||
link_mailslot = create_symlink( dir_global, &link_mailslot_str, 0, &dir_mailslot_str );
|
link_mailslot = create_symlink( dir_global, &link_mailslot_str, 0, &dir_mailslot_str, NULL );
|
||||||
link_0 = create_symlink( dir_sessions, &link_0_str, 0, &dir_basenamed_str );
|
link_0 = create_symlink( dir_sessions, &link_0_str, 0, &dir_basenamed_str, NULL );
|
||||||
link_session = create_symlink( dir_basenamed, &link_session_str, 0, &link_sessions_str );
|
link_session = create_symlink( dir_basenamed, &link_session_str, 0, &link_sessions_str, NULL );
|
||||||
make_object_static( (struct object *)link_dosdev );
|
make_object_static( (struct object *)link_dosdev );
|
||||||
make_object_static( (struct object *)link_global1 );
|
make_object_static( (struct object *)link_global1 );
|
||||||
make_object_static( (struct object *)link_global2 );
|
make_object_static( (struct object *)link_global2 );
|
||||||
|
@ -222,7 +222,8 @@ extern void init_directories(void);
|
|||||||
/* symbolic link functions */
|
/* symbolic link functions */
|
||||||
|
|
||||||
extern struct symlink *create_symlink( struct directory *root, const struct unicode_str *name,
|
extern struct symlink *create_symlink( struct directory *root, const struct unicode_str *name,
|
||||||
unsigned int attr, const struct unicode_str *target );
|
unsigned int attr, const struct unicode_str *target,
|
||||||
|
const struct security_descriptor *sd );
|
||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
|
|
||||||
|
@ -3331,10 +3331,7 @@ struct handle_info
|
|||||||
/* Create a symbolic link object */
|
/* Create a symbolic link object */
|
||||||
@REQ(create_symlink)
|
@REQ(create_symlink)
|
||||||
unsigned int access; /* access flags */
|
unsigned int access; /* access flags */
|
||||||
unsigned int attributes; /* object attributes */
|
VARARG(objattr,object_attributes); /* object attributes */
|
||||||
obj_handle_t rootdir; /* root directory */
|
|
||||||
data_size_t name_len; /* length of the symlink name in bytes */
|
|
||||||
VARARG(name,unicode_str,name_len); /* symlink name */
|
|
||||||
VARARG(target_name,unicode_str); /* target name */
|
VARARG(target_name,unicode_str); /* target name */
|
||||||
@REPLY
|
@REPLY
|
||||||
obj_handle_t handle; /* handle to the symlink */
|
obj_handle_t handle; /* handle to the symlink */
|
||||||
|
@ -2110,10 +2110,7 @@ C_ASSERT( sizeof(struct get_directory_entry_request) == 24 );
|
|||||||
C_ASSERT( FIELD_OFFSET(struct get_directory_entry_reply, name_len) == 8 );
|
C_ASSERT( FIELD_OFFSET(struct get_directory_entry_reply, name_len) == 8 );
|
||||||
C_ASSERT( sizeof(struct get_directory_entry_reply) == 16 );
|
C_ASSERT( sizeof(struct get_directory_entry_reply) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_symlink_request, access) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct create_symlink_request, access) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_symlink_request, attributes) == 16 );
|
C_ASSERT( sizeof(struct create_symlink_request) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_symlink_request, rootdir) == 20 );
|
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_symlink_request, name_len) == 24 );
|
|
||||||
C_ASSERT( sizeof(struct create_symlink_request) == 32 );
|
|
||||||
C_ASSERT( FIELD_OFFSET(struct create_symlink_reply, handle) == 8 );
|
C_ASSERT( FIELD_OFFSET(struct create_symlink_reply, handle) == 8 );
|
||||||
C_ASSERT( sizeof(struct create_symlink_reply) == 16 );
|
C_ASSERT( sizeof(struct create_symlink_reply) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct open_symlink_request, access) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct open_symlink_request, access) == 12 );
|
||||||
|
@ -132,7 +132,8 @@ static void symlink_destroy( struct object *obj )
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct symlink *create_symlink( struct directory *root, const struct unicode_str *name,
|
struct symlink *create_symlink( struct directory *root, const struct unicode_str *name,
|
||||||
unsigned int attr, const struct unicode_str *target )
|
unsigned int attr, const struct unicode_str *target,
|
||||||
|
const struct security_descriptor *sd )
|
||||||
{
|
{
|
||||||
struct symlink *symlink;
|
struct symlink *symlink;
|
||||||
|
|
||||||
@ -145,7 +146,13 @@ struct symlink *create_symlink( struct directory *root, const struct unicode_str
|
|||||||
(get_error() != STATUS_OBJECT_NAME_EXISTS))
|
(get_error() != STATUS_OBJECT_NAME_EXISTS))
|
||||||
{
|
{
|
||||||
if ((symlink->target = memdup( target->str, target->len )))
|
if ((symlink->target = memdup( target->str, target->len )))
|
||||||
|
{
|
||||||
symlink->len = target->len;
|
symlink->len = target->len;
|
||||||
|
if (sd)
|
||||||
|
default_set_sd( &symlink->obj, sd,
|
||||||
|
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
|
||||||
|
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
release_object( symlink );
|
release_object( symlink );
|
||||||
@ -162,23 +169,20 @@ DECL_HANDLER(create_symlink)
|
|||||||
struct symlink *symlink;
|
struct symlink *symlink;
|
||||||
struct unicode_str name, target;
|
struct unicode_str name, target;
|
||||||
struct directory *root = NULL;
|
struct directory *root = NULL;
|
||||||
|
const struct security_descriptor *sd;
|
||||||
|
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
|
||||||
|
|
||||||
if (req->name_len > get_req_data_size())
|
if (!objattr) return;
|
||||||
|
|
||||||
|
target.str = (const WCHAR *)get_req_data() + sizeof(*objattr) / sizeof(WCHAR) +
|
||||||
|
objattr->sd_len / sizeof(WCHAR) + name.len / sizeof(WCHAR);
|
||||||
|
target.len = get_req_data_size() - ((const char *)target.str - (const char *)get_req_data());
|
||||||
|
|
||||||
|
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
|
||||||
|
|
||||||
|
if ((symlink = create_symlink( root, &name, objattr->attributes, &target, sd )))
|
||||||
{
|
{
|
||||||
set_error( STATUS_INVALID_PARAMETER );
|
reply->handle = alloc_handle( current->process, symlink, req->access, objattr->attributes );
|
||||||
return;
|
|
||||||
}
|
|
||||||
name.str = get_req_data();
|
|
||||||
target.str = name.str + req->name_len / sizeof(WCHAR);
|
|
||||||
name.len = (target.str - name.str) * sizeof(WCHAR);
|
|
||||||
target.len = ((get_req_data_size() - name.len) / sizeof(WCHAR)) * sizeof(WCHAR);
|
|
||||||
|
|
||||||
if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((symlink = create_symlink( root, &name, req->attributes, &target )))
|
|
||||||
{
|
|
||||||
reply->handle = alloc_handle( current->process, symlink, req->access, req->attributes );
|
|
||||||
release_object( symlink );
|
release_object( symlink );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user