ntdll: Use FSCTL_GET_OBJECT_ID to compare file identities.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
251335cdf3
commit
9e3893cc29
|
@ -37,6 +37,7 @@
|
|||
#define NONAMELESSSTRUCT
|
||||
#include "windef.h"
|
||||
#include "winnt.h"
|
||||
#include "winioctl.h"
|
||||
#include "winternl.h"
|
||||
#include "delayloadhandler.h"
|
||||
|
||||
|
@ -122,12 +123,16 @@ static const char * const reason_names[] =
|
|||
|
||||
static const WCHAR dllW[] = {'.','d','l','l',0};
|
||||
|
||||
/* internal representation of 32bit modules. per process. */
|
||||
struct file_id
|
||||
{
|
||||
BYTE ObjectId[16];
|
||||
};
|
||||
|
||||
/* internal representation of loaded modules */
|
||||
typedef struct _wine_modref
|
||||
{
|
||||
LDR_DATA_TABLE_ENTRY ldr;
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
struct file_id id;
|
||||
void *so_handle;
|
||||
int alloc_deps;
|
||||
int nDeps;
|
||||
|
@ -554,12 +559,11 @@ static WINE_MODREF *find_fullname_module( const UNICODE_STRING *nt_name )
|
|||
* Find a module from its file id.
|
||||
* The loader_section must be locked while calling this function
|
||||
*/
|
||||
static WINE_MODREF *find_fileid_module( struct stat *st )
|
||||
static WINE_MODREF *find_fileid_module( const struct file_id *id )
|
||||
{
|
||||
LIST_ENTRY *mark, *entry;
|
||||
|
||||
if (cached_modref && cached_modref->dev == st->st_dev && cached_modref->ino == st->st_ino)
|
||||
return cached_modref;
|
||||
if (cached_modref && !memcmp( &cached_modref->id, id, sizeof(*id) )) return cached_modref;
|
||||
|
||||
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||
|
@ -567,7 +571,7 @@ static WINE_MODREF *find_fileid_module( struct stat *st )
|
|||
LDR_DATA_TABLE_ENTRY *mod = CONTAINING_RECORD( entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks );
|
||||
WINE_MODREF *wm = CONTAINING_RECORD( mod, WINE_MODREF, ldr );
|
||||
|
||||
if (wm->dev == st->st_dev && wm->ino == st->st_ino)
|
||||
if (!memcmp( &wm->id, id, sizeof(*id) ))
|
||||
{
|
||||
cached_modref = wm;
|
||||
return wm;
|
||||
|
@ -2303,16 +2307,16 @@ static NTSTATUS get_dll_load_path_search_flags( LPCWSTR module, DWORD flags, WCH
|
|||
* Open a file for a new dll. Helper for find_dll_file.
|
||||
*/
|
||||
static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, WINE_MODREF **pwm,
|
||||
void **module, pe_image_info_t *image_info, struct stat *st )
|
||||
void **module, pe_image_info_t *image_info, struct file_id *id )
|
||||
{
|
||||
FILE_BASIC_INFORMATION info;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
LARGE_INTEGER size;
|
||||
FILE_OBJECTID_BUFFER fid;
|
||||
SIZE_T len = 0;
|
||||
NTSTATUS status;
|
||||
HANDLE handle, mapping;
|
||||
int fd, needs_close;
|
||||
|
||||
if ((*pwm = find_fullname_module( nt_name )))
|
||||
{
|
||||
|
@ -2342,11 +2346,10 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, WINE_MODREF **pwm,
|
|||
return STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!unix_funcs->server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))
|
||||
if (!NtFsControlFile( handle, 0, NULL, NULL, &io, FSCTL_GET_OBJECT_ID, NULL, 0, &fid, sizeof(fid) ))
|
||||
{
|
||||
fstat( fd, st );
|
||||
if (needs_close) close( fd );
|
||||
if ((*pwm = find_fileid_module( st )))
|
||||
memcpy( id, fid.ObjectId, sizeof(*id) );
|
||||
if ((*pwm = find_fileid_module( id )))
|
||||
{
|
||||
TRACE( "%s is the same file as existing module %p %s\n", debugstr_w( nt_name->Buffer ),
|
||||
(*pwm)->ldr.DllBase, debugstr_w( (*pwm)->ldr.FullDllName.Buffer ));
|
||||
|
@ -2390,8 +2393,8 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, WINE_MODREF **pwm,
|
|||
* load_native_dll (internal)
|
||||
*/
|
||||
static NTSTATUS load_native_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name, void **module,
|
||||
const pe_image_info_t *image_info, DWORD flags, WINE_MODREF** pwm,
|
||||
struct stat *st )
|
||||
const pe_image_info_t *image_info, const struct file_id *id,
|
||||
DWORD flags, WINE_MODREF** pwm )
|
||||
{
|
||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( *module );
|
||||
WINE_MODREF *wm;
|
||||
|
@ -2409,8 +2412,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, const UNICODE_STRING *nt_nam
|
|||
if (!(wm = alloc_module( *module, nt_name, (image_info->image_flags & IMAGE_FLAGS_WineBuiltin) )))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
wm->dev = st->st_dev;
|
||||
wm->ino = st->st_ino;
|
||||
wm->id = *id;
|
||||
if (image_info->loader_flags) wm->ldr.Flags |= LDR_COR_IMAGE;
|
||||
if (image_info->image_flags & IMAGE_FLAGS_ComPlusILOnly) wm->ldr.Flags |= LDR_COR_ILONLY;
|
||||
|
||||
|
@ -2521,7 +2523,7 @@ static inline char *prepend( char *buffer, const char *str, size_t len )
|
|||
* open_builtin_file
|
||||
*/
|
||||
static NTSTATUS open_builtin_file( char *name, WINE_MODREF **pwm, void **module,
|
||||
pe_image_info_t *image_info, struct stat *st, char **so_name )
|
||||
pe_image_info_t *image_info, struct file_id *id, char **so_name )
|
||||
{
|
||||
ANSI_STRING strA;
|
||||
UNICODE_STRING nt_name;
|
||||
|
@ -2532,7 +2534,7 @@ static NTSTATUS open_builtin_file( char *name, WINE_MODREF **pwm, void **module,
|
|||
RtlInitString( &strA, name );
|
||||
if ((status = wine_unix_to_nt_file_name( &strA, &nt_name ))) return status;
|
||||
|
||||
status = open_dll_file( &nt_name, pwm, module, image_info, st );
|
||||
status = open_dll_file( &nt_name, pwm, module, image_info, id );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
|
||||
/* ignore non-builtins */
|
||||
|
@ -2569,9 +2571,8 @@ static NTSTATUS open_builtin_file( char *name, WINE_MODREF **pwm, void **module,
|
|||
/***********************************************************************
|
||||
* find_builtin_dll
|
||||
*/
|
||||
static NTSTATUS find_builtin_dll( const WCHAR *name, WINE_MODREF **pwm,
|
||||
void **module, pe_image_info_t *image_info, struct stat *st,
|
||||
char **so_name )
|
||||
static NTSTATUS find_builtin_dll( const WCHAR *name, WINE_MODREF **pwm, void **module,
|
||||
pe_image_info_t *image_info, struct file_id *id, char **so_name )
|
||||
{
|
||||
unsigned int i, pos, len, namelen, maxlen = 0;
|
||||
char *ptr, *file;
|
||||
|
@ -2608,7 +2609,7 @@ static NTSTATUS find_builtin_dll( const WCHAR *name, WINE_MODREF **pwm,
|
|||
ptr = prepend( ptr, ptr, namelen );
|
||||
ptr = prepend( ptr, "/dlls", sizeof("/dlls") - 1 );
|
||||
ptr = prepend( ptr, build_dir, strlen(build_dir) );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, st, so_name );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, id, so_name );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
|
||||
/* now as a program */
|
||||
|
@ -2619,7 +2620,7 @@ static NTSTATUS find_builtin_dll( const WCHAR *name, WINE_MODREF **pwm,
|
|||
ptr = prepend( ptr, ptr, namelen );
|
||||
ptr = prepend( ptr, "/programs", sizeof("/programs") - 1 );
|
||||
ptr = prepend( ptr, build_dir, strlen(build_dir) );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, st, so_name );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, id, so_name );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
}
|
||||
|
||||
|
@ -2627,7 +2628,7 @@ static NTSTATUS find_builtin_dll( const WCHAR *name, WINE_MODREF **pwm,
|
|||
{
|
||||
file[pos + len + 1] = 0;
|
||||
ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, st, so_name );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, id, so_name );
|
||||
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE;
|
||||
else if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
}
|
||||
|
@ -2760,7 +2761,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, const UNICODE_STRING *nt_na
|
|||
NTSTATUS status;
|
||||
void *module = NULL;
|
||||
pe_image_info_t image_info;
|
||||
struct stat st;
|
||||
struct file_id id;
|
||||
char *so_name;
|
||||
|
||||
/* Fix the name in case we have a full path and extension */
|
||||
|
@ -2772,7 +2773,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, const UNICODE_STRING *nt_na
|
|||
|
||||
if (!module_ptr) module_ptr = &module;
|
||||
|
||||
status = find_builtin_dll( name, pwm, module_ptr, &image_info, &st, &so_name );
|
||||
status = find_builtin_dll( name, pwm, module_ptr, &image_info, &id, &so_name );
|
||||
if (status) return status;
|
||||
|
||||
if (*pwm)
|
||||
|
@ -2787,7 +2788,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, const UNICODE_STRING *nt_na
|
|||
if (*module_ptr)
|
||||
{
|
||||
TRACE( "loading %s from PE builtin %s\n", debugstr_w(name), debugstr_us(nt_name) );
|
||||
return load_native_dll( load_path, nt_name, module_ptr, &image_info, flags, pwm, &st );
|
||||
return load_native_dll( load_path, nt_name, module_ptr, &image_info, &id, flags, pwm );
|
||||
}
|
||||
|
||||
status = load_so_dll( load_path, nt_name, so_name, flags, pwm );
|
||||
|
@ -2904,7 +2905,7 @@ done:
|
|||
*/
|
||||
static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING *nt_name,
|
||||
WINE_MODREF **pwm, void **module, pe_image_info_t *image_info,
|
||||
struct stat *st )
|
||||
struct file_id *id )
|
||||
{
|
||||
WCHAR *name;
|
||||
BOOL found_image = FALSE;
|
||||
|
@ -2931,7 +2932,7 @@ static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING *
|
|||
nt_name->Buffer = NULL;
|
||||
if ((status = RtlDosPathNameToNtPathName_U_WithStatus( name, nt_name, NULL, NULL ))) goto done;
|
||||
|
||||
status = open_dll_file( nt_name, pwm, module, image_info, st );
|
||||
status = open_dll_file( nt_name, pwm, module, image_info, id );
|
||||
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE;
|
||||
else if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
RtlFreeUnicodeString( nt_name );
|
||||
|
@ -2960,7 +2961,7 @@ done:
|
|||
*/
|
||||
static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, const WCHAR *default_ext,
|
||||
UNICODE_STRING *nt_name, WINE_MODREF **pwm,
|
||||
void **module, pe_image_info_t *image_info, struct stat *st )
|
||||
void **module, pe_image_info_t *image_info, struct file_id *id )
|
||||
{
|
||||
WCHAR *ext, *dllname;
|
||||
NTSTATUS status;
|
||||
|
@ -3011,9 +3012,9 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, con
|
|||
}
|
||||
|
||||
if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH)
|
||||
status = search_dll_file( load_path, libname, nt_name, pwm, module, image_info, st );
|
||||
status = search_dll_file( load_path, libname, nt_name, pwm, module, image_info, id );
|
||||
else if (!(status = RtlDosPathNameToNtPathName_U_WithStatus( libname, nt_name, NULL, NULL )))
|
||||
status = open_dll_file( nt_name, pwm, module, image_info, st );
|
||||
status = open_dll_file( nt_name, pwm, module, image_info, id );
|
||||
|
||||
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) status = STATUS_INVALID_IMAGE_FORMAT;
|
||||
|
||||
|
@ -3036,14 +3037,14 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
|
|||
enum loadorder loadorder;
|
||||
WINE_MODREF *main_exe;
|
||||
UNICODE_STRING nt_name;
|
||||
struct stat st;
|
||||
struct file_id id;
|
||||
void *module;
|
||||
pe_image_info_t image_info;
|
||||
NTSTATUS nts;
|
||||
|
||||
TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) );
|
||||
|
||||
nts = find_dll_file( load_path, libname, default_ext, &nt_name, pwm, &module, &image_info, &st );
|
||||
nts = find_dll_file( load_path, libname, default_ext, &nt_name, pwm, &module, &image_info, &id );
|
||||
|
||||
if (*pwm) /* found already loaded module */
|
||||
{
|
||||
|
@ -3090,7 +3091,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
|
|||
case LO_DEFAULT:
|
||||
nts = load_builtin_dll( load_path, &nt_name, &module, flags, pwm );
|
||||
if (nts == STATUS_DLL_NOT_FOUND)
|
||||
nts = load_native_dll( load_path, &nt_name, &module, &image_info, flags, pwm, &st );
|
||||
nts = load_native_dll( load_path, &nt_name, &module, &image_info, &id, flags, pwm );
|
||||
break;
|
||||
default:
|
||||
nts = STATUS_DLL_NOT_FOUND;
|
||||
|
@ -3105,7 +3106,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
|
|||
{
|
||||
case LO_NATIVE:
|
||||
case LO_NATIVE_BUILTIN:
|
||||
nts = load_native_dll( load_path, &nt_name, &module, &image_info, flags, pwm, &st );
|
||||
nts = load_native_dll( load_path, &nt_name, &module, &image_info, &id, flags, pwm );
|
||||
break;
|
||||
case LO_BUILTIN:
|
||||
nts = load_builtin_dll( load_path, &nt_name, &module, flags, pwm );
|
||||
|
@ -3121,10 +3122,10 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
|
|||
LdrUnloadDll( (*pwm)->ldr.DllBase );
|
||||
nts = STATUS_DLL_NOT_FOUND;
|
||||
/* map the dll again if it was unmapped */
|
||||
if (!module && open_dll_file( &nt_name, pwm, &module, &image_info, &st )) break;
|
||||
if (!module && open_dll_file( &nt_name, pwm, &module, &image_info, &id )) break;
|
||||
}
|
||||
if (nts == STATUS_DLL_NOT_FOUND)
|
||||
nts = load_native_dll( load_path, &nt_name, &module, &image_info, flags, pwm, &st );
|
||||
nts = load_native_dll( load_path, &nt_name, &module, &image_info, &id, flags, pwm );
|
||||
break;
|
||||
default:
|
||||
nts = STATUS_DLL_NOT_FOUND;
|
||||
|
@ -3203,13 +3204,13 @@ NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_S
|
|||
WINE_MODREF *wm;
|
||||
void *module;
|
||||
pe_image_info_t image_info;
|
||||
struct stat st;
|
||||
struct file_id id;
|
||||
|
||||
RtlEnterCriticalSection( &loader_section );
|
||||
|
||||
if (!load_path) load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
|
||||
|
||||
status = find_dll_file( load_path, name->Buffer, dllW, &nt_name, &wm, &module, &image_info, &st );
|
||||
status = find_dll_file( load_path, name->Buffer, dllW, &nt_name, &wm, &module, &image_info, &id );
|
||||
|
||||
if (wm) *base = wm->ldr.DllBase;
|
||||
else
|
||||
|
|
|
@ -1024,7 +1024,6 @@ static struct unix_funcs unix_funcs =
|
|||
exec_process,
|
||||
wine_server_call,
|
||||
server_send_fd,
|
||||
server_get_unix_fd,
|
||||
server_fd_to_handle,
|
||||
server_handle_to_fd,
|
||||
server_release_fd,
|
||||
|
|
|
@ -999,7 +999,7 @@ static int remove_fd_from_cache( HANDLE handle )
|
|||
*
|
||||
* The returned unix_fd should be closed iff needs_close is non-zero.
|
||||
*/
|
||||
int CDECL server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
int *needs_close, enum server_fd_type *type, unsigned int *options )
|
||||
{
|
||||
sigset_t sigset;
|
||||
|
|
|
@ -101,9 +101,6 @@ extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN;
|
|||
extern void CDECL virtual_set_large_address_space(void) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void CDECL server_send_fd( int fd ) DECLSPEC_HIDDEN;
|
||||
extern int CDECL server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
int *needs_close, enum server_fd_type *type,
|
||||
unsigned int *options ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL server_fd_to_handle( int fd, unsigned int access, unsigned int attributes,
|
||||
HANDLE *handle ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL server_handle_to_fd( HANDLE handle, unsigned int access, int *unix_fd,
|
||||
|
@ -155,6 +152,8 @@ extern unsigned int server_wait( const select_op_t *select_op, data_size_t size,
|
|||
const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
|
||||
extern unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call,
|
||||
apc_result_t *result ) DECLSPEC_HIDDEN;
|
||||
extern int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
int *needs_close, enum server_fd_type *type, unsigned int *options ) DECLSPEC_HIDDEN;
|
||||
extern void server_init_process(void) DECLSPEC_HIDDEN;
|
||||
extern size_t server_init_thread( void *entry_point, BOOL *suspend ) DECLSPEC_HIDDEN;
|
||||
extern int server_pipe( int fd[2] ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
|||
struct msghdr;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 56
|
||||
#define NTDLL_UNIXLIB_VERSION 57
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -310,8 +310,6 @@ struct unix_funcs
|
|||
/* server functions */
|
||||
unsigned int (CDECL *server_call)( void *req_ptr );
|
||||
void (CDECL *server_send_fd)( int fd );
|
||||
int (CDECL *server_get_unix_fd)( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
int *needs_close, enum server_fd_type *type, unsigned int *options );
|
||||
NTSTATUS (CDECL *server_fd_to_handle)( int fd, unsigned int access, unsigned int attributes,
|
||||
HANDLE *handle );
|
||||
NTSTATUS (CDECL *server_handle_to_fd)( HANDLE handle, unsigned int access, int *unix_fd,
|
||||
|
|
Loading…
Reference in New Issue