diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index e1810bc5ab9..e919d7e2671 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -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; diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 10089a740c2..01d4f3ea418 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -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) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index e362f5eb4db..cbafa0d8882 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -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)); } diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index d0fa7a54f49..0f14e69f2be 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -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;