ntdll: Return a char pointer instead of an ANSI_STRING in nt_to_unix_file_name().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-07-09 09:57:57 +02:00
parent 461fc592ad
commit d0a16b7dc9
4 changed files with 76 additions and 65 deletions

View File

@ -2806,7 +2806,7 @@ void init_files(void)
*
* Get the Unix path of a DOS device.
*/
static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, ANSI_STRING *unix_name_ret )
static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, char **unix_name_ret )
{
struct stat st;
char *unix_name, *new_name, *dev;
@ -2841,9 +2841,7 @@ static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, ANSI_STRING *u
if (!stat( unix_name, &st ))
{
TRACE( "%s -> %s\n", debugstr_wn(name,name_len), debugstr_a(unix_name) );
unix_name_ret->Buffer = unix_name;
unix_name_ret->Length = strlen(unix_name);
unix_name_ret->MaximumLength = unix_len;
*unix_name_ret = unix_name;
return STATUS_SUCCESS;
}
if (!dev) break;
@ -2993,37 +2991,36 @@ static NTSTATUS find_drive_rootA( LPCSTR *ppath, unsigned int len, int *drive_re
*
* Recursively search directories from the dir queue for a given inode.
*/
static NTSTATUS find_file_id( ANSI_STRING *unix_name, ULONGLONG file_id, dev_t dev )
static NTSTATUS find_file_id( char **unix_name, ULONG *len, ULONGLONG file_id, dev_t dev )
{
unsigned int pos;
DIR *dir;
struct dirent *de;
NTSTATUS status;
struct stat st;
char *name = *unix_name;
while (!(status = next_dir_in_queue( unix_name->Buffer )))
while (!(status = next_dir_in_queue( name )))
{
if (!(dir = opendir( unix_name->Buffer ))) continue;
TRACE( "searching %s for %s\n", unix_name->Buffer, wine_dbgstr_longlong(file_id) );
pos = strlen( unix_name->Buffer );
if (pos + MAX_DIR_ENTRY_LEN >= unix_name->MaximumLength/sizeof(WCHAR))
if (!(dir = opendir( name ))) continue;
TRACE( "searching %s for %s\n", debugstr_a(name), wine_dbgstr_longlong(file_id) );
pos = strlen( name );
if (pos + MAX_DIR_ENTRY_LEN >= *len / sizeof(WCHAR))
{
char *new = RtlReAllocateHeap( GetProcessHeap(), 0, unix_name->Buffer,
unix_name->MaximumLength * 2 );
if (!new)
if (!(name = RtlReAllocateHeap( GetProcessHeap(), 0, name, *len * 2 )))
{
closedir( dir );
return STATUS_NO_MEMORY;
}
unix_name->MaximumLength *= 2;
unix_name->Buffer = new;
*len *= 2;
*unix_name = name;
}
unix_name->Buffer[pos++] = '/';
name[pos++] = '/';
while ((de = readdir( dir )))
{
if (!strcmp( de->d_name, "." ) || !strcmp( de->d_name, ".." )) continue;
strcpy( unix_name->Buffer + pos, de->d_name );
if (lstat( unix_name->Buffer, &st ) == -1) continue;
strcpy( name + pos, de->d_name );
if (lstat( name, &st ) == -1) continue;
if (st.st_dev != dev) continue;
if (st.st_ino == file_id)
{
@ -3031,7 +3028,7 @@ static NTSTATUS find_file_id( ANSI_STRING *unix_name, ULONGLONG file_id, dev_t d
return STATUS_SUCCESS;
}
if (!S_ISDIR( st.st_mode )) continue;
if ((status = add_dir_to_queue( unix_name->Buffer )) != STATUS_SUCCESS)
if ((status = add_dir_to_queue( name )) != STATUS_SUCCESS)
{
closedir( dir );
return status;
@ -3048,10 +3045,12 @@ static NTSTATUS find_file_id( ANSI_STRING *unix_name, ULONGLONG file_id, dev_t d
*
* Lookup a file from its file id instead of its name.
*/
static NTSTATUS file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name )
static NTSTATUS file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **unix_name_ret )
{
enum server_fd_type type;
int old_cwd, root_fd, needs_close;
char *unix_name;
ULONG len;
NTSTATUS status;
ULONGLONG file_id;
struct stat st, root_st;
@ -3060,10 +3059,9 @@ static NTSTATUS file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, ANSI_S
if (!attr->RootDirectory) return STATUS_INVALID_PARAMETER;
memcpy( &file_id, attr->ObjectName->Buffer, sizeof(file_id) );
unix_name->MaximumLength = 2 * MAX_DIR_ENTRY_LEN + 4;
if (!(unix_name->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, unix_name->MaximumLength )))
return STATUS_NO_MEMORY;
strcpy( unix_name->Buffer, "." );
len = 2 * MAX_DIR_ENTRY_LEN + 4;
if (!(unix_name = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return STATUS_NO_MEMORY;
strcpy( unix_name, "." );
if ((status = server_get_unix_fd( attr->RootDirectory, 0, &root_fd, &needs_close, &type, NULL )))
goto done;
@ -3087,16 +3085,16 @@ static NTSTATUS file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, ANSI_S
/* shortcut for ".." */
if (!stat( "..", &st ) && st.st_dev == root_st.st_dev && st.st_ino == file_id)
{
strcpy( unix_name->Buffer, ".." );
strcpy( unix_name, ".." );
status = STATUS_SUCCESS;
}
else
{
status = add_dir_to_queue( "." );
if (!status)
status = find_file_id( unix_name, file_id, root_st.st_dev );
status = find_file_id( &unix_name, &len, file_id, root_st.st_dev );
if (!status) /* get rid of "./" prefix */
memmove( unix_name->Buffer, unix_name->Buffer + 2, strlen(unix_name->Buffer) - 1 );
memmove( unix_name, unix_name + 2, strlen(unix_name) - 1 );
flush_dir_queue();
}
if (fchdir( old_cwd ) == -1) chdir( "/" );
@ -3108,13 +3106,13 @@ static NTSTATUS file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, ANSI_S
done:
if (status == STATUS_SUCCESS)
{
TRACE( "%s -> %s\n", wine_dbgstr_longlong(file_id), debugstr_a(unix_name->Buffer) );
unix_name->Length = strlen( unix_name->Buffer );
TRACE( "%s -> %s\n", wine_dbgstr_longlong(file_id), debugstr_a(unix_name) );
*unix_name_ret = unix_name;
}
else
{
TRACE( "%s not found in dir %p\n", wine_dbgstr_longlong(file_id), attr->RootDirectory );
RtlFreeHeap( GetProcessHeap(), 0, unix_name->Buffer );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
}
if (needs_close) close( root_fd );
return status;
@ -3238,7 +3236,7 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
/******************************************************************************
* nt_to_unix_file_name_attr
*/
static NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name_ret,
static NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, char **name_ret,
UINT disposition )
{
static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 };
@ -3250,7 +3248,7 @@ static NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
NTSTATUS status;
if (!attr->RootDirectory) /* without root dir fall back to normal lookup */
return nt_to_unix_file_name( attr->ObjectName, unix_name_ret, disposition );
return nt_to_unix_file_name( attr->ObjectName, name_ret, disposition );
name = attr->ObjectName->Buffer;
name_len = attr->ObjectName->Length / sizeof(WCHAR);
@ -3293,9 +3291,7 @@ static NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)
{
TRACE( "%s -> %s\n", debugstr_us(attr->ObjectName), debugstr_a(unix_name) );
unix_name_ret->Buffer = unix_name;
unix_name_ret->Length = strlen(unix_name);
unix_name_ret->MaximumLength = unix_len;
*name_ret = unix_name;
}
else
{
@ -3315,8 +3311,7 @@ static NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
* element doesn't have to exist; in that case STATUS_NO_SUCH_FILE is
* returned, but the unix name is still filled in properly.
*/
NTSTATUS CDECL nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
UINT disposition )
NTSTATUS nt_to_unix_file_name( const UNICODE_STRING *nameW, char **unix_name_ret, UINT disposition )
{
static const WCHAR unixW[] = {'u','n','i','x'};
static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 };
@ -3412,9 +3407,7 @@ NTSTATUS CDECL nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *u
if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)
{
TRACE( "%s -> %s\n", debugstr_us(nameW), debugstr_a(unix_name) );
unix_name_ret->Buffer = unix_name;
unix_name_ret->Length = strlen(unix_name);
unix_name_ret->MaximumLength = unix_len;
*unix_name_ret = unix_name;
}
else
{
@ -3425,6 +3418,25 @@ NTSTATUS CDECL nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *u
}
/******************************************************************************
* wine_nt_to_unix_file_name
*
* Convert a file name from NT namespace to Unix namespace.
*
* If disposition is not FILE_OPEN or FILE_OVERWRITE, the last path
* element doesn't have to exist; in that case STATUS_NO_SUCH_FILE is
* returned, but the unix name is still filled in properly.
*/
NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
UINT disposition )
{
char *buffer = NULL;
NTSTATUS status = nt_to_unix_file_name( nameW, &buffer, disposition );
if (buffer) RtlInitAnsiString( unix_name_ret, buffer );
return status;
}
/******************************************************************
* unix_to_nt_file_name
*/
@ -3528,7 +3540,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
ULONG attributes, ULONG sharing, ULONG disposition,
ULONG options, void *ea_buffer, ULONG ea_length )
{
ANSI_STRING unix_name;
char *unix_name;
BOOL created = FALSE;
TRACE( "handle=%p access=%08x name=%s objattr=%08x root=%p sec=%p io=%p alloc_size=%p "
@ -3580,7 +3592,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
unix_attr.ObjectName = &empty_string; /* we send the unix name instead */
if ((io->u.Status = alloc_object_attributes( &unix_attr, &objattr, &len )))
{
RtlFreeAnsiString( &unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
return io->u.Status;
}
SERVER_START_REQ( create_file )
@ -3591,13 +3603,13 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
req->options = options;
req->attrs = attributes;
wine_server_add_data( req, objattr, len );
wine_server_add_data( req, unix_name.Buffer, unix_name.Length );
wine_server_add_data( req, unix_name, strlen(unix_name) );
io->u.Status = wine_server_call( req );
*handle = wine_server_ptr_handle( reply->handle );
}
SERVER_END_REQ;
free( objattr );
RtlFreeAnsiString( &unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
}
else WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), io->u.Status );
@ -3747,7 +3759,7 @@ NTSTATUS WINAPI NtDeleteFile( OBJECT_ATTRIBUTES *attr )
NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
FILE_NETWORK_OPEN_INFORMATION *info )
{
ANSI_STRING unix_name;
char *unix_name;
NTSTATUS status;
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
@ -3755,7 +3767,7 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
ULONG attributes;
struct stat st;
if (get_file_info( unix_name.Buffer, &st, &attributes ) == -1)
if (get_file_info( unix_name, &st, &attributes ) == -1)
status = errno_to_status( errno );
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
@ -3776,7 +3788,7 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
info->FileAttributes = basic.FileAttributes;
if (is_hidden_file( attr->ObjectName )) info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
}
RtlFreeAnsiString( &unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
}
else WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), status );
return status;
@ -3788,7 +3800,7 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
*/
NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC_INFORMATION *info )
{
ANSI_STRING unix_name;
char *unix_name;
NTSTATUS status;
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
@ -3796,7 +3808,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
ULONG attributes;
struct stat st;
if (get_file_info( unix_name.Buffer, &st, &attributes ) == -1)
if (get_file_info( unix_name, &st, &attributes ) == -1)
status = errno_to_status( errno );
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
@ -3805,7 +3817,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
status = fill_file_info( &st, attributes, info, FileBasicInformation );
if (is_hidden_file( attr->ObjectName )) info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
}
RtlFreeAnsiString( &unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
}
else WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), status );
return status;
@ -4345,7 +4357,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
FILE_RENAME_INFORMATION *info = ptr;
UNICODE_STRING name_str;
OBJECT_ATTRIBUTES attr;
ANSI_STRING unix_name;
char *unix_name;
name_str.Buffer = info->FileName;
name_str.Length = info->FileNameLength;
@ -4366,12 +4378,12 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
req->rootdir = wine_server_obj_handle( attr.RootDirectory );
req->link = FALSE;
req->replace = info->ReplaceIfExists;
wine_server_add_data( req, unix_name.Buffer, unix_name.Length );
wine_server_add_data( req, unix_name, strlen(unix_name) );
io->u.Status = wine_server_call( req );
}
SERVER_END_REQ;
RtlFreeAnsiString( &unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
}
else io->u.Status = STATUS_INVALID_PARAMETER_3;
break;
@ -4382,7 +4394,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
FILE_LINK_INFORMATION *info = ptr;
UNICODE_STRING name_str;
OBJECT_ATTRIBUTES attr;
ANSI_STRING unix_name;
char *unix_name;
name_str.Buffer = info->FileName;
name_str.Length = info->FileNameLength;
@ -4403,12 +4415,12 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
req->rootdir = wine_server_obj_handle( attr.RootDirectory );
req->link = TRUE;
req->replace = info->ReplaceIfExists;
wine_server_add_data( req, unix_name.Buffer, unix_name.Length );
wine_server_add_data( req, unix_name, strlen(unix_name) );
io->u.Status = wine_server_call( req );
}
SERVER_END_REQ;
RtlFreeAnsiString( &unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
}
else io->u.Status = STATUS_INVALID_PARAMETER_3;
break;

View File

@ -927,7 +927,7 @@ already_loaded:
static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
{
static const WCHAR soW[] = {'.','s','o',0};
ANSI_STRING unix_name;
char *unix_name;
NTSTATUS status;
DWORD len;
@ -937,8 +937,8 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
len = nt_name->Length / sizeof(WCHAR);
if (len > 3 && !wcsicmp( nt_name->Buffer + len - 3, soW )) nt_name->Length -= 3 * sizeof(WCHAR);
status = dlopen_dll( unix_name.Buffer, module );
RtlFreeAnsiString( &unix_name );
status = dlopen_dll( unix_name, module );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
return status;
}
@ -1533,7 +1533,7 @@ static struct unix_funcs unix_funcs =
server_handle_to_fd,
server_release_fd,
server_init_process_done,
nt_to_unix_file_name,
wine_nt_to_unix_file_name,
unix_to_nt_file_name,
set_show_dot_files,
load_so_dll,

View File

@ -662,7 +662,7 @@ static NTSTATUS fork_and_exec( UNICODE_STRING *path, int unixdir,
pid_t pid;
int fd[2], stdin_fd = -1, stdout_fd = -1;
char **argv, **envp;
ANSI_STRING unix_name;
char *unix_name;
NTSTATUS status;
status = nt_to_unix_file_name( path, &unix_name, FILE_OPEN );
@ -712,7 +712,7 @@ static NTSTATUS fork_and_exec( UNICODE_STRING *path, int unixdir,
fchdir( unixdir );
close( unixdir );
}
execve( unix_name.Buffer, argv, envp );
execve( unix_name, argv, envp );
}
if (pid <= 0) /* grandchild if exec failed or child if fork failed */
@ -750,7 +750,7 @@ static NTSTATUS fork_and_exec( UNICODE_STRING *path, int unixdir,
if (stdin_fd != -1) close( stdin_fd );
if (stdout_fd != -1) close( stdout_fd );
done:
RtlFreeAnsiString( &unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
return status;
}

View File

@ -124,8 +124,6 @@ extern NTSTATUS CDECL exec_process( UNICODE_STRING *path, UNICODE_STRING *cmdlin
extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
CONTEXT *context ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
UINT disposition ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt ) DECLSPEC_HIDDEN;
extern void CDECL set_show_dot_files( BOOL enable ) DECLSPEC_HIDDEN;
@ -237,6 +235,7 @@ extern NTSTATUS tape_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTI
ULONG in_size, void *out_buffer, ULONG out_size ) DECLSPEC_HIDDEN;
extern NTSTATUS errno_to_status( int err ) DECLSPEC_HIDDEN;
extern NTSTATUS nt_to_unix_file_name( const UNICODE_STRING *nameW, char **name_ret, UINT disposition ) DECLSPEC_HIDDEN;
extern void init_files(void) DECLSPEC_HIDDEN;
extern void init_cpu_info(void) DECLSPEC_HIDDEN;