ntdll: Add a helper function to open a file from its Unix path.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-07-10 07:56:02 +02:00
parent a2e77268f2
commit 9ec262ebcc
3 changed files with 53 additions and 47 deletions

View File

@ -3528,6 +3528,42 @@ void CDECL set_show_dot_files( BOOL enable )
}
/******************************************************************************
* open_unix_file
*
* Helper for NtCreateFile that takes a Unix path.
*/
NTSTATUS open_unix_file( HANDLE *handle, const char *unix_name, ACCESS_MASK access,
OBJECT_ATTRIBUTES *attr, ULONG attributes, ULONG sharing, ULONG disposition,
ULONG options, void *ea_buffer, ULONG ea_length )
{
static UNICODE_STRING empty_string;
struct object_attributes *objattr;
OBJECT_ATTRIBUTES unix_attr = *attr;
NTSTATUS status;
data_size_t len;
unix_attr.ObjectName = &empty_string; /* we send the unix name instead */
if ((status = alloc_object_attributes( &unix_attr, &objattr, &len ))) return status;
SERVER_START_REQ( create_file )
{
req->access = access;
req->sharing = sharing;
req->create = disposition;
req->options = options;
req->attrs = attributes;
wine_server_add_data( req, objattr, len );
wine_server_add_data( req, unix_name, strlen(unix_name) );
status = wine_server_call( req );
*handle = wine_server_ptr_handle( reply->handle );
}
SERVER_END_REQ;
free( objattr );
return status;
}
/******************************************************************************
* NtCreateFile (NTDLL.@)
*/
@ -3580,31 +3616,8 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
if (io->u.Status == STATUS_SUCCESS)
{
static UNICODE_STRING empty_string;
OBJECT_ATTRIBUTES unix_attr = *attr;
data_size_t len;
struct object_attributes *objattr;
unix_attr.ObjectName = &empty_string; /* we send the unix name instead */
if ((io->u.Status = alloc_object_attributes( &unix_attr, &objattr, &len )))
{
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
return io->u.Status;
}
SERVER_START_REQ( create_file )
{
req->access = access;
req->sharing = sharing;
req->create = disposition;
req->options = options;
req->attrs = attributes;
wine_server_add_data( req, objattr, len );
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 );
io->u.Status = open_unix_file( handle, unix_name, access, attr, attributes,
sharing, disposition, options, ea_buffer, ea_length );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
}
else WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), io->u.Status );

View File

@ -990,31 +990,26 @@ 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( const WCHAR *name, void **module, pe_image_info_t *image_info )
static NTSTATUS open_dll_file( const char *name, void **module, pe_image_info_t *image_info )
{
struct builtin_module *builtin;
FILE_BASIC_INFORMATION info;
OBJECT_ATTRIBUTES attr;
OBJECT_ATTRIBUTES attr = { sizeof(attr) };
IO_STATUS_BLOCK io;
UNICODE_STRING nt_name;
LARGE_INTEGER size;
FILE_OBJECTID_BUFFER id;
struct stat st;
SIZE_T len = 0;
NTSTATUS status;
HANDLE handle, mapping;
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 )))
if ((status = open_unix_file( &handle, name, GENERIC_READ | SYNCHRONIZE, &attr, 0,
FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0 )))
{
if (status != STATUS_OBJECT_PATH_NOT_FOUND &&
status != STATUS_OBJECT_NAME_NOT_FOUND &&
!NtQueryAttributesFile( &attr, &info ))
if (status != STATUS_OBJECT_PATH_NOT_FOUND && status != STATUS_OBJECT_NAME_NOT_FOUND)
{
/* if the file exists but failed to open, report the error */
return status;
if (!stat( name, &st )) return status;
}
/* otherwise continue searching */
return STATUS_DLL_NOT_FOUND;
@ -1026,7 +1021,7 @@ static NTSTATUS open_dll_file( const WCHAR *name, void **module, pe_image_info_t
{
if (!memcmp( &builtin->id, id.ObjectId, sizeof(builtin->id) ))
{
TRACE( "%s is the same file as existing module %p\n", debugstr_w(name),
TRACE( "%s is the same file as existing module %p\n", debugstr_a(name),
builtin->module );
NtClose( handle );
NtUnmapViewOfSection( NtCurrentProcess(), *module );
@ -1057,12 +1052,12 @@ static NTSTATUS open_dll_file( const WCHAR *name, void **module, pe_image_info_t
/* ignore non-builtins */
if (!(image_info->image_flags & IMAGE_FLAGS_WineBuiltin))
{
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_w(name) );
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_a(name) );
status = STATUS_DLL_NOT_FOUND;
}
else if (image_info->cpu != client_cpu)
{
TRACE( "%s is for CPU %u, continuing search\n", debugstr_w(name), image_info->cpu );
TRACE( "%s is for CPU %u, continuing search\n", debugstr_a(name), image_info->cpu );
status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
}
@ -1082,15 +1077,10 @@ static NTSTATUS open_dll_file( const WCHAR *name, void **module, pe_image_info_t
*/
static NTSTATUS open_builtin_file( char *name, void **module, pe_image_info_t *image_info )
{
WCHAR *nt_name = NULL;
NTSTATUS status;
int fd;
if ((status = unix_to_nt_file_name( name, &nt_name ))) return status;
status = open_dll_file( nt_name, module, image_info );
RtlFreeHeap( GetProcessHeap(), 0, nt_name );
status = open_dll_file( name, module, image_info );
if (status != STATUS_DLL_NOT_FOUND) return status;
/* try .so file */

View File

@ -237,6 +237,9 @@ 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 NTSTATUS open_unix_file( HANDLE *handle, const char *unix_name, ACCESS_MASK access,
OBJECT_ATTRIBUTES *attr, ULONG attributes, ULONG sharing, ULONG disposition,
ULONG options, void *ea_buffer, ULONG ea_length ) DECLSPEC_HIDDEN;
extern void init_files(void) DECLSPEC_HIDDEN;
extern void init_cpu_info(void) DECLSPEC_HIDDEN;