ntdll: Use char pointers instead of ANSI/UNICODE_STRING in unix_to_nt_file_name().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-07-09 10:01:19 +02:00
parent 368e3a93b8
commit 5ebdeaaa37
4 changed files with 79 additions and 74 deletions

View File

@ -1057,16 +1057,14 @@ static void append_envW( WCHAR *env, SIZE_T *pos, const char *name, const WCHAR
/* set an environment variable for one of the wine path variables */
static void add_path_var( WCHAR *env, SIZE_T *pos, const char *name, const char *path )
{
UNICODE_STRING nt_name;
ANSI_STRING unix_name;
WCHAR *nt_name;
if (!path) append_envW( env, pos, name, NULL );
else
{
RtlInitAnsiString( &unix_name, path );
if (unix_to_nt_file_name( &unix_name, &nt_name )) return;
append_envW( env, pos, name, nt_name.Buffer );
RtlFreeUnicodeString( &nt_name );
if (unix_to_nt_file_name( path, &nt_name )) return;
append_envW( env, pos, name, nt_name );
RtlFreeHeap( GetProcessHeap(), 0, nt_name );
}
}
@ -1202,25 +1200,24 @@ void CDECL get_initial_directory( UNICODE_STRING *dir )
if (pwd)
{
ANSI_STRING unix_name;
UNICODE_STRING nt_name;
WCHAR *nt_name;
RtlInitAnsiString( &unix_name, pwd );
if (!unix_to_nt_file_name( &unix_name, &nt_name ))
if (!unix_to_nt_file_name( pwd, &nt_name ))
{
/* skip the \??\ prefix */
if (nt_name.Length > 6 * sizeof(WCHAR) && nt_name.Buffer[5] == ':')
ULONG len = wcslen( nt_name );
if (len > 6 && nt_name[5] == ':')
{
dir->Length = nt_name.Length - 4 * sizeof(WCHAR);
memcpy( dir->Buffer, nt_name.Buffer + 4, dir->Length );
dir->Length = (len - 4) * sizeof(WCHAR);
memcpy( dir->Buffer, nt_name + 4, dir->Length );
}
else /* change \??\ to \\?\ */
{
dir->Length = nt_name.Length;
memcpy( dir->Buffer, nt_name.Buffer, dir->Length );
dir->Length = len * sizeof(WCHAR);
memcpy( dir->Buffer, nt_name, dir->Length );
dir->Buffer[1] = '\\';
}
RtlFreeUnicodeString( &nt_name );
RtlFreeHeap( GetProcessHeap(), 0, nt_name );
}
}

View File

@ -1767,7 +1767,7 @@ static NTSTATUS fill_file_info( const struct stat *st, ULONG attr, void *ptr,
}
static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
static NTSTATUS server_get_unix_name( HANDLE handle, char **unix_name )
{
data_size_t size = 1024;
NTSTATUS ret;
@ -1777,7 +1777,6 @@ static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
{
name = RtlAllocateHeap( GetProcessHeap(), 0, size + 1 );
if (!name) return STATUS_NO_MEMORY;
unix_name->MaximumLength = size + 1;
SERVER_START_REQ( get_handle_unix_name )
{
@ -1791,8 +1790,7 @@ static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
if (!ret)
{
name[size] = 0;
unix_name->Buffer = name;
unix_name->Length = size;
*unix_name = name;
break;
}
RtlFreeHeap( GetProcessHeap(), 0, name );
@ -1801,15 +1799,15 @@ static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
return ret;
}
static NTSTATUS fill_name_info( const ANSI_STRING *unix_name, FILE_NAME_INFORMATION *info, LONG *name_len )
static NTSTATUS fill_name_info( const char *unix_name, FILE_NAME_INFORMATION *info, LONG *name_len )
{
UNICODE_STRING nt_name;
WCHAR *nt_name;
NTSTATUS status;
if (!(status = unix_to_nt_file_name( unix_name, &nt_name )))
{
const WCHAR *ptr = nt_name.Buffer;
const WCHAR *end = ptr + (nt_name.Length / sizeof(WCHAR));
const WCHAR *ptr = nt_name;
const WCHAR *end = ptr + wcslen( nt_name );
/* Skip the volume mount point. */
while (ptr != end && *ptr == '\\') ++ptr;
@ -1822,7 +1820,7 @@ static NTSTATUS fill_name_info( const ANSI_STRING *unix_name, FILE_NAME_INFORMAT
else *name_len = info->FileNameLength;
memcpy( info->FileName, ptr, *name_len );
RtlFreeUnicodeString( &nt_name );
RtlFreeHeap( GetProcessHeap(), 0, nt_name );
}
return status;
@ -1953,7 +1951,7 @@ static struct mountmgr_unix_drive *get_mountmgr_fs_info( HANDLE handle, int fd )
struct mountmgr_unix_drive *drive;
OBJECT_ATTRIBUTES attr;
UNICODE_STRING string;
ANSI_STRING unix_name;
char *unix_name;
IO_STATUS_BLOCK io;
HANDLE mountmgr;
NTSTATUS status;
@ -1962,8 +1960,8 @@ static struct mountmgr_unix_drive *get_mountmgr_fs_info( HANDLE handle, int fd )
if (server_get_unix_name( handle, &unix_name ))
return NULL;
letter = find_dos_device( unix_name.Buffer );
RtlFreeAnsiString( &unix_name );
letter = find_dos_device( unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
if (!(drive = RtlAllocateHeap( GetProcessHeap(), 0, 1024 )))
return NULL;
@ -3447,19 +3445,19 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, char *nam
/******************************************************************
* unix_to_nt_file_name
*/
NTSTATUS CDECL unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt )
NTSTATUS unix_to_nt_file_name( const char *name, WCHAR **nt )
{
static const WCHAR unix_prefixW[] = {'\\','?','?','\\','u','n','i','x',0};
WCHAR dos_prefixW[] = {'\\','?','?','\\','A',':','\\',0};
const WCHAR *prefix = unix_prefixW;
unsigned int lenW, lenA = name->Length;
const char *path = name->Buffer;
unsigned int lenW, lenA = strlen(name);
const char *path = name;
NTSTATUS status;
WCHAR *p;
WCHAR *p, *buffer;
int drive;
status = find_drive_rootA( &path, lenA, &drive );
lenA -= (path - name->Buffer);
lenA -= path - name;
if (status == STATUS_SUCCESS)
{
@ -3470,18 +3468,29 @@ NTSTATUS CDECL unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt
else if (status != STATUS_OBJECT_PATH_NOT_FOUND) return status;
lenW = wcslen( prefix );
if (!(nt->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, (lenA + lenW + 1) * sizeof(WCHAR) )))
if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0, (lenA + lenW + 1) * sizeof(WCHAR) )))
return STATUS_NO_MEMORY;
memcpy( nt->Buffer, prefix, lenW * sizeof(WCHAR) );
lenW += ntdll_umbstowcs( path, lenA, nt->Buffer + lenW, lenA );
nt->Buffer[lenW] = 0;
nt->Length = lenW * sizeof(WCHAR);
nt->MaximumLength = nt->Length + sizeof(WCHAR);
for (p = nt->Buffer; *p; p++) if (*p == '/') *p = '\\';
memcpy( buffer, prefix, lenW * sizeof(WCHAR) );
lenW += ntdll_umbstowcs( path, lenA, buffer + lenW, lenA );
buffer[lenW] = 0;
for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
*nt = buffer;
return STATUS_SUCCESS;
}
/******************************************************************
* wine_unix_to_nt_file_name
*/
NTSTATUS CDECL wine_unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt )
{
WCHAR *nt_name = NULL;
NTSTATUS status = unix_to_nt_file_name( name->Buffer, &nt_name );
if (nt_name) RtlInitUnicodeString( nt, nt_name );
return status;
}
/***********************************************************************
* unmount_device
*
@ -3974,7 +3983,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
case FileAllInformation:
{
FILE_ALL_INFORMATION *info = ptr;
ANSI_STRING unix_name;
char *unix_name;
if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = errno_to_status( errno );
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
@ -3991,8 +4000,8 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
info->ModeInformation.Mode = 0; /* FIXME */
info->AlignmentInformation.AlignmentRequirement = 1; /* FIXME */
io->u.Status = fill_name_info( &unix_name, &info->NameInformation, &name_len );
RtlFreeAnsiString( &unix_name );
io->u.Status = fill_name_info( unix_name, &info->NameInformation, &name_len );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
io->Information = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + name_len;
}
}
@ -4038,13 +4047,13 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
case FileNameInformation:
{
FILE_NAME_INFORMATION *info = ptr;
ANSI_STRING unix_name;
char *unix_name;
if (!(io->u.Status = server_get_unix_name( handle, &unix_name )))
{
LONG name_len = len - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
io->u.Status = fill_name_info( &unix_name, info, &name_len );
RtlFreeAnsiString( &unix_name );
io->u.Status = fill_name_info( unix_name, info, &name_len );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
io->Information = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + name_len;
}
}
@ -4052,14 +4061,14 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
case FileNetworkOpenInformation:
{
FILE_NETWORK_OPEN_INFORMATION *info = ptr;
ANSI_STRING unix_name;
char *unix_name;
if (!(io->u.Status = server_get_unix_name( handle, &unix_name )))
{
ULONG attributes;
struct stat st;
if (get_file_info( unix_name.Buffer, &st, &attributes ) == -1)
if (get_file_info( unix_name, &st, &attributes ) == -1)
io->u.Status = errno_to_status( errno );
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS;
@ -4079,7 +4088,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
info->EndOfFile = std.EndOfFile;
info->FileAttributes = basic.FileAttributes;
}
RtlFreeAnsiString( &unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
}
}
break;
@ -6384,29 +6393,29 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
case ObjectNameInformation:
{
OBJECT_NAME_INFORMATION *p = ptr;
ANSI_STRING unix_name;
char *unix_name;
WCHAR *nt_name;
/* first try as a file object */
if (!(status = server_get_unix_name( handle, &unix_name )))
{
UNICODE_STRING nt_name;
if (!(status = unix_to_nt_file_name( &unix_name, &nt_name )))
if (!(status = unix_to_nt_file_name( unix_name, &nt_name )))
{
ULONG size = (wcslen(nt_name) + 1) * sizeof(WCHAR);
if (len < sizeof(*p)) status = STATUS_INFO_LENGTH_MISMATCH;
else if (len < sizeof(*p) + nt_name.MaximumLength) status = STATUS_BUFFER_OVERFLOW;
else if (len < sizeof(*p) + size) status = STATUS_BUFFER_OVERFLOW;
else
{
p->Name.Buffer = (WCHAR *)(p + 1);
p->Name.Length = nt_name.Length;
p->Name.MaximumLength = nt_name.MaximumLength;
memcpy( p->Name.Buffer, nt_name.Buffer, nt_name.MaximumLength );
p->Name.Length = size - sizeof(WCHAR);
p->Name.MaximumLength = size;
wcscpy( p->Name.Buffer, nt_name );
}
if (used_len) *used_len = sizeof(*p) + nt_name.MaximumLength;
RtlFreeUnicodeString( &nt_name );
if (used_len) *used_len = sizeof(*p) + size;
RtlFreeHeap( GetProcessHeap(), 0, nt_name );
}
RtlFreeAnsiString( &unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
break;
}
else if (status != STATUS_OBJECT_TYPE_MISMATCH) break;

View File

@ -990,19 +990,21 @@ static inline char *prepend( char *buffer, const char *str, size_t len )
*
* Open a file for a new dll. Helper for find_dll_file.
*/
static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, void **module, pe_image_info_t *image_info )
static NTSTATUS open_dll_file( const WCHAR *name, void **module, pe_image_info_t *image_info )
{
struct builtin_module *builtin;
FILE_BASIC_INFORMATION info;
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
UNICODE_STRING nt_name;
LARGE_INTEGER size;
FILE_OBJECTID_BUFFER id;
SIZE_T len = 0;
NTSTATUS status;
HANDLE handle, mapping;
InitializeObjectAttributes( &attr, nt_name, OBJ_CASE_INSENSITIVE, 0, NULL );
RtlInitUnicodeString( &nt_name, name );
InitializeObjectAttributes( &attr, &nt_name, OBJ_CASE_INSENSITIVE, 0, NULL );
if ((status = NtOpenFile( &handle, GENERIC_READ | SYNCHRONIZE, &attr, &io,
FILE_SHARE_READ | FILE_SHARE_DELETE,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE )))
@ -1024,7 +1026,7 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, void **module, pe_image_
{
if (!memcmp( &builtin->id, id.ObjectId, sizeof(builtin->id) ))
{
TRACE( "%s is the same file as existing module %p\n", debugstr_w( nt_name->Buffer ),
TRACE( "%s is the same file as existing module %p\n", debugstr_w(name),
builtin->module );
NtClose( handle );
NtUnmapViewOfSection( NtCurrentProcess(), *module );
@ -1055,12 +1057,12 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, void **module, pe_image_
/* ignore non-builtins */
if (!(image_info->image_flags & IMAGE_FLAGS_WineBuiltin))
{
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_us(nt_name) );
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_w(name) );
status = STATUS_DLL_NOT_FOUND;
}
else if (image_info->cpu != client_cpu)
{
TRACE( "%s is for CPU %u, continuing search\n", debugstr_us(nt_name), image_info->cpu );
TRACE( "%s is for CPU %u, continuing search\n", debugstr_w(name), image_info->cpu );
status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
}
@ -1080,17 +1082,14 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, void **module, pe_image_
*/
static NTSTATUS open_builtin_file( char *name, void **module, pe_image_info_t *image_info )
{
ANSI_STRING strA;
UNICODE_STRING nt_name;
WCHAR *nt_name = NULL;
NTSTATUS status;
int fd;
nt_name.Buffer = NULL;
RtlInitAnsiString( &strA, name );
if ((status = unix_to_nt_file_name( &strA, &nt_name ))) return status;
if ((status = unix_to_nt_file_name( name, &nt_name ))) return status;
status = open_dll_file( &nt_name, module, image_info );
RtlFreeUnicodeString( &nt_name );
status = open_dll_file( nt_name, module, image_info );
RtlFreeHeap( GetProcessHeap(), 0, nt_name );
if (status != STATUS_DLL_NOT_FOUND) return status;
@ -1534,7 +1533,7 @@ static struct unix_funcs unix_funcs =
server_release_fd,
server_init_process_done,
wine_nt_to_unix_file_name,
unix_to_nt_file_name,
wine_unix_to_nt_file_name,
set_show_dot_files,
load_so_dll,
load_builtin_dll,

View File

@ -124,7 +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 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;
extern const char *home_dir DECLSPEC_HIDDEN;
@ -236,6 +235,7 @@ extern NTSTATUS tape_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTI
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 NTSTATUS unix_to_nt_file_name( const char *name, WCHAR **nt ) DECLSPEC_HIDDEN;
extern void init_files(void) DECLSPEC_HIDDEN;
extern void init_cpu_info(void) DECLSPEC_HIDDEN;