Commit c7b1551e authored by Joel Holdsworth's avatar Joel Holdsworth Committed by Alexandre Julliard

ntdll: Initial implementation of FileRenameInformationEx.

parent 25db1c5d
...@@ -4783,13 +4783,23 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, ...@@ -4783,13 +4783,23 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
break; break;
case FileRenameInformation: case FileRenameInformation:
case FileRenameInformationEx:
if (len >= sizeof(FILE_RENAME_INFORMATION)) if (len >= sizeof(FILE_RENAME_INFORMATION))
{ {
FILE_RENAME_INFORMATION *info = ptr; FILE_RENAME_INFORMATION *info = ptr;
unsigned int flags;
UNICODE_STRING name_str, redir; UNICODE_STRING name_str, redir;
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
char *unix_name; char *unix_name;
if (class == FileRenameInformation)
flags = info->ReplaceIfExists ? FILE_RENAME_REPLACE_IF_EXISTS : 0;
else
flags = info->Flags;
if (flags & ~FILE_RENAME_REPLACE_IF_EXISTS)
FIXME( "unsupported flags: %#x\n", flags );
name_str.Buffer = info->FileName; name_str.Buffer = info->FileName;
name_str.Length = info->FileNameLength; name_str.Length = info->FileNameLength;
name_str.MaximumLength = info->FileNameLength + sizeof(WCHAR); name_str.MaximumLength = info->FileNameLength + sizeof(WCHAR);
...@@ -4805,7 +4815,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, ...@@ -4805,7 +4815,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
req->rootdir = wine_server_obj_handle( attr.RootDirectory ); req->rootdir = wine_server_obj_handle( attr.RootDirectory );
req->namelen = attr.ObjectName->Length; req->namelen = attr.ObjectName->Length;
req->link = FALSE; req->link = FALSE;
req->replace = info->ReplaceIfExists; req->flags = flags;
wine_server_add_data( req, attr.ObjectName->Buffer, attr.ObjectName->Length ); wine_server_add_data( req, attr.ObjectName->Buffer, attr.ObjectName->Length );
wine_server_add_data( req, unix_name, strlen(unix_name) ); wine_server_add_data( req, unix_name, strlen(unix_name) );
status = wine_server_call( req ); status = wine_server_call( req );
...@@ -4842,7 +4852,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, ...@@ -4842,7 +4852,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
req->rootdir = wine_server_obj_handle( attr.RootDirectory ); req->rootdir = wine_server_obj_handle( attr.RootDirectory );
req->namelen = attr.ObjectName->Length; req->namelen = attr.ObjectName->Length;
req->link = TRUE; req->link = TRUE;
req->replace = info->ReplaceIfExists; req->flags = info->ReplaceIfExists ? FILE_LINK_REPLACE_IF_EXISTS : 0;
wine_server_add_data( req, attr.ObjectName->Buffer, attr.ObjectName->Length ); wine_server_add_data( req, attr.ObjectName->Buffer, attr.ObjectName->Length );
wine_server_add_data( req, unix_name, strlen(unix_name) ); wine_server_add_data( req, unix_name, strlen(unix_name) );
status = wine_server_call( req ); status = wine_server_call( req );
......
...@@ -792,6 +792,7 @@ NTSTATUS WINAPI wow64_NtSetInformationFile( UINT *args ) ...@@ -792,6 +792,7 @@ NTSTATUS WINAPI wow64_NtSetInformationFile( UINT *args )
break; break;
case FileRenameInformation: /* FILE_RENAME_INFORMATION */ case FileRenameInformation: /* FILE_RENAME_INFORMATION */
case FileRenameInformationEx: /* FILE_RENAME_INFORMATION */
case FileLinkInformation: /* FILE_LINK_INFORMATION */ case FileLinkInformation: /* FILE_LINK_INFORMATION */
if (len >= sizeof(FILE_RENAME_INFORMATION32)) if (len >= sizeof(FILE_RENAME_INFORMATION32))
{ {
...@@ -807,7 +808,7 @@ NTSTATUS WINAPI wow64_NtSetInformationFile( UINT *args ) ...@@ -807,7 +808,7 @@ NTSTATUS WINAPI wow64_NtSetInformationFile( UINT *args )
get_file_redirect( &attr ); get_file_redirect( &attr );
size = offsetof( FILE_RENAME_INFORMATION, FileName[name.Length/sizeof(WCHAR)] ); size = offsetof( FILE_RENAME_INFORMATION, FileName[name.Length/sizeof(WCHAR)] );
info = Wow64AllocateTemp( size ); info = Wow64AllocateTemp( size );
info->ReplaceIfExists = info32->ReplaceIfExists; info->Flags = info32->Flags;
info->RootDirectory = attr.RootDirectory; info->RootDirectory = attr.RootDirectory;
info->FileNameLength = name.Length; info->FileNameLength = name.Length;
memcpy( info->FileName, name.Buffer, info->FileNameLength ); memcpy( info->FileName, name.Buffer, info->FileNameLength );
......
...@@ -94,7 +94,11 @@ typedef struct ...@@ -94,7 +94,11 @@ typedef struct
typedef struct typedef struct
{ {
BOOLEAN ReplaceIfExists; union
{
BOOLEAN ReplaceIfExists;
ULONG Flags;
};
ULONG RootDirectory; ULONG RootDirectory;
ULONG FileNameLength; ULONG FileNameLength;
WCHAR FileName[1]; WCHAR FileName[1];
......
...@@ -5307,7 +5307,7 @@ struct set_fd_name_info_request ...@@ -5307,7 +5307,7 @@ struct set_fd_name_info_request
obj_handle_t rootdir; obj_handle_t rootdir;
data_size_t namelen; data_size_t namelen;
int link; int link;
int replace; unsigned int flags;
/* VARARG(name,unicode_str,namelen); */ /* VARARG(name,unicode_str,namelen); */
/* VARARG(filename,string); */ /* VARARG(filename,string); */
}; };
...@@ -6487,7 +6487,7 @@ union generic_reply ...@@ -6487,7 +6487,7 @@ union generic_reply
/* ### protocol_version begin ### */ /* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 782 #define SERVER_PROTOCOL_VERSION 783
/* ### protocol_version end ### */ /* ### protocol_version end ### */
......
...@@ -2511,11 +2511,12 @@ static void set_fd_disposition( struct fd *fd, unsigned int flags ) ...@@ -2511,11 +2511,12 @@ static void set_fd_disposition( struct fd *fd, unsigned int flags )
/* set new name for the fd */ /* set new name for the fd */
static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, data_size_t len, static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, data_size_t len,
struct unicode_str nt_name, int create_link, int replace ) struct unicode_str nt_name, int create_link, unsigned int flags )
{ {
struct inode *inode; struct inode *inode;
struct stat st, st2; struct stat st, st2;
char *name; char *name;
const unsigned int replace = flags & FILE_RENAME_REPLACE_IF_EXISTS;
if (!fd->inode || !fd->unix_name) if (!fd->inode || !fd->unix_name)
{ {
...@@ -2967,7 +2968,7 @@ DECL_HANDLER(set_fd_name_info) ...@@ -2967,7 +2968,7 @@ DECL_HANDLER(set_fd_name_info)
if ((fd = get_handle_fd_obj( current->process, req->handle, 0 ))) if ((fd = get_handle_fd_obj( current->process, req->handle, 0 )))
{ {
set_fd_name( fd, root_fd, (const char *)get_req_data() + req->namelen, set_fd_name( fd, root_fd, (const char *)get_req_data() + req->namelen,
get_req_data_size() - req->namelen, nt_name, req->link, req->replace ); get_req_data_size() - req->namelen, nt_name, req->link, req->flags );
release_object( fd ); release_object( fd );
} }
if (root_fd) release_object( root_fd ); if (root_fd) release_object( root_fd );
......
...@@ -3692,7 +3692,7 @@ struct handle_info ...@@ -3692,7 +3692,7 @@ struct handle_info
obj_handle_t rootdir; /* root directory */ obj_handle_t rootdir; /* root directory */
data_size_t namelen; /* length of NT name in bytes */ data_size_t namelen; /* length of NT name in bytes */
int link; /* link instead of renaming */ int link; /* link instead of renaming */
int replace; /* replace an existing file? */ unsigned int flags; /* FILE_RENAME_* flags */
VARARG(name,unicode_str,namelen); /* NT name */ VARARG(name,unicode_str,namelen); /* NT name */
VARARG(filename,string); /* new file name */ VARARG(filename,string); /* new file name */
@END @END
......
...@@ -2241,7 +2241,7 @@ C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, handle) == 12 ); ...@@ -2241,7 +2241,7 @@ C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, rootdir) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, rootdir) == 16 );
C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, namelen) == 20 ); C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, namelen) == 20 );
C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, link) == 24 ); C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, link) == 24 );
C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, replace) == 28 ); C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, flags) == 28 );
C_ASSERT( sizeof(struct set_fd_name_info_request) == 32 ); C_ASSERT( sizeof(struct set_fd_name_info_request) == 32 );
C_ASSERT( FIELD_OFFSET(struct set_fd_eof_info_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct set_fd_eof_info_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct set_fd_eof_info_request, eof) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_fd_eof_info_request, eof) == 16 );
......
...@@ -4411,7 +4411,7 @@ static void dump_set_fd_name_info_request( const struct set_fd_name_info_request ...@@ -4411,7 +4411,7 @@ static void dump_set_fd_name_info_request( const struct set_fd_name_info_request
fprintf( stderr, ", rootdir=%04x", req->rootdir ); fprintf( stderr, ", rootdir=%04x", req->rootdir );
fprintf( stderr, ", namelen=%u", req->namelen ); fprintf( stderr, ", namelen=%u", req->namelen );
fprintf( stderr, ", link=%d", req->link ); fprintf( stderr, ", link=%d", req->link );
fprintf( stderr, ", replace=%d", req->replace ); fprintf( stderr, ", flags=%08x", req->flags );
dump_varargs_unicode_str( ", name=", min(cur_size,req->namelen) ); dump_varargs_unicode_str( ", name=", min(cur_size,req->namelen) );
dump_varargs_string( ", filename=", cur_size ); dump_varargs_string( ", filename=", cur_size );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment