[PATCH] server: Automatically create ProfileList key for current user.

Dmitry Timoshkov dmitry at baikal.ru
Tue Nov 19 21:40:32 CST 2019


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 at 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 ), &current_user_str );
+    if (!current_user_path ||
+        !(profile_key = create_key_recursive( key, &current_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)
 {
-- 
2.20.1




More information about the wine-devel mailing list