Commit c7c4246a authored by Peter Ganten's avatar Peter Ganten Committed by Alexandre Julliard

- 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.
parent 8bba9bad
......@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment