ntdll: Add a WINEBOOTSTRAPMODE environment variable to allow loading non-existent builtins.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50905 Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4f04994ef4
commit
446f7e3aa8
|
@ -1926,14 +1926,10 @@ static NTSTATUS build_module( LPCWSTR load_path, const UNICODE_STRING *nt_name,
|
|||
static void build_ntdll_module(void)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION meminfo;
|
||||
FILE_BASIC_INFORMATION basic_info;
|
||||
UNICODE_STRING nt_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
WINE_MODREF *wm;
|
||||
|
||||
RtlInitUnicodeString( &nt_name, L"\\??\\C:\\windows\\system32\\ntdll.dll" );
|
||||
InitializeObjectAttributes( &attr, &nt_name, OBJ_CASE_INSENSITIVE, 0, NULL );
|
||||
is_prefix_bootstrap = NtQueryAttributesFile( &attr, &basic_info) != STATUS_SUCCESS;
|
||||
NtQueryVirtualMemory( GetCurrentProcess(), build_ntdll_module, MemoryBasicInformation,
|
||||
&meminfo, sizeof(meminfo), NULL );
|
||||
wm = alloc_module( meminfo.AllocationBase, &nt_name, TRUE );
|
||||
|
@ -2672,7 +2668,7 @@ static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING *
|
|||
|
||||
if (found_image)
|
||||
status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
|
||||
else if (is_prefix_bootstrap && !wcspbrk( search, L":/\\" ))
|
||||
else if (is_prefix_bootstrap && !contains_path( search ))
|
||||
status = find_builtin_without_file( search, nt_name, pwm, mapping, image_info, id );
|
||||
|
||||
done:
|
||||
|
@ -3498,10 +3494,14 @@ static void process_breakpoint(void)
|
|||
static void load_global_options(void)
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING name_str;
|
||||
UNICODE_STRING name_str, val_str;
|
||||
HANDLE hkey;
|
||||
ULONG value;
|
||||
|
||||
RtlInitUnicodeString( &name_str, L"WINEBOOTSTRAPMODE" );
|
||||
val_str.MaximumLength = 0;
|
||||
is_prefix_bootstrap = RtlQueryEnvironmentVariable_U( NULL, &name_str, &val_str ) != STATUS_VARIABLE_NOT_FOUND;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.ObjectName = &name_str;
|
||||
|
|
|
@ -64,6 +64,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(environ);
|
|||
|
||||
USHORT *uctable = NULL, *lctable = NULL;
|
||||
SIZE_T startup_info_size = 0;
|
||||
BOOL is_prefix_bootstrap = FALSE;
|
||||
|
||||
static const WCHAR bootstrapW[] = {'W','I','N','E','B','O','O','T','S','T','R','A','P','M','O','D','E'};
|
||||
|
||||
int main_argc = 0;
|
||||
char **main_argv = NULL;
|
||||
|
@ -1211,6 +1214,18 @@ static WCHAR *find_env_var( WCHAR *env, SIZE_T size, const WCHAR *name, SIZE_T n
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static WCHAR *get_env_var( WCHAR *env, SIZE_T size, const WCHAR *name, SIZE_T namelen )
|
||||
{
|
||||
WCHAR *ret = NULL, *var = find_env_var( env, size, name, namelen );
|
||||
|
||||
if (var)
|
||||
{
|
||||
var += namelen + 1; /* skip name */
|
||||
if ((ret = malloc( (wcslen(var) + 1) * sizeof(WCHAR) ))) wcscpy( ret, var );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set an environment variable, replacing it if it exists */
|
||||
static void set_env_var( WCHAR **env, SIZE_T *pos, SIZE_T *size,
|
||||
const WCHAR *name, SIZE_T namelen, const WCHAR *value )
|
||||
|
@ -1889,29 +1904,32 @@ static inline WCHAR *get_dos_path( WCHAR *nt_path )
|
|||
*/
|
||||
static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
|
||||
{
|
||||
static const WCHAR valueW[] = {'1',0};
|
||||
static const WCHAR pathW[] = {'P','A','T','H'};
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
SIZE_T size, env_pos, env_size;
|
||||
WCHAR *dst, *image, *cmdline, *p, *path = NULL;
|
||||
WCHAR *dst, *image, *cmdline, *path, *bootstrap;
|
||||
WCHAR *env = get_initial_environment( &env_pos, &env_size );
|
||||
WCHAR *curdir = get_initial_directory();
|
||||
void *module = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
/* store the initial PATH value */
|
||||
if ((p = find_env_var( env, env_pos, pathW, 4 )))
|
||||
{
|
||||
path = malloc( (wcslen(p + 5) + 1) * sizeof(WCHAR) );
|
||||
wcscpy( path, p + 5 );
|
||||
}
|
||||
path = get_env_var( env, env_pos, pathW, 4 );
|
||||
add_dynamic_environment( &env, &env_pos, &env_size );
|
||||
add_registry_environment( &env, &env_pos, &env_size );
|
||||
bootstrap = get_env_var( env, env_pos, bootstrapW, ARRAY_SIZE(bootstrapW) );
|
||||
set_env_var( &env, &env_pos, &env_size, bootstrapW, ARRAY_SIZE(bootstrapW), valueW );
|
||||
is_prefix_bootstrap = TRUE;
|
||||
env[env_pos] = 0;
|
||||
run_wineboot( env, env_pos );
|
||||
|
||||
/* reload environment now that wineboot has run */
|
||||
set_env_var( &env, &env_pos, &env_size, pathW, 4, path ); /* reset PATH */
|
||||
free( path );
|
||||
set_env_var( &env, &env_pos, &env_size, bootstrapW, ARRAY_SIZE(bootstrapW), bootstrap );
|
||||
is_prefix_bootstrap = !!bootstrap;
|
||||
free( bootstrap );
|
||||
add_registry_environment( &env, &env_pos, &env_size );
|
||||
env[env_pos++] = 0;
|
||||
|
||||
|
@ -2012,6 +2030,7 @@ void init_startup_info(void)
|
|||
memcpy( env, (char *)info + info_size, env_size * sizeof(WCHAR) );
|
||||
env_pos = env_size - 1;
|
||||
add_dynamic_environment( &env, &env_pos, &env_size );
|
||||
is_prefix_bootstrap = !!find_env_var( env, env_pos, bootstrapW, ARRAY_SIZE(bootstrapW) );
|
||||
env[env_pos++] = 0;
|
||||
|
||||
size = (sizeof(*params)
|
||||
|
|
|
@ -1387,10 +1387,10 @@ BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine )
|
|||
{
|
||||
static const WCHAR wow64W[] = {'\\','?','?','\\','c',':','\\','w','i','n','d','o','w','s','\\',
|
||||
's','y','s','w','o','w','6','4'};
|
||||
BOOL is_prefix_bootstrap;
|
||||
unsigned int len;
|
||||
struct stat st;
|
||||
char *ntdll;
|
||||
|
||||
/* only fake builtin existence during prefix bootstrap */
|
||||
if (!is_prefix_bootstrap) return FALSE;
|
||||
|
||||
*machine = current_machine;
|
||||
if (path->Length > wcslen(system_dir) * sizeof(WCHAR) &&
|
||||
|
@ -1413,15 +1413,7 @@ found:
|
|||
len = wcslen(system_dir);
|
||||
while (len < path->Length / sizeof(WCHAR) && path->Buffer[len] == '\\') len++;
|
||||
while (len < path->Length / sizeof(WCHAR) && path->Buffer[len] != '\\') len++;
|
||||
if (len != path->Length / sizeof(WCHAR)) return FALSE;
|
||||
|
||||
/* if the corresponding ntdll exists, don't fake the existence of the builtin */
|
||||
ntdll = build_path( config_dir, *machine == IMAGE_FILE_MACHINE_I386 ?
|
||||
"dosdevices/c:/windows/syswow64/ntdll.dll" :
|
||||
"dosdevices/c:/windows/system32/ntdll.dll" );
|
||||
is_prefix_bootstrap = stat( ntdll, &st ) == -1;
|
||||
free( ntdll );
|
||||
return is_prefix_bootstrap;
|
||||
return (len == path->Length / sizeof(WCHAR));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@ extern const char **dll_paths DECLSPEC_HIDDEN;
|
|||
extern USHORT *uctable DECLSPEC_HIDDEN;
|
||||
extern USHORT *lctable DECLSPEC_HIDDEN;
|
||||
extern SIZE_T startup_info_size DECLSPEC_HIDDEN;
|
||||
extern BOOL is_prefix_bootstrap DECLSPEC_HIDDEN;
|
||||
extern SECTION_IMAGE_INFORMATION main_image_info DECLSPEC_HIDDEN;
|
||||
extern int main_argc DECLSPEC_HIDDEN;
|
||||
extern char **main_argv DECLSPEC_HIDDEN;
|
||||
|
|
Loading…
Reference in New Issue