Moved loadorder support to dlls/ntdll.
Removed the --dll option and replaced it by the WINEDLLOVERRIDES environment variable.
This commit is contained in:
parent
1d2eb37bde
commit
2052538a47
|
@ -47,6 +47,7 @@
|
|||
#include "builtin16.h"
|
||||
#include "stackframe.h"
|
||||
#include "excpt.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/exception.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -1201,7 +1202,18 @@ static HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit, BOOL lib_
|
|||
loadorder[0] = LOADORDER_BI;
|
||||
loadorder[1] = LOADORDER_INVALID;
|
||||
}
|
||||
else MODULE_GetLoadOrder(loadorder, basename, FALSE);
|
||||
else
|
||||
{
|
||||
WCHAR buffer[MAX_PATH], *p;
|
||||
|
||||
if (!GetModuleFileNameW( 0, buffer, MAX_PATH )) p = NULL;
|
||||
else
|
||||
{
|
||||
if ((p = strrchrW( buffer, '\\' ))) p++;
|
||||
else p = buffer;
|
||||
}
|
||||
MODULE_GetLoadOrder(loadorder, p, basename, FALSE);
|
||||
}
|
||||
|
||||
for(i = 0; i < LOADORDER_NTYPES; i++)
|
||||
{
|
||||
|
|
|
@ -185,7 +185,7 @@ static HANDLE open_exe_file( const char *name )
|
|||
name = buffer;
|
||||
}
|
||||
|
||||
MODULE_GetLoadOrder( loadorder, name, TRUE );
|
||||
MODULE_GetLoadOrder( loadorder, NULL, name, TRUE );
|
||||
|
||||
for(i = 0; i < LOADORDER_NTYPES; i++)
|
||||
{
|
||||
|
@ -246,7 +246,7 @@ static BOOL find_exe_file( const char *name, char *buffer, int buflen, HANDLE *h
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
MODULE_GetLoadOrder( loadorder, buffer, TRUE );
|
||||
MODULE_GetLoadOrder( loadorder, NULL, buffer, TRUE );
|
||||
|
||||
for(i = 0; i < LOADORDER_NTYPES; i++)
|
||||
{
|
||||
|
|
|
@ -12,7 +12,6 @@ C_SRCS = \
|
|||
$(TOPOBJDIR)/files/drive.c \
|
||||
$(TOPOBJDIR)/files/file.c \
|
||||
$(TOPOBJDIR)/files/smb.c \
|
||||
$(TOPOBJDIR)/loader/loadorder.c \
|
||||
$(TOPOBJDIR)/loader/module.c \
|
||||
$(TOPOBJDIR)/loader/task.c \
|
||||
$(TOPOBJDIR)/loader/ne/module.c \
|
||||
|
@ -42,6 +41,7 @@ C_SRCS = \
|
|||
heap.c \
|
||||
large_int.c \
|
||||
loader.c \
|
||||
loadorder.c \
|
||||
misc.c \
|
||||
nt.c \
|
||||
om.c \
|
||||
|
|
|
@ -1263,6 +1263,7 @@ static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
|
|||
LPSTR filename;
|
||||
const char *filetype = "";
|
||||
DWORD found;
|
||||
WINE_MODREF *main_exe;
|
||||
BOOL allocated_libdir = FALSE;
|
||||
static LPCSTR libdir = NULL; /* See above */
|
||||
NTSTATUS nts = STATUS_NO_SUCH_FILE;
|
||||
|
@ -1343,7 +1344,8 @@ static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
MODULE_GetLoadOrder( loadorder, filename, TRUE);
|
||||
main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
|
||||
MODULE_GetLoadOrder( loadorder, main_exe->ldr.BaseDllName.Buffer, filename, TRUE);
|
||||
|
||||
for (i = 0; i < LOADORDER_NTYPES; i++)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* Module/Library loadorder
|
||||
* Dlls load order support
|
||||
*
|
||||
* Copyright 1999 Bertho Stultiens
|
||||
* Copyright 2003 Alexandre Julliard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -33,6 +34,7 @@
|
|||
#include "winternl.h"
|
||||
#include "file.h"
|
||||
#include "module.h"
|
||||
#include "ntdll_misc.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
@ -109,7 +111,8 @@ static const enum loadorder_type default_path_loadorder[LOADORDER_NTYPES] =
|
|||
LOADORDER_DLL, LOADORDER_BI, 0
|
||||
};
|
||||
|
||||
static struct loadorder_list cmdline_list;
|
||||
static int init_done;
|
||||
static struct loadorder_list env_list;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -125,46 +128,6 @@ static int cmp_sort_func(const void *s1, const void *s2)
|
|||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* get_tok (internal, static)
|
||||
*
|
||||
* strtok wrapper for non-destructive buffer writing.
|
||||
* NOTE: strtok is not reentrant and therefore this code is neither.
|
||||
*/
|
||||
static char *get_tok(const char *str, const char *delim)
|
||||
{
|
||||
static char *buf = NULL;
|
||||
char *cptr;
|
||||
|
||||
if(!str && !buf)
|
||||
return NULL;
|
||||
|
||||
if(str && buf)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
if(str && !buf)
|
||||
{
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, strlen(str)+1);
|
||||
strcpy( buf, str );
|
||||
cptr = strtok(buf, delim);
|
||||
}
|
||||
else
|
||||
{
|
||||
cptr = strtok(NULL, delim);
|
||||
}
|
||||
|
||||
if(!cptr)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
buf = NULL;
|
||||
}
|
||||
return cptr;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* get_basename
|
||||
*
|
||||
|
@ -208,153 +171,172 @@ static const char *debugstr_loadorder( enum loadorder_type lo[] )
|
|||
|
||||
|
||||
/***************************************************************************
|
||||
* ParseLoadOrder (internal, static)
|
||||
* append_load_order
|
||||
*
|
||||
* Parses the loadorder options from the configuration and puts it into
|
||||
* a structure.
|
||||
* Append a load order to the list if necessary.
|
||||
*/
|
||||
static BOOL ParseLoadOrder(char *order, enum loadorder_type lo[])
|
||||
static void append_load_order(enum loadorder_type lo[], enum loadorder_type append)
|
||||
{
|
||||
static int warn;
|
||||
char *cptr;
|
||||
int n = 0;
|
||||
int i;
|
||||
|
||||
cptr = get_tok(order, ", \t");
|
||||
while(cptr)
|
||||
for (i = 0; i < LOADORDER_NTYPES; i++)
|
||||
{
|
||||
enum loadorder_type type = LOADORDER_INVALID;
|
||||
|
||||
if(n >= LOADORDER_NTYPES-1)
|
||||
if (lo[i] == LOADORDER_INVALID) /* append it here */
|
||||
{
|
||||
ERR("More than existing %d module-types specified, rest ignored\n", LOADORDER_NTYPES-1);
|
||||
break;
|
||||
lo[i++] = append;
|
||||
lo[i] = LOADORDER_INVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(*cptr)
|
||||
{
|
||||
case 'N': /* Native */
|
||||
case 'n': type = LOADORDER_DLL; break;
|
||||
|
||||
case 'S': /* So */
|
||||
case 's':
|
||||
if (!warn++) MESSAGE("Load order 'so' no longer supported, ignored\n");
|
||||
break;
|
||||
|
||||
case 'B': /* Builtin */
|
||||
case 'b': type = LOADORDER_BI; break;
|
||||
|
||||
default:
|
||||
ERR("Invalid load order module-type '%s', ignored\n", cptr);
|
||||
if (lo[i] == append) return; /* already in the list */
|
||||
}
|
||||
|
||||
if(type != LOADORDER_INVALID) lo[n++] = type;
|
||||
cptr = get_tok(NULL, ", \t");
|
||||
}
|
||||
lo[n] = LOADORDER_INVALID;
|
||||
return TRUE;
|
||||
assert(0); /* cannot get here */
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* AddLoadOrder (internal, static)
|
||||
* parse_load_order
|
||||
*
|
||||
* Adds an entry in the list of command-line overrides.
|
||||
* Parses the loadorder options from the configuration and puts it into
|
||||
* a structure.
|
||||
*/
|
||||
static BOOL AddLoadOrder(module_loadorder_t *plo)
|
||||
static void parse_load_order( const char *order, enum loadorder_type lo[] )
|
||||
{
|
||||
lo[0] = LOADORDER_INVALID;
|
||||
while (*order)
|
||||
{
|
||||
order += strspn( order, ", \t" );
|
||||
switch(*order)
|
||||
{
|
||||
case 'N': /* Native */
|
||||
case 'n':
|
||||
append_load_order( lo, LOADORDER_DLL );
|
||||
break;
|
||||
case 'B': /* Builtin */
|
||||
case 'b':
|
||||
append_load_order( lo, LOADORDER_BI );
|
||||
break;
|
||||
}
|
||||
order += strcspn( order, ", \t" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* add_load_order
|
||||
*
|
||||
* Adds an entry in the list of environment overrides.
|
||||
*/
|
||||
static void add_load_order( const module_loadorder_t *plo )
|
||||
{
|
||||
int i;
|
||||
|
||||
/* TRACE(module, "'%s' -> %08lx\n", plo->modulename, *(DWORD *)(plo->loadorder)); */
|
||||
|
||||
for(i = 0; i < cmdline_list.count; i++)
|
||||
for(i = 0; i < env_list.count; i++)
|
||||
{
|
||||
if(!cmp_sort_func(plo, &cmdline_list.order[i] ))
|
||||
if(!cmp_sort_func(plo, &env_list.order[i] ))
|
||||
{
|
||||
/* replace existing option */
|
||||
memcpy( cmdline_list.order[i].loadorder, plo->loadorder, sizeof(plo->loadorder));
|
||||
return TRUE;
|
||||
memcpy( env_list.order[i].loadorder, plo->loadorder, sizeof(plo->loadorder));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= cmdline_list.alloc)
|
||||
if (i >= env_list.alloc)
|
||||
{
|
||||
/* No space in current array, make it larger */
|
||||
cmdline_list.alloc += LOADORDER_ALLOC_CLUSTER;
|
||||
cmdline_list.order = HeapReAlloc(GetProcessHeap(), 0, cmdline_list.order,
|
||||
cmdline_list.alloc * sizeof(module_loadorder_t));
|
||||
if(!cmdline_list.order)
|
||||
env_list.alloc += LOADORDER_ALLOC_CLUSTER;
|
||||
if (env_list.order)
|
||||
env_list.order = RtlReAllocateHeap(GetProcessHeap(), 0, env_list.order,
|
||||
env_list.alloc * sizeof(module_loadorder_t));
|
||||
else
|
||||
env_list.order = RtlAllocateHeap(GetProcessHeap(), 0,
|
||||
env_list.alloc * sizeof(module_loadorder_t));
|
||||
if(!env_list.order)
|
||||
{
|
||||
MESSAGE("Virtual memory exhausted\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
memcpy(cmdline_list.order[i].loadorder, plo->loadorder, sizeof(plo->loadorder));
|
||||
cmdline_list.order[i].modulename = HeapAlloc(GetProcessHeap(), 0, strlen(plo->modulename)+1);
|
||||
strcpy( (char *)cmdline_list.order[i].modulename, plo->modulename );
|
||||
cmdline_list.count++;
|
||||
return TRUE;
|
||||
memcpy(env_list.order[i].loadorder, plo->loadorder, sizeof(plo->loadorder));
|
||||
env_list.order[i].modulename = RtlAllocateHeap(GetProcessHeap(), 0, strlen(plo->modulename)+1);
|
||||
strcpy( (char *)env_list.order[i].modulename, plo->modulename );
|
||||
env_list.count++;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* AddLoadOrderSet (internal, static)
|
||||
* add_load_order_set
|
||||
*
|
||||
* Adds a set of entries in the list of command-line overrides from the key parameter.
|
||||
*/
|
||||
static BOOL AddLoadOrderSet(char *key, char *order)
|
||||
static void add_load_order_set( char *entry )
|
||||
{
|
||||
module_loadorder_t ldo;
|
||||
char *cptr;
|
||||
char *end = strchr( entry, '=' );
|
||||
|
||||
/* Parse the loadorder before the rest because strtok is not reentrant */
|
||||
if(!ParseLoadOrder(order, ldo.loadorder))
|
||||
return FALSE;
|
||||
if (!end) return;
|
||||
*end++ = 0;
|
||||
parse_load_order( end, ldo.loadorder );
|
||||
|
||||
cptr = get_tok(key, ", \t");
|
||||
while(cptr)
|
||||
while (*entry)
|
||||
{
|
||||
char *ext = strrchr(cptr, '.');
|
||||
entry += strspn( entry, ", \t" );
|
||||
end = entry + strcspn( entry, ", \t" );
|
||||
if (*end) *end++ = 0;
|
||||
if (*entry)
|
||||
{
|
||||
char *ext = strrchr(entry, '.');
|
||||
if(ext && !FILE_strcasecmp( ext, ".dll" )) *ext = 0;
|
||||
ldo.modulename = cptr;
|
||||
if(!AddLoadOrder(&ldo)) return FALSE;
|
||||
cptr = get_tok(NULL, ", \t");
|
||||
ldo.modulename = entry;
|
||||
add_load_order( &ldo );
|
||||
entry = end;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* MODULE_AddLoadOrderOption
|
||||
*
|
||||
* The commandline option is in the form:
|
||||
* name[,name,...]=native[,b,...]
|
||||
* init_load_order
|
||||
*/
|
||||
void MODULE_AddLoadOrderOption( const char *option )
|
||||
static void init_load_order(void)
|
||||
{
|
||||
char *value, *key = HeapAlloc(GetProcessHeap(), 0, strlen(option)+1);
|
||||
const char *order = getenv( "WINEDLLOVERRIDES" );
|
||||
char *str, *entry, *next;
|
||||
|
||||
strcpy( key, option );
|
||||
if (!(value = strchr(key, '='))) goto error;
|
||||
*value++ = '\0';
|
||||
init_done = 1;
|
||||
if (!order) return;
|
||||
|
||||
TRACE("Commandline override '%s' = '%s'\n", key, value);
|
||||
if (!strcmp( order, "help" ))
|
||||
{
|
||||
MESSAGE( "Syntax:\n"
|
||||
" WINEDLLOVERRIDES=\"entry;entry;entry...\"\n"
|
||||
" where each entry is of the form:\n"
|
||||
" module[,module...]={native|builtin}[,{b|n}]\n"
|
||||
"\n"
|
||||
" Only the first letter of the override (native or builtin)\n"
|
||||
" is significant.\n\n"
|
||||
"Example:\n"
|
||||
" WINEDLLOVERRIDES=\"comdlg32,commdlg=n,b;shell,shell32=b\"\n" );
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!AddLoadOrderSet(key, value)) goto error;
|
||||
HeapFree(GetProcessHeap(), 0, key);
|
||||
str = RtlAllocateHeap( GetProcessHeap(), 0, strlen(order)+1 );
|
||||
strcpy( str, order );
|
||||
entry = str;
|
||||
while (*entry)
|
||||
{
|
||||
while (*entry && *entry == ';') entry++;
|
||||
if (!*entry) break;
|
||||
next = strchr( entry, ';' );
|
||||
if (next) *next++ = 0;
|
||||
else next = entry + strlen(entry);
|
||||
add_load_order_set( entry );
|
||||
entry = next;
|
||||
}
|
||||
RtlFreeHeap( GetProcessHeap(), 0, str );
|
||||
|
||||
/* sort the array for quick lookup */
|
||||
qsort(cmdline_list.order, cmdline_list.count, sizeof(cmdline_list.order[0]), cmp_sort_func);
|
||||
return;
|
||||
|
||||
error:
|
||||
MESSAGE( "Syntax: -dll name[,name[,...]]={native|so|builtin}[,{n|s|b}[,...]]\n"
|
||||
" - 'name' is the name of any dll without extension\n"
|
||||
" - the order of loading (native, so and builtin) can be abbreviated\n"
|
||||
" with the first letter\n"
|
||||
" - the option can be specified multiple times\n"
|
||||
" Example:\n"
|
||||
" -dll comdlg32,commdlg=n -dll shell,shell32=b\n" );
|
||||
ExitProcess(1);
|
||||
if (env_list.count)
|
||||
qsort(env_list.order, env_list.count, sizeof(env_list.order[0]), cmp_sort_func);
|
||||
}
|
||||
|
||||
|
||||
|
@ -382,27 +364,29 @@ static BOOL get_list_load_order( const char *module, const struct loadorder_list
|
|||
*
|
||||
* Open the registry key to the app-specific DllOverrides list.
|
||||
*/
|
||||
static HKEY open_app_key( const char *module )
|
||||
static HKEY open_app_key( const WCHAR *app_name, const char *module )
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
HKEY hkey, appkey;
|
||||
char buffer[MAX_PATH+16], *appname;
|
||||
HKEY hkey;
|
||||
WCHAR *str;
|
||||
static const WCHAR AppDefaultsW[] = {'M','a','c','h','i','n','e','\\',
|
||||
'S','o','f','t','w','a','r','e','\\',
|
||||
'W','i','n','e','\\',
|
||||
'W','i','n','e','\\',
|
||||
'C','o','n','f','i','g','\\',
|
||||
'A','p','p','D','e','f','a','u','l','t','s',0};
|
||||
'A','p','p','D','e','f','a','u','l','t','s','\\',0};
|
||||
static const WCHAR DllOverridesW[] = {'\\','D','l','l','O','v','e','r','r','i','d','e','s',0};
|
||||
|
||||
if (!GetModuleFileNameA( 0, buffer, MAX_PATH ))
|
||||
{
|
||||
WARN( "could not get module file name loading %s\n", module );
|
||||
return 0;
|
||||
}
|
||||
appname = (char *)get_basename( buffer );
|
||||
str = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||
sizeof(AppDefaultsW) + sizeof(DllOverridesW) +
|
||||
strlenW(app_name) * sizeof(WCHAR) );
|
||||
if (!str) return 0;
|
||||
strcpyW( str, AppDefaultsW );
|
||||
strcatW( str, app_name );
|
||||
strcatW( str, DllOverridesW );
|
||||
|
||||
TRACE( "searching '%s' in AppDefaults\\%s\\DllOverrides\n", module, appname );
|
||||
TRACE( "searching '%s' in %s\n", module, debugstr_w(str) );
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
|
@ -410,18 +394,11 @@ static HKEY open_app_key( const char *module )
|
|||
attr.Attributes = 0;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
RtlInitUnicodeString( &nameW, AppDefaultsW );
|
||||
RtlInitUnicodeString( &nameW, str );
|
||||
|
||||
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) return 0;
|
||||
attr.RootDirectory = hkey;
|
||||
|
||||
/* open AppDefaults\\appname\\DllOverrides key */
|
||||
strcat( appname, "\\DllOverrides" );
|
||||
RtlCreateUnicodeStringFromAsciiz( &nameW, appname );
|
||||
if (NtOpenKey( &appkey, KEY_ALL_ACCESS, &attr )) appkey = 0;
|
||||
RtlFreeUnicodeString( &nameW );
|
||||
NtClose( hkey );
|
||||
return appkey;
|
||||
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) hkey = 0;
|
||||
RtlFreeHeap( GetProcessHeap(), 0, str );
|
||||
return hkey;
|
||||
}
|
||||
|
||||
|
||||
|
@ -501,7 +478,7 @@ BOOL MODULE_GetBuiltinPath( const char *libname, const char *ext, char *filename
|
|||
if (strlen(libname) >= size) return FALSE; /* too long */
|
||||
if (strchr( libname, '/' )) /* need to convert slashes */
|
||||
{
|
||||
if (!(tmp = HeapAlloc( GetProcessHeap(), 0, strlen(libname)+1 ))) return FALSE;
|
||||
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, strlen(libname)+1 ))) return FALSE;
|
||||
strcpy( tmp, libname );
|
||||
for (p = tmp; *p; p++) if (*p == '/') *p = '\\';
|
||||
}
|
||||
|
@ -512,7 +489,7 @@ BOOL MODULE_GetBuiltinPath( const char *libname, const char *ext, char *filename
|
|||
strcpy( filename, tmp );
|
||||
ret = TRUE;
|
||||
}
|
||||
if (tmp != libname) HeapFree( GetProcessHeap(), 0, tmp );
|
||||
if (tmp != libname) RtlFreeHeap( GetProcessHeap(), 0, tmp );
|
||||
if (!ret) return FALSE;
|
||||
}
|
||||
else
|
||||
|
@ -539,8 +516,11 @@ BOOL MODULE_GetBuiltinPath( const char *libname, const char *ext, char *filename
|
|||
* Any path is stripped from the path-argument and so are the extension
|
||||
* '.dll' and '.exe'. A lookup in the table can yield an override for
|
||||
* the specific dll. Otherwise the default load order is returned.
|
||||
*
|
||||
* FIXME: 'path' should be Unicode too.
|
||||
*/
|
||||
void MODULE_GetLoadOrder( enum loadorder_type loadorder[], const char *path, BOOL win32 )
|
||||
void MODULE_GetLoadOrder( enum loadorder_type loadorder[], const WCHAR *app_name,
|
||||
const char *path, BOOL win32 )
|
||||
{
|
||||
static const WCHAR DllOverridesW[] = {'M','a','c','h','i','n','e','\\',
|
||||
'S','o','f','t','w','a','r','e','\\',
|
||||
|
@ -554,6 +534,8 @@ void MODULE_GetLoadOrder( enum loadorder_type loadorder[], const char *path, BOO
|
|||
char *module, *basename;
|
||||
int len;
|
||||
|
||||
if (!init_done) init_load_order();
|
||||
|
||||
TRACE("looking for %s\n", path);
|
||||
|
||||
loadorder[0] = LOADORDER_INVALID; /* in case something bad happens below */
|
||||
|
@ -573,7 +555,7 @@ void MODULE_GetLoadOrder( enum loadorder_type loadorder[], const char *path, BOO
|
|||
}
|
||||
|
||||
if (!(len = strlen(path))) return;
|
||||
if (!(module = HeapAlloc( GetProcessHeap(), 0, len + 2 ))) return;
|
||||
if (!(module = RtlAllocateHeap( GetProcessHeap(), 0, len + 2 ))) return;
|
||||
strcpy( module+1, path ); /* reserve module[0] for the wildcard char */
|
||||
|
||||
if (len >= 4)
|
||||
|
@ -582,22 +564,25 @@ void MODULE_GetLoadOrder( enum loadorder_type loadorder[], const char *path, BOO
|
|||
if (!FILE_strcasecmp( ext, ".dll" )) *ext = 0;
|
||||
}
|
||||
|
||||
/* check command-line first */
|
||||
if (get_list_load_order( module+1, &cmdline_list, loadorder ))
|
||||
/* check environment variable first */
|
||||
if (get_list_load_order( module+1, &env_list, loadorder ))
|
||||
{
|
||||
TRACE( "got cmdline %s for %s\n",
|
||||
TRACE( "got environment %s for %s\n",
|
||||
debugstr_loadorder(loadorder), debugstr_a(path) );
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* then explicit module name in AppDefaults */
|
||||
app_key = open_app_key( module+1 );
|
||||
if (app_name)
|
||||
{
|
||||
app_key = open_app_key( app_name, module+1 );
|
||||
if (app_key && get_registry_value( app_key, module+1, loadorder ))
|
||||
{
|
||||
TRACE( "got app defaults %s for %s\n",
|
||||
debugstr_loadorder(loadorder), debugstr_a(path) );
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* then explicit module name in standard section */
|
||||
if (std_key == (HKEY)-1)
|
||||
|
@ -681,5 +666,5 @@ void MODULE_GetLoadOrder( enum loadorder_type loadorder[], const char *path, BOO
|
|||
|
||||
done:
|
||||
if (app_key) NtClose( app_key );
|
||||
HeapFree( GetProcessHeap(), 0, module );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, module );
|
||||
}
|
|
@ -51,6 +51,7 @@ static inline HANDLE ntdll_get_process_heap(void)
|
|||
{
|
||||
return NtCurrentTeb()->Peb->ProcessHeap;
|
||||
}
|
||||
#define GetProcessHeap() ntdll_get_process_heap()
|
||||
|
||||
static inline RTL_USER_PROCESS_PARAMETERS* ntdll_get_process_pmts(void)
|
||||
{
|
||||
|
|
|
@ -104,49 +104,6 @@ For more information on debugging messages, see the file
|
|||
.I documentation/running.sgml
|
||||
in the source distribution (FIXME: outdated).
|
||||
.RE
|
||||
.TP
|
||||
.I --dll name[,name[,...]]={native|builtin}[,{n|b}[,...]]
|
||||
Selects the override type and load order of dll used in the loading
|
||||
process for any dll. The default is set in the configuration
|
||||
file. There are currently three types of libraries that can be loaded
|
||||
into a process' address space: Native windows dlls (
|
||||
.I native
|
||||
),
|
||||
.B wine
|
||||
internal dlls (
|
||||
.I builtin
|
||||
). The type may be abbreviated with the first letter of the type (
|
||||
.I n, b
|
||||
). Each sequence of orders must be separated by commas.
|
||||
.br
|
||||
Each dll may have its own specific load order. The load order
|
||||
determines which version of the dll is attempted to be loaded into the
|
||||
address space. If the first fails, then the next is tried and so
|
||||
on. 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
|
||||
.I --dll comdlg32,commdlg=n,b
|
||||
.br
|
||||
Try to load comdlg32 and commdlg as native windows dll first and try
|
||||
the builtin version if the native load fails.
|
||||
.br
|
||||
.I --dll shell,shell32=n --dll c:\(rs\(rsfoo\(rs\(rsbar\(rs\(rsbaz=b
|
||||
.br
|
||||
Try to load the libraries shell and shell32 as native windows dlls. Furthermore, if
|
||||
an application request to load c:\(rsfoo\(rsbar\(rsbaz.dll load the builtin library baz.
|
||||
.br
|
||||
.I --dll comdlg32,commdlg=b,n --dll shell,shell32=b --dll comctl32,commctrl=n
|
||||
.br
|
||||
Try to load comdlg32 and commdlg as builtin first and try the native version
|
||||
if the builtin load fails; load shell32/shell always as builtin and
|
||||
comctl32/commctrl always as native.
|
||||
.br
|
||||
Note: It is wise to keep dll pairs (comdlg32/commdlg, shell/shell32, etc.)
|
||||
having exactly the same load order. This will prevent mismatches at runtime.
|
||||
See also configuration file format below.
|
||||
.PD 1
|
||||
.SH PROGRAM/ARGUMENTS
|
||||
The program name may be specified in DOS format (
|
||||
|
@ -181,7 +138,7 @@ by
|
|||
For example, if you want to execute
|
||||
.B wine
|
||||
with the options
|
||||
.I --dll riched32=n
|
||||
.I --debugmsg +module
|
||||
and if
|
||||
.B wine
|
||||
should run the program
|
||||
|
@ -191,7 +148,7 @@ with the arguments
|
|||
, then you could use the following command line to invoke
|
||||
.B wine:
|
||||
.PP
|
||||
.I wine --dll riched32=n -- myapp.exe --display 3d somefile
|
||||
.I wine --debugmsg +module -- myapp.exe --display 3d somefile
|
||||
.PP
|
||||
Note that in contrast to previous versions of
|
||||
.B wine,
|
||||
|
@ -255,14 +212,61 @@ addition to any directory specified in
|
|||
Wine will also look in
|
||||
.B @dlldir@.
|
||||
.TP
|
||||
.I WINEDLLOVERRIDES
|
||||
Defines the override type and load order of dlls used in the loading
|
||||
process for any dll. The default is set in the configuration
|
||||
file. There are currently two types of libraries that can be loaded
|
||||
into a process' address space: Native windows dlls (
|
||||
.I native
|
||||
),
|
||||
.B wine
|
||||
internal dlls (
|
||||
.I builtin
|
||||
). The type may be abbreviated with the first letter of the type (
|
||||
.I n, b
|
||||
). Each sequence of orders must be separated by commas.
|
||||
.br
|
||||
Each dll may have its own specific load order. The load order
|
||||
determines which version of the dll is attempted to be loaded into the
|
||||
address space. If the first fails, then the next is tried and so
|
||||
on. Multiple libraries with the same load order can be separated with
|
||||
commas. It is also possible to use specify different loadorders for
|
||||
different libraries by separating the entries by ";".
|
||||
.br
|
||||
Examples:
|
||||
.RS
|
||||
.TP
|
||||
WINEDLLOVERRIDES="comdlg32,commdlg=n,b"
|
||||
.br
|
||||
Try to load comdlg32 and commdlg as native windows dll first and try
|
||||
the builtin version if the native load fails.
|
||||
.TP
|
||||
WINEDLLOVERRIDES="shell,shell32=n;c:\(rs\(rsfoo\(rs\(rsbar\(rs\(rsbaz=b"
|
||||
.br
|
||||
Try to load the libraries shell and shell32 as native windows dlls. Furthermore, if
|
||||
an application request to load c:\(rsfoo\(rsbar\(rsbaz.dll load the builtin library baz.
|
||||
.TP
|
||||
WINEDLLOVERRIDES="comdlg32,commdlg=b,n;shell,shell32=b;comctl32,commctrl=n"
|
||||
.br
|
||||
Try to load comdlg32 and commdlg as builtin first and try the native version
|
||||
if the builtin load fails; load shell32/shell always as builtin and
|
||||
comctl32/commctrl always as native.
|
||||
.br
|
||||
Note: It is wise to keep dll pairs (comdlg32/commdlg, shell/shell32, etc.)
|
||||
having exactly the same load order. This will prevent mismatches at runtime.
|
||||
See also configuration file format below.
|
||||
.RE
|
||||
.TP
|
||||
.I DISPLAY
|
||||
Specifies the X11 display to use.
|
||||
.SH CONFIGURATION FILE
|
||||
.B wine
|
||||
expects a configuration file (
|
||||
.I $WINEPREFIX/config
|
||||
(~/.wine/config)
|
||||
), which must conform to the format specified in the
|
||||
or
|
||||
.I ~/.wine/config
|
||||
if WINEPREFIX is not set), which must conform to the format specified
|
||||
in the
|
||||
.BR wine.conf (5)
|
||||
man page. A sample configuration file is documentation/samples/config in the
|
||||
.B wine
|
||||
|
|
|
@ -217,8 +217,8 @@ extern HRSRC PE_FindResourceExW(HMODULE,LPCWSTR,LPCWSTR,WORD);
|
|||
|
||||
/* loader/loadorder.c */
|
||||
extern BOOL MODULE_GetBuiltinPath( const char *libname, const char *ext, char *filename, UINT size );
|
||||
extern void MODULE_GetLoadOrder( enum loadorder_type plo[], const char *path, BOOL win32 );
|
||||
extern void MODULE_AddLoadOrderOption( const char *option );
|
||||
extern void MODULE_GetLoadOrder( enum loadorder_type plo[], const WCHAR *app_name,
|
||||
const char *path, BOOL win32 );
|
||||
|
||||
/* relay32/builtin.c */
|
||||
extern HMODULE BUILTIN32_LoadExeModule( HMODULE main );
|
||||
|
|
|
@ -56,6 +56,7 @@ static void out_of_memory(void)
|
|||
}
|
||||
|
||||
static void do_debugmsg( const char *arg );
|
||||
static void do_dll( const char *arg );
|
||||
static void do_help( const char *arg );
|
||||
static void do_version( const char *arg );
|
||||
|
||||
|
@ -63,8 +64,8 @@ static const struct option_descr option_table[] =
|
|||
{
|
||||
{ "debugmsg", 0, 1, 1, do_debugmsg,
|
||||
"--debugmsg name Turn debugging-messages on or off" },
|
||||
{ "dll", 0, 1, 1, MODULE_AddLoadOrderOption,
|
||||
"--dll name Enable or disable built-in DLLs" },
|
||||
{ "dll", 0, 1, 1, do_dll,
|
||||
"--dll name This option is no longer supported" },
|
||||
{ "help", 'h', 0, 0, do_help,
|
||||
"--help,-h Show this help message" },
|
||||
{ "version", 'v', 0, 0, do_version,
|
||||
|
@ -96,6 +97,14 @@ static void do_debugmsg( const char *arg )
|
|||
}
|
||||
}
|
||||
|
||||
static void do_dll( const char *arg )
|
||||
{
|
||||
MESSAGE("The --dll option has been removed, you should use\n"
|
||||
"the WINEDLLOVERRIDES environment variable instead.\n"
|
||||
"To see a help message, run:\n"
|
||||
" WINEDLLOVERRIDES=help wine <program.exe>\n");
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
static void remove_options( char *argv[], int pos, int count, int inherit )
|
||||
{
|
||||
|
|
|
@ -110,8 +110,8 @@ fi
|
|||
# set environment variables needed for Wine
|
||||
|
||||
if [ -n "$modules" ]; then
|
||||
WINEOPTIONS="$WINEOPTIONS --dll $modules=b"
|
||||
export WINEOPTIONS
|
||||
WINEDLLOVERRIDES="$WINEDLLOVERRIDES;$modules=b"
|
||||
export WINEDLLOVERRIDES
|
||||
fi
|
||||
WINETEST_PLATFORM=${platform:-wine}
|
||||
export WINETEST_PLATFORM WINETEST_DEBUG
|
||||
|
|
Loading…
Reference in New Issue