This patch aims to replace the appropriate patchset from wine-staging, the ProfileList key is populated on first user process creation, and thus this emulates the "system login" phase. If this approach is not acceptable I'd be interested to know a preferred way to add similar functionality.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- server/object.h | 1 + server/process.c | 3 ++ server/registry.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+)
diff --git a/server/object.h b/server/object.h index 4a486e0d63..0744fe4a8d 100644 --- a/server/object.h +++ b/server/object.h @@ -214,6 +214,7 @@ extern void debug_exit_thread( struct thread *thread ); extern unsigned int get_prefix_cpu_mask(void); extern void init_registry(void); extern void flush_registry(void); +extern void init_profilelist(void);
/* signal functions */
diff --git a/server/process.c b/server/process.c index 16bb5d57e7..5c7bd40c8a 100644 --- a/server/process.c +++ b/server/process.c @@ -1208,6 +1208,9 @@ DECL_HANDLER(new_process)
if (!(process = create_process( socket_fd, parent, req->inherit_all, sd ))) goto done;
+ if (running_processes == 1) + init_profilelist(); + process->startup_info = (struct startup_info *)grab_object( info );
if (req->exe_file && diff --git a/server/registry.c b/server/registry.c index 48a0f28c97..0a3c32640b 100644 --- a/server/registry.c +++ b/server/registry.c @@ -1762,6 +1762,77 @@ static WCHAR *format_user_registry_path( const SID *sid, struct unicode_str *pat return p; }
+static WCHAR *format_user_sid_path( const SID *sid, struct unicode_str *path ) +{ + static const WCHAR prefixW[] = {'S',0}; + static const WCHAR formatW[] = {'-','%','u',0}; + WCHAR buffer[1 + 10 + 10 + 10 * SID_MAX_SUB_AUTHORITIES]; + WCHAR *p = buffer; + unsigned int i; + + strcpyW( p, prefixW ); + p += strlenW( prefixW ); + p += sprintfW( p, formatW, sid->Revision ); + p += sprintfW( p, formatW, MAKELONG( MAKEWORD( sid->IdentifierAuthority.Value[5], + sid->IdentifierAuthority.Value[4] ), + MAKEWORD( sid->IdentifierAuthority.Value[3], + sid->IdentifierAuthority.Value[2] ))); + for (i = 0; i < sid->SubAuthorityCount; i++) + p += sprintfW( p, formatW, sid->SubAuthority[i] ); + + path->len = (p - buffer) * sizeof(WCHAR); + path->str = p = memdup( buffer, path->len ); + return p; +} + +void init_profilelist(void) +{ + static const WCHAR profile_list[] = {'M','a','c','h','i','n','e','\', + 'S','o','f','t','w','a','r','e','\', + 'M','i','c','r','o','s','o','f','t','\', + 'W','i','n','d','o','w','s',' ','N','T','\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\', + 'P','r','o','f','i','l','e','L','i','s','t'}; + static const WCHAR image_path[] = {'P','r','o','f','i','l','e','I','m','a','g','e','P','a','t','h'}; + static const struct unicode_str profile_list_name = { profile_list, sizeof(profile_list) }; + static const struct unicode_str image_path_name = { image_path, sizeof(image_path) }; + static const WCHAR users[] = {'C',':','\','u','s','e','r','s','\'}; + WCHAR *current_user_path, *profile; + struct unicode_str current_user_str; + struct key *key, *profile_key; + const char *user; + int len; + + if (!(key = create_key_recursive( root_key, &profile_list_name, current_time ))) + fatal_error( "could not create ProfileList key\n" ); + + current_user_path = format_user_sid_path( token_get_user( current->process->token ), ¤t_user_str ); + if (!current_user_path || + !(profile_key = create_key_recursive( key, ¤t_user_str, current_time ))) + fatal_error( "could not create ProfileList\SID registry key\n" ); + + if (debug_level) + { + fprintf( stderr, "profile: " ); + dump_strW( current_user_str.str, current_user_str.len / sizeof(WCHAR), stderr, """" ); + fprintf( stderr, ""\n" ); + } + free( current_user_path ); + + user = wine_get_user_name(); + + len = sizeof(users) + (strlen(user) + 1) * sizeof(WCHAR); + profile = mem_alloc( len ); + memcpy( profile, users, sizeof(users) ); + wine_utf8_mbstowcs( 0, user, strlen(user) + 1, profile + sizeof(users) / sizeof(WCHAR), len ); + + set_value( profile_key, &image_path_name, REG_EXPAND_SZ, profile, len ); + free( profile ); + + release_object( profile_key ); + release_object( key ); +} + /* get the cpu architectures that can be supported in the current prefix */ unsigned int get_prefix_cpu_mask(void) {