mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 12:03:45 +00:00
- Always store the full path name of 32bit modules in WINE_MODREF
- Add the possibility to use path names with the --dll command line option - Add the possibility to use the --dll command line option several times. - Note: The colon-sign is now exchanged with the plus-sign, as it is part of dos path names.
This commit is contained in:
parent
8bba9badaf
commit
c7c4246a99
9 changed files with 123 additions and 65 deletions
|
@ -170,7 +170,7 @@ Use a desktop window of the given geometry, e.g. "640x480"
|
|||
.I --display name
|
||||
Use the specified X display
|
||||
.TP
|
||||
.I --dll name[,name[,...]]={native|elfdll|so|builtin}[,{n|e|s|b}[,...]][:...]
|
||||
.I --dll name[,name[,...]]={native|elfdll|so|builtin}[,{n|e|s|b}[,...]][+...]
|
||||
Selects the override type and load order of dll used in the loading process
|
||||
for any dll. The default is set in @sysconfdir@/wine.conf or ~/.winerc. There
|
||||
are currently four types of libraries that can be loaded into a process' address
|
||||
|
@ -191,8 +191,10 @@ internal dlls (
|
|||
Each dll may have its own specific load order. The load order determines
|
||||
which verion of the dll is attempted to be loaded into the address space. If
|
||||
the first fails, then the next is tried and so on. Different load orders can
|
||||
be specified by separating the entries with a colon. Multiple libraries
|
||||
with the same load order can be separated with commas.
|
||||
be specified by separating the entries with a plus sign. Multiple libraries
|
||||
with the same load order can be separated with commas. It is also possible to
|
||||
use the --dll option several times, to specify different loadorders for different
|
||||
libraries
|
||||
.br
|
||||
Examples:
|
||||
.br
|
||||
|
@ -201,7 +203,12 @@ Examples:
|
|||
Try to load comdlg32 and commdlg as native windows dll first and try
|
||||
the builtin version if the native load fails.
|
||||
.br
|
||||
.I --dll comdlg32,commdlg=e,n:shell,shell32=b:comctl32,commctrl=n
|
||||
.I --dll shell,shell32=n --dll c:\\foo\\bar\\baz=b
|
||||
.br
|
||||
Try to load the libraries shell and shell32 as native windows dlls. Furthermore, if
|
||||
an application request to load c:\\foo\\bar\\baz.dll load the builtin library baz.
|
||||
.br
|
||||
.I --dll comdlg32,commdlg=e,n:shell,shell32=b+comctl32,commctrl=n
|
||||
.br
|
||||
Try to load comdlg32 and commdlg as elfdll first and try the native version
|
||||
if the elfdll load fails; load shell32/shell always as builtin and
|
||||
|
|
|
@ -22,7 +22,7 @@ typedef struct module_loadorder {
|
|||
} module_loadorder_t;
|
||||
|
||||
BOOL MODULE_InitLoadOrder(void);
|
||||
module_loadorder_t *MODULE_GetLoadOrder(const char *path);
|
||||
module_loadorder_t *MODULE_GetLoadOrder(const char *path, BOOL win32);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags)
|
|||
|
||||
SNOOP_RegisterDLL(hmod,libname,STUBSIZE/sizeof(ELF_STDCALL_STUB));
|
||||
|
||||
wm = PE_CreateModule( hmod, modname, 0, -1, FALSE );
|
||||
wm = PE_CreateModule( hmod, libname, 0, -1, FALSE );
|
||||
wm->find_export = ELF_FindExportedFunction;
|
||||
wm->dlhandle = dlhandle;
|
||||
return wm;
|
||||
|
|
|
@ -271,7 +271,7 @@ static BOOL AddLoadOrderSet(char *key, char *order, BOOL override)
|
|||
* ParseCommandlineOverrides (internal, static)
|
||||
*
|
||||
* The commandline is in the form:
|
||||
* name[,name,...]=native[,b,...][:...]
|
||||
* name[,name,...]=native[,b,...][+...]
|
||||
*/
|
||||
static BOOL ParseCommandlineOverrides(void)
|
||||
{
|
||||
|
@ -289,7 +289,7 @@ static BOOL ParseCommandlineOverrides(void)
|
|||
next = key;
|
||||
for(; next; key = next)
|
||||
{
|
||||
next = strchr(key, ':');
|
||||
next = strchr(key, '+');
|
||||
if(next)
|
||||
{
|
||||
*next = '\0';
|
||||
|
@ -425,14 +425,14 @@ BOOL MODULE_InitLoadOrder(void)
|
|||
/* Add the commandline overrides to the pool */
|
||||
if(!ParseCommandlineOverrides())
|
||||
{
|
||||
MESSAGE( "Syntax: -dll name[,name[,...]]={native|elfdll|so|builtin}[,{n|e|s|b}[,...]][:...]\n"
|
||||
MESSAGE( "Syntax: -dll name[,name[,...]]={native|elfdll|so|builtin}[,{n|e|s|b}[,...]][+...]\n"
|
||||
" - 'name' is the name of any dll without extension\n"
|
||||
" - the order of loading (native, elfdll, so and builtin) can be abbreviated\n"
|
||||
" with the first letter\n"
|
||||
" - different loadorders for different dlls can be specified by seperating the\n"
|
||||
" commandline entries with a ':'\n"
|
||||
" commandline entries with a '+'\n"
|
||||
" Example:\n"
|
||||
" -dll comdlg32,commdlg=n:shell,shell32=b\n"
|
||||
" -dll comdlg32,commdlg=n+shell,shell32=b\n"
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -445,8 +445,8 @@ BOOL MODULE_InitLoadOrder(void)
|
|||
while (dllpair->dll1)
|
||||
{
|
||||
module_loadorder_t *plo1, *plo2;
|
||||
plo1 = MODULE_GetLoadOrder(dllpair->dll1);
|
||||
plo2 = MODULE_GetLoadOrder(dllpair->dll2);
|
||||
plo1 = MODULE_GetLoadOrder(dllpair->dll1, FALSE);
|
||||
plo2 = MODULE_GetLoadOrder(dllpair->dll2, FALSE);
|
||||
assert(plo1 && plo2);
|
||||
if(memcmp(plo1->loadorder, plo2->loadorder, sizeof(plo1->loadorder)))
|
||||
MESSAGE("Warning: Modules '%s' and '%s' have different loadorder which may cause trouble\n", dllpair->dll1, dllpair->dll2);
|
||||
|
@ -479,10 +479,11 @@ BOOL MODULE_InitLoadOrder(void)
|
|||
* '.dll' and '.exe'. A lookup in the table can yield an override for
|
||||
* the specific dll. Otherwise the default load order is returned.
|
||||
*/
|
||||
module_loadorder_t *MODULE_GetLoadOrder(const char *path)
|
||||
module_loadorder_t *MODULE_GetLoadOrder(const char *path, BOOL win32 )
|
||||
{
|
||||
module_loadorder_t lo, *tmp;
|
||||
char fname[256];
|
||||
char sysdir[MAX_PATH+1];
|
||||
char *cptr;
|
||||
char *name;
|
||||
int len;
|
||||
|
@ -491,26 +492,36 @@ module_loadorder_t *MODULE_GetLoadOrder(const char *path)
|
|||
|
||||
assert(path != NULL);
|
||||
|
||||
/* Strip path information */
|
||||
cptr = strrchr(path, '\\');
|
||||
if(!cptr)
|
||||
name = strrchr(path, '/');
|
||||
else
|
||||
name = strrchr(cptr, '/');
|
||||
|
||||
if(!name)
|
||||
name = cptr ? cptr+1 : (char *)path;
|
||||
else
|
||||
name++;
|
||||
|
||||
if((cptr = strchr(name, ':')) != NULL) /* Also strip drive if in format 'C:MODULE.DLL' */
|
||||
name = cptr+1;
|
||||
if ( ! GetSystemDirectoryA ( sysdir, MAX_PATH ) )
|
||||
return &default_loadorder; /* Hmmm ... */
|
||||
|
||||
/* Strip path information for 16 bit modules or if the module
|
||||
resides in the system directory */
|
||||
if ( !win32 || !strncasecmp ( sysdir, path, strlen (sysdir) ) )
|
||||
{
|
||||
|
||||
cptr = strrchr(path, '\\');
|
||||
if(!cptr)
|
||||
name = strrchr(path, '/');
|
||||
else
|
||||
name = strrchr(cptr, '/');
|
||||
|
||||
if(!name)
|
||||
name = cptr ? cptr+1 : (char *)path;
|
||||
else
|
||||
name++;
|
||||
|
||||
if((cptr = strchr(name, ':')) != NULL) /* Also strip drive if in format 'C:MODULE.DLL' */
|
||||
name = cptr+1;
|
||||
}
|
||||
else
|
||||
name = (char *)path;
|
||||
|
||||
len = strlen(name);
|
||||
if(len >= sizeof(fname) || len <= 0)
|
||||
{
|
||||
ERR("Path '%s' -> '%s' reduces to zilch or just too large...\n", path, name);
|
||||
return &default_loadorder;
|
||||
ERR("Path '%s' -> '%s' reduces to zilch or just too large...\n", path, name);
|
||||
return &default_loadorder;
|
||||
}
|
||||
|
||||
strcpy(fname, name);
|
||||
|
|
|
@ -415,7 +415,7 @@ HMODULE MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 )
|
|||
|
||||
|
||||
/**********************************************************************
|
||||
* MODULE_FindModule32
|
||||
* MODULE_FindModule
|
||||
*
|
||||
* Find a (loaded) win32 module depending on path
|
||||
*
|
||||
|
@ -1258,11 +1258,48 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
|
|||
WINE_MODREF *pwm;
|
||||
int i;
|
||||
module_loadorder_t *plo;
|
||||
LPSTR filename, p;
|
||||
|
||||
if ( !libname ) return NULL;
|
||||
|
||||
filename = HeapAlloc ( GetProcessHeap(), 0, MAX_PATH + 1 );
|
||||
if ( !filename ) return NULL;
|
||||
|
||||
/* build the modules filename */
|
||||
if (!SearchPathA( NULL, libname, ".dll", MAX_PATH, filename, NULL ))
|
||||
{
|
||||
if ( ! GetSystemDirectoryA ( filename, MAX_PATH ) )
|
||||
goto error;
|
||||
|
||||
/* if the library name contains a path and can not be found, return an error.
|
||||
exception: if the path is the system directory, proceed, so that modules,
|
||||
which are not PE-modules can be loaded
|
||||
|
||||
if the library name does not contain a path and can not be found, assume the
|
||||
system directory is meant */
|
||||
|
||||
if ( ! strncasecmp ( filename, libname, strlen ( filename ) ))
|
||||
strcpy ( filename, libname );
|
||||
else
|
||||
{
|
||||
if ( strchr ( libname, '\\' ) || strchr ( libname, ':') || strchr ( libname, '/' ) )
|
||||
goto error;
|
||||
else
|
||||
{
|
||||
strcat ( filename, "\\" );
|
||||
strcat ( filename, libname );
|
||||
}
|
||||
}
|
||||
|
||||
/* if the filename doesn't have an extension append .DLL */
|
||||
if (!(p = strrchr( filename, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
|
||||
strcat( filename, ".DLL" );
|
||||
}
|
||||
|
||||
EnterCriticalSection(&PROCESS_Current()->crit_section);
|
||||
|
||||
/* Check for already loaded module */
|
||||
if((pwm = MODULE_FindModule(libname)))
|
||||
if((pwm = MODULE_FindModule(filename)))
|
||||
{
|
||||
if(!(pwm->flags & WINE_MODREF_MARKER))
|
||||
pwm->refCount++;
|
||||
|
@ -1274,12 +1311,13 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
|
|||
pwm->flags &= ~WINE_MODREF_DONT_RESOLVE_REFS;
|
||||
fixup_imports( pwm );
|
||||
}
|
||||
TRACE("Already loaded module '%s' at 0x%08x, count=%d, \n", libname, pwm->module, pwm->refCount);
|
||||
TRACE("Already loaded module '%s' at 0x%08x, count=%d, \n", filename, pwm->module, pwm->refCount);
|
||||
LeaveCriticalSection(&PROCESS_Current()->crit_section);
|
||||
HeapFree ( GetProcessHeap(), 0, filename );
|
||||
return pwm;
|
||||
}
|
||||
|
||||
plo = MODULE_GetLoadOrder(libname);
|
||||
plo = MODULE_GetLoadOrder(filename, TRUE);
|
||||
|
||||
for(i = 0; i < MODULE_LOADORDER_NTYPES; i++)
|
||||
{
|
||||
|
@ -1287,25 +1325,25 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
|
|||
switch(plo->loadorder[i])
|
||||
{
|
||||
case MODULE_LOADORDER_DLL:
|
||||
TRACE("Trying native dll '%s'\n", libname);
|
||||
pwm = PE_LoadLibraryExA(libname, flags);
|
||||
TRACE("Trying native dll '%s'\n", filename);
|
||||
pwm = PE_LoadLibraryExA(filename, flags);
|
||||
break;
|
||||
|
||||
case MODULE_LOADORDER_ELFDLL:
|
||||
TRACE("Trying elfdll '%s'\n", libname);
|
||||
if (!(pwm = BUILTIN32_LoadLibraryExA(libname, flags)))
|
||||
pwm = ELFDLL_LoadLibraryExA(libname, flags);
|
||||
TRACE("Trying elfdll '%s'\n", filename);
|
||||
if (!(pwm = BUILTIN32_LoadLibraryExA(filename, flags)))
|
||||
pwm = ELFDLL_LoadLibraryExA(filename, flags);
|
||||
break;
|
||||
|
||||
case MODULE_LOADORDER_SO:
|
||||
TRACE("Trying so-library '%s'\n", libname);
|
||||
if (!(pwm = BUILTIN32_LoadLibraryExA(libname, flags)))
|
||||
pwm = ELF_LoadLibraryExA(libname, flags);
|
||||
TRACE("Trying so-library '%s'\n", filename);
|
||||
if (!(pwm = BUILTIN32_LoadLibraryExA(filename, flags)))
|
||||
pwm = ELF_LoadLibraryExA(filename, flags);
|
||||
break;
|
||||
|
||||
case MODULE_LOADORDER_BI:
|
||||
TRACE("Trying built-in '%s'\n", libname);
|
||||
pwm = BUILTIN32_LoadLibraryExA(libname, flags);
|
||||
TRACE("Trying built-in '%s'\n", filename);
|
||||
pwm = BUILTIN32_LoadLibraryExA(filename, flags);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1320,7 +1358,7 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
|
|||
if(pwm)
|
||||
{
|
||||
/* Initialize DLL just loaded */
|
||||
TRACE("Loaded module '%s' at 0x%08x, \n", libname, pwm->module);
|
||||
TRACE("Loaded module '%s' at 0x%08x, \n", filename, pwm->module);
|
||||
|
||||
/* Set the refCount here so that an attach failure will */
|
||||
/* decrement the dependencies through the MODULE_FreeLibrary call. */
|
||||
|
@ -1328,6 +1366,7 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
|
|||
|
||||
LeaveCriticalSection(&PROCESS_Current()->crit_section);
|
||||
SetLastError( err ); /* restore last error */
|
||||
HeapFree ( GetProcessHeap(), 0, filename );
|
||||
return pwm;
|
||||
}
|
||||
|
||||
|
@ -1335,8 +1374,10 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
|
|||
break;
|
||||
}
|
||||
|
||||
WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError());
|
||||
LeaveCriticalSection(&PROCESS_Current()->crit_section);
|
||||
error:
|
||||
WARN("Failed to load module '%s'; error=0x%08lx, \n", filename, GetLastError());
|
||||
HeapFree ( GetProcessHeap(), 0, filename );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -912,7 +912,7 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_
|
|||
int i;
|
||||
module_loadorder_t *plo;
|
||||
|
||||
plo = MODULE_GetLoadOrder(libname);
|
||||
plo = MODULE_GetLoadOrder(libname, FALSE);
|
||||
|
||||
for(i = 0; i < MODULE_LOADORDER_NTYPES; i++)
|
||||
{
|
||||
|
|
|
@ -702,19 +702,14 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags)
|
|||
{
|
||||
HMODULE hModule32;
|
||||
WINE_MODREF *wm;
|
||||
char filename[256];
|
||||
HANDLE hFile;
|
||||
|
||||
/* Search for and open PE file */
|
||||
if ( SearchPathA( NULL, name, ".DLL",
|
||||
sizeof(filename), filename, NULL ) == 0 ) return NULL;
|
||||
|
||||
hFile = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ,
|
||||
hFile = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, -1 );
|
||||
if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
|
||||
|
||||
/* Load PE module */
|
||||
hModule32 = PE_LoadImage( hFile, filename, flags );
|
||||
hModule32 = PE_LoadImage( hFile, name, flags );
|
||||
if (!hModule32)
|
||||
{
|
||||
CloseHandle( hFile );
|
||||
|
@ -722,9 +717,9 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags)
|
|||
}
|
||||
|
||||
/* Create 32-bit MODREF */
|
||||
if ( !(wm = PE_CreateModule( hModule32, filename, flags, -1, FALSE )) )
|
||||
if ( !(wm = PE_CreateModule( hModule32, name, flags, -1, FALSE )) )
|
||||
{
|
||||
ERR( "can't load %s\n", filename );
|
||||
ERR( "can't load %s\n", name );
|
||||
CloseHandle( hFile );
|
||||
SetLastError( ERROR_OUTOFMEMORY );
|
||||
return NULL;
|
||||
|
|
|
@ -130,13 +130,16 @@ static void do_dll( const char *arg )
|
|||
{
|
||||
if (Options.dllFlags)
|
||||
{
|
||||
/* don't overwrite previous value. Should we
|
||||
* automatically add the ',' between multiple DLLs ?
|
||||
*/
|
||||
MESSAGE("Only one -dll flag is allowed. Use ',' between multiple DLLs\n");
|
||||
ExitProcess(1);
|
||||
Options.dllFlags = (char *) realloc ( Options.dllFlags,
|
||||
strlen ( Options.dllFlags ) + strlen ( arg ) + 2 );
|
||||
if ( !Options.dllFlags ) out_of_memory();
|
||||
strcat ( Options.dllFlags, "+" );
|
||||
strcat ( Options.dllFlags, arg );
|
||||
}
|
||||
else
|
||||
{
|
||||
Options.dllFlags = xstrdup( arg );
|
||||
}
|
||||
Options.dllFlags = xstrdup( arg );
|
||||
}
|
||||
|
||||
static void do_language( const char *arg )
|
||||
|
|
|
@ -269,8 +269,9 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags)
|
|||
int i;
|
||||
|
||||
/* Fix the name in case we have a full path and extension */
|
||||
if ((p = strrchr( path, '\\' ))) path = p + 1;
|
||||
lstrcpynA( dllname, path, sizeof(dllname) );
|
||||
if ((p = strrchr( path, '\\' ))) p++;
|
||||
else p = (char *)path;
|
||||
lstrcpynA( dllname, p, sizeof(dllname) );
|
||||
|
||||
p = strrchr( dllname, '.' );
|
||||
if (!p) strcat( dllname, ".dll" );
|
||||
|
@ -295,7 +296,7 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags)
|
|||
if (!(module = BUILTIN32_DoLoadImage( builtin_dlls[i] ))) return NULL;
|
||||
|
||||
/* Create 32-bit MODREF */
|
||||
if ( !(wm = PE_CreateModule( module, dllname, flags, -1, TRUE )) )
|
||||
if ( !(wm = PE_CreateModule( module, path, flags, -1, TRUE )) )
|
||||
{
|
||||
ERR( "can't load %s\n", path );
|
||||
SetLastError( ERROR_OUTOFMEMORY );
|
||||
|
|
Loading…
Reference in a new issue