Added wine_dll_get_owner function that retrieves the 32-bit dll

containing a given 16-bit dll by reading the symlink, so that we don't
need to dlopen it.
This commit is contained in:
Alexandre Julliard 2004-01-02 21:08:05 +00:00
parent 03b47d2118
commit 7984ded712
3 changed files with 90 additions and 17 deletions

View File

@ -47,6 +47,7 @@ extern void *wine_dll_load( const char *filename, char *error, int errorsize, in
extern void *wine_dll_load_main_exe( const char *name, char *error, int errorsize, extern void *wine_dll_load_main_exe( const char *name, char *error, int errorsize,
int test_only, int *file_exists ); int test_only, int *file_exists );
extern void wine_dll_unload( void *handle ); extern void wine_dll_unload( void *handle );
extern int wine_dll_get_owner( const char *name, char *buffer, int size, int *file_exists );
extern int __wine_main_argc; extern int __wine_main_argc;
extern char **__wine_main_argv; extern char **__wine_main_argv;

View File

@ -47,6 +47,12 @@ char **__wine_main_argv = NULL;
WCHAR **__wine_main_wargv = NULL; WCHAR **__wine_main_wargv = NULL;
char **__wine_main_environ = NULL; char **__wine_main_environ = NULL;
struct dll_path_context
{
int index;
char *buffer;
};
#define MAX_DLLS 100 #define MAX_DLLS 100
static struct static struct
@ -121,33 +127,64 @@ inline static int file_exists( const char *name )
return (fd != -1); return (fd != -1);
} }
/* get a filename from the next entry in the dll path */
static char *next_dll_path( struct dll_path_context *context )
{
int index = context->index++;
if (index < nb_dll_paths)
{
int len = strlen( dll_paths[index] );
char *path = context->buffer + dll_path_maxlen - len;
memcpy( path, dll_paths[index], len );
return path;
}
return NULL;
}
/* get a filename from the first entry in the dll path */
static char *first_dll_path( const char *name, const char *ext, struct dll_path_context *context )
{
char *p;
int namelen = strlen( name );
context->buffer = p = malloc( dll_path_maxlen + namelen + strlen(ext) + 2 );
context->index = 0;
/* store the name at the end of the buffer, followed by extension */
p += dll_path_maxlen;
*p++ = '/';
memcpy( p, name, namelen );
strcpy( p + namelen, ext );
return next_dll_path( context );
}
/* free the dll path context created by first_dll_path */
inline static void free_dll_path( struct dll_path_context *context )
{
free( context->buffer );
}
/* open a library for a given dll, searching in the dll path /* open a library for a given dll, searching in the dll path
* 'name' must be the Windows dll name (e.g. "kernel32.dll") */ * 'name' must be the Windows dll name (e.g. "kernel32.dll") */
static void *dlopen_dll( const char *name, char *error, int errorsize, static void *dlopen_dll( const char *name, char *error, int errorsize,
int test_only, int *exists ) int test_only, int *exists )
{ {
int i, namelen = strlen(name); struct dll_path_context context;
char *buffer, *p; char *path;
void *ret = NULL; void *ret = NULL;
buffer = malloc( dll_path_maxlen + namelen + 5 );
/* store the name at the end of the buffer, followed by .so */
p = buffer + dll_path_maxlen;
*p++ = '/';
memcpy( p, name, namelen );
strcpy( p + namelen, ".so" );
*exists = 0; *exists = 0;
for (path = first_dll_path( name, ".so", &context ); path; path = next_dll_path( &context ))
for (i = 0; i < nb_dll_paths; i++)
{ {
int len = strlen(dll_paths[i]); if (!test_only && (ret = wine_dlopen( path, RTLD_NOW, error, errorsize ))) break;
p = buffer + dll_path_maxlen - len; if ((*exists = file_exists( path ))) break; /* exists but cannot be loaded, return the error */
memcpy( p, dll_paths[i], len );
if (!test_only && (ret = wine_dlopen( p, RTLD_NOW, error, errorsize ))) break;
if ((*exists = file_exists( p ))) break; /* exists but cannot be loaded, return the error */
} }
free( buffer ); free_dll_path( &context );
return ret; return ret;
} }
@ -411,6 +448,40 @@ void *wine_dll_load_main_exe( const char *name, char *error, int errorsize,
} }
/***********************************************************************
* wine_dll_get_owner
*
* Retrieve the name of the 32-bit owner dll for a 16-bit dll.
* Return 0 if OK, -1 on error.
*/
int wine_dll_get_owner( const char *name, char *buffer, int size, int *exists )
{
int ret = -1;
char *path;
struct dll_path_context context;
*exists = 0;
for (path = first_dll_path( name, ".so", &context ); path; path = next_dll_path( &context ))
{
int res = readlink( path, buffer, size );
if (res != -1) /* got a symlink */
{
*exists = 1;
if (res < 4 || res >= size) break;
buffer[res] = 0;
if (strchr( buffer, '/' )) break; /* contains a path, not valid */
if (strcmp( buffer + res - 3, ".so" )) break; /* does not end in .so, not valid */
buffer[res - 3] = 0; /* remove .so */
ret = 0;
break;
}
if ((*exists = file_exists( path ))) break; /* exists but not a symlink, return the error */
}
free_dll_path( &context );
return ret;
}
/*********************************************************************** /***********************************************************************
* debug_usage * debug_usage
*/ */

View File

@ -24,6 +24,7 @@ EXPORTS
wine_dbgstr_w wine_dbgstr_w
wine_dbgstr_wn wine_dbgstr_wn
wine_dlclose wine_dlclose
wine_dll_get_owner
wine_dll_load wine_dll_load
wine_dll_load_main_exe wine_dll_load_main_exe
wine_dll_set_callback wine_dll_set_callback