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" ...@@ -170,7 +170,7 @@ Use a desktop window of the given geometry, e.g. "640x480"
.I --display name .I --display name
Use the specified X display Use the specified X display
.TP .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 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 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 are currently four types of libraries that can be loaded into a process' address
...@@ -191,8 +191,10 @@ internal dlls ( ...@@ -191,8 +191,10 @@ internal dlls (
Each dll may have its own specific load order. The load order determines 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 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 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 be specified by separating the entries with a plus sign. Multiple libraries
with the same load order can be separated with commas. 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 .br
Examples: Examples:
.br .br
...@@ -201,7 +203,12 @@ Examples: ...@@ -201,7 +203,12 @@ Examples:
Try to load comdlg32 and commdlg as native windows dll first and try Try to load comdlg32 and commdlg as native windows dll first and try
the builtin version if the native load fails. the builtin version if the native load fails.
.br .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 .br
Try to load comdlg32 and commdlg as elfdll first and try the native version 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 if the elfdll load fails; load shell32/shell always as builtin and
......
...@@ -22,7 +22,7 @@ typedef struct module_loadorder { ...@@ -22,7 +22,7 @@ typedef struct module_loadorder {
} module_loadorder_t; } module_loadorder_t;
BOOL MODULE_InitLoadOrder(void); BOOL MODULE_InitLoadOrder(void);
module_loadorder_t *MODULE_GetLoadOrder(const char *path); module_loadorder_t *MODULE_GetLoadOrder(const char *path, BOOL win32);
#endif #endif
...@@ -158,7 +158,7 @@ WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags) ...@@ -158,7 +158,7 @@ WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags)
SNOOP_RegisterDLL(hmod,libname,STUBSIZE/sizeof(ELF_STDCALL_STUB)); 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->find_export = ELF_FindExportedFunction;
wm->dlhandle = dlhandle; wm->dlhandle = dlhandle;
return wm; return wm;
......
...@@ -271,7 +271,7 @@ static BOOL AddLoadOrderSet(char *key, char *order, BOOL override) ...@@ -271,7 +271,7 @@ static BOOL AddLoadOrderSet(char *key, char *order, BOOL override)
* ParseCommandlineOverrides (internal, static) * ParseCommandlineOverrides (internal, static)
* *
* The commandline is in the form: * The commandline is in the form:
* name[,name,...]=native[,b,...][:...] * name[,name,...]=native[,b,...][+...]
*/ */
static BOOL ParseCommandlineOverrides(void) static BOOL ParseCommandlineOverrides(void)
{ {
...@@ -289,7 +289,7 @@ static BOOL ParseCommandlineOverrides(void) ...@@ -289,7 +289,7 @@ static BOOL ParseCommandlineOverrides(void)
next = key; next = key;
for(; next; key = next) for(; next; key = next)
{ {
next = strchr(key, ':'); next = strchr(key, '+');
if(next) if(next)
{ {
*next = '\0'; *next = '\0';
...@@ -425,14 +425,14 @@ BOOL MODULE_InitLoadOrder(void) ...@@ -425,14 +425,14 @@ BOOL MODULE_InitLoadOrder(void)
/* Add the commandline overrides to the pool */ /* Add the commandline overrides to the pool */
if(!ParseCommandlineOverrides()) 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" " - 'name' is the name of any dll without extension\n"
" - the order of loading (native, elfdll, so and builtin) can be abbreviated\n" " - the order of loading (native, elfdll, so and builtin) can be abbreviated\n"
" with the first letter\n" " with the first letter\n"
" - different loadorders for different dlls can be specified by seperating the\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" " Example:\n"
" -dll comdlg32,commdlg=n:shell,shell32=b\n" " -dll comdlg32,commdlg=n+shell,shell32=b\n"
); );
return FALSE; return FALSE;
} }
...@@ -445,8 +445,8 @@ BOOL MODULE_InitLoadOrder(void) ...@@ -445,8 +445,8 @@ BOOL MODULE_InitLoadOrder(void)
while (dllpair->dll1) while (dllpair->dll1)
{ {
module_loadorder_t *plo1, *plo2; module_loadorder_t *plo1, *plo2;
plo1 = MODULE_GetLoadOrder(dllpair->dll1); plo1 = MODULE_GetLoadOrder(dllpair->dll1, FALSE);
plo2 = MODULE_GetLoadOrder(dllpair->dll2); plo2 = MODULE_GetLoadOrder(dllpair->dll2, FALSE);
assert(plo1 && plo2); assert(plo1 && plo2);
if(memcmp(plo1->loadorder, plo2->loadorder, sizeof(plo1->loadorder))) 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); 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) ...@@ -479,10 +479,11 @@ BOOL MODULE_InitLoadOrder(void)
* '.dll' and '.exe'. A lookup in the table can yield an override for * '.dll' and '.exe'. A lookup in the table can yield an override for
* the specific dll. Otherwise the default load order is returned. * 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; module_loadorder_t lo, *tmp;
char fname[256]; char fname[256];
char sysdir[MAX_PATH+1];
char *cptr; char *cptr;
char *name; char *name;
int len; int len;
...@@ -491,26 +492,36 @@ module_loadorder_t *MODULE_GetLoadOrder(const char *path) ...@@ -491,26 +492,36 @@ module_loadorder_t *MODULE_GetLoadOrder(const char *path)
assert(path != NULL); assert(path != NULL);
/* Strip path information */ if ( ! GetSystemDirectoryA ( sysdir, MAX_PATH ) )
cptr = strrchr(path, '\\'); return &default_loadorder; /* Hmmm ... */
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;
/* 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); len = strlen(name);
if(len >= sizeof(fname) || len <= 0) if(len >= sizeof(fname) || len <= 0)
{ {
ERR("Path '%s' -> '%s' reduces to zilch or just too large...\n", path, name); ERR("Path '%s' -> '%s' reduces to zilch or just too large...\n", path, name);
return &default_loadorder; return &default_loadorder;
} }
strcpy(fname, name); strcpy(fname, name);
......
...@@ -415,7 +415,7 @@ HMODULE MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 ) ...@@ -415,7 +415,7 @@ HMODULE MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 )
/********************************************************************** /**********************************************************************
* MODULE_FindModule32 * MODULE_FindModule
* *
* Find a (loaded) win32 module depending on path * Find a (loaded) win32 module depending on path
* *
...@@ -1258,11 +1258,48 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ) ...@@ -1258,11 +1258,48 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
WINE_MODREF *pwm; WINE_MODREF *pwm;
int i; int i;
module_loadorder_t *plo; 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); EnterCriticalSection(&PROCESS_Current()->crit_section);
/* Check for already loaded module */ /* Check for already loaded module */
if((pwm = MODULE_FindModule(libname))) if((pwm = MODULE_FindModule(filename)))
{ {
if(!(pwm->flags & WINE_MODREF_MARKER)) if(!(pwm->flags & WINE_MODREF_MARKER))
pwm->refCount++; pwm->refCount++;
...@@ -1274,12 +1311,13 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ) ...@@ -1274,12 +1311,13 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
pwm->flags &= ~WINE_MODREF_DONT_RESOLVE_REFS; pwm->flags &= ~WINE_MODREF_DONT_RESOLVE_REFS;
fixup_imports( pwm ); 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); LeaveCriticalSection(&PROCESS_Current()->crit_section);
HeapFree ( GetProcessHeap(), 0, filename );
return pwm; return pwm;
} }
plo = MODULE_GetLoadOrder(libname); plo = MODULE_GetLoadOrder(filename, TRUE);
for(i = 0; i < MODULE_LOADORDER_NTYPES; i++) for(i = 0; i < MODULE_LOADORDER_NTYPES; i++)
{ {
...@@ -1287,25 +1325,25 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ) ...@@ -1287,25 +1325,25 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
switch(plo->loadorder[i]) switch(plo->loadorder[i])
{ {
case MODULE_LOADORDER_DLL: case MODULE_LOADORDER_DLL:
TRACE("Trying native dll '%s'\n", libname); TRACE("Trying native dll '%s'\n", filename);
pwm = PE_LoadLibraryExA(libname, flags); pwm = PE_LoadLibraryExA(filename, flags);
break; break;
case MODULE_LOADORDER_ELFDLL: case MODULE_LOADORDER_ELFDLL:
TRACE("Trying elfdll '%s'\n", libname); TRACE("Trying elfdll '%s'\n", filename);
if (!(pwm = BUILTIN32_LoadLibraryExA(libname, flags))) if (!(pwm = BUILTIN32_LoadLibraryExA(filename, flags)))
pwm = ELFDLL_LoadLibraryExA(libname, flags); pwm = ELFDLL_LoadLibraryExA(filename, flags);
break; break;
case MODULE_LOADORDER_SO: case MODULE_LOADORDER_SO:
TRACE("Trying so-library '%s'\n", libname); TRACE("Trying so-library '%s'\n", filename);
if (!(pwm = BUILTIN32_LoadLibraryExA(libname, flags))) if (!(pwm = BUILTIN32_LoadLibraryExA(filename, flags)))
pwm = ELF_LoadLibraryExA(libname, flags); pwm = ELF_LoadLibraryExA(filename, flags);
break; break;
case MODULE_LOADORDER_BI: case MODULE_LOADORDER_BI:
TRACE("Trying built-in '%s'\n", libname); TRACE("Trying built-in '%s'\n", filename);
pwm = BUILTIN32_LoadLibraryExA(libname, flags); pwm = BUILTIN32_LoadLibraryExA(filename, flags);
break; break;
default: default:
...@@ -1320,7 +1358,7 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ) ...@@ -1320,7 +1358,7 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
if(pwm) if(pwm)
{ {
/* Initialize DLL just loaded */ /* 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 */ /* Set the refCount here so that an attach failure will */
/* decrement the dependencies through the MODULE_FreeLibrary call. */ /* decrement the dependencies through the MODULE_FreeLibrary call. */
...@@ -1328,6 +1366,7 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ) ...@@ -1328,6 +1366,7 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
LeaveCriticalSection(&PROCESS_Current()->crit_section); LeaveCriticalSection(&PROCESS_Current()->crit_section);
SetLastError( err ); /* restore last error */ SetLastError( err ); /* restore last error */
HeapFree ( GetProcessHeap(), 0, filename );
return pwm; return pwm;
} }
...@@ -1335,8 +1374,10 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ) ...@@ -1335,8 +1374,10 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
break; break;
} }
WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError());
LeaveCriticalSection(&PROCESS_Current()->crit_section); LeaveCriticalSection(&PROCESS_Current()->crit_section);
error:
WARN("Failed to load module '%s'; error=0x%08lx, \n", filename, GetLastError());
HeapFree ( GetProcessHeap(), 0, filename );
return NULL; return NULL;
} }
......
...@@ -912,7 +912,7 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_ ...@@ -912,7 +912,7 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_
int i; int i;
module_loadorder_t *plo; module_loadorder_t *plo;
plo = MODULE_GetLoadOrder(libname); plo = MODULE_GetLoadOrder(libname, FALSE);
for(i = 0; i < MODULE_LOADORDER_NTYPES; i++) for(i = 0; i < MODULE_LOADORDER_NTYPES; i++)
{ {
......
...@@ -702,19 +702,14 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags) ...@@ -702,19 +702,14 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags)
{ {
HMODULE hModule32; HMODULE hModule32;
WINE_MODREF *wm; WINE_MODREF *wm;
char filename[256];
HANDLE hFile; 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 ); NULL, OPEN_EXISTING, 0, -1 );
if ( hFile == INVALID_HANDLE_VALUE ) return NULL; if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
/* Load PE module */ /* Load PE module */
hModule32 = PE_LoadImage( hFile, filename, flags ); hModule32 = PE_LoadImage( hFile, name, flags );
if (!hModule32) if (!hModule32)
{ {
CloseHandle( hFile ); CloseHandle( hFile );
...@@ -722,9 +717,9 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags) ...@@ -722,9 +717,9 @@ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags)
} }
/* Create 32-bit MODREF */ /* 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 ); CloseHandle( hFile );
SetLastError( ERROR_OUTOFMEMORY ); SetLastError( ERROR_OUTOFMEMORY );
return NULL; return NULL;
......
...@@ -130,13 +130,16 @@ static void do_dll( const char *arg ) ...@@ -130,13 +130,16 @@ static void do_dll( const char *arg )
{ {
if (Options.dllFlags) if (Options.dllFlags)
{ {
/* don't overwrite previous value. Should we Options.dllFlags = (char *) realloc ( Options.dllFlags,
* automatically add the ',' between multiple DLLs ? strlen ( Options.dllFlags ) + strlen ( arg ) + 2 );
*/ if ( !Options.dllFlags ) out_of_memory();
MESSAGE("Only one -dll flag is allowed. Use ',' between multiple DLLs\n"); strcat ( Options.dllFlags, "+" );
ExitProcess(1); strcat ( Options.dllFlags, arg );
}
else
{
Options.dllFlags = xstrdup( arg );
} }
Options.dllFlags = xstrdup( arg );
} }
static void do_language( const char *arg ) static void do_language( const char *arg )
......
...@@ -269,8 +269,9 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags) ...@@ -269,8 +269,9 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags)
int i; int i;
/* Fix the name in case we have a full path and extension */ /* Fix the name in case we have a full path and extension */
if ((p = strrchr( path, '\\' ))) path = p + 1; if ((p = strrchr( path, '\\' ))) p++;
lstrcpynA( dllname, path, sizeof(dllname) ); else p = (char *)path;
lstrcpynA( dllname, p, sizeof(dllname) );
p = strrchr( dllname, '.' ); p = strrchr( dllname, '.' );
if (!p) strcat( dllname, ".dll" ); if (!p) strcat( dllname, ".dll" );
...@@ -295,7 +296,7 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags) ...@@ -295,7 +296,7 @@ WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags)
if (!(module = BUILTIN32_DoLoadImage( builtin_dlls[i] ))) return NULL; if (!(module = BUILTIN32_DoLoadImage( builtin_dlls[i] ))) return NULL;
/* Create 32-bit MODREF */ /* 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 ); ERR( "can't load %s\n", path );
SetLastError( ERROR_OUTOFMEMORY ); 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