[PATCH] kernelbase: Pass inherited handles list when creating new process.

Nikolay Sivov nsivov at codeweavers.com
Wed Aug 19 07:55:06 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/kernelbase/process.c | 103 ++++++++++++++++++++++++++++----------
 1 file changed, 77 insertions(+), 26 deletions(-)

diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c
index 2b9b1c019ec..0081b6bf9c8 100644
--- a/dlls/kernelbase/process.c
+++ b/dlls/kernelbase/process.c
@@ -242,26 +242,89 @@ static RTL_USER_PROCESS_PARAMETERS *create_process_params( const WCHAR *filename
     return params;
 }
 
+struct proc_thread_attr
+{
+    DWORD_PTR attr;
+    SIZE_T size;
+    void *value;
+};
+
+struct _PROC_THREAD_ATTRIBUTE_LIST
+{
+    DWORD mask;  /* bitmask of items in list */
+    DWORD size;  /* max number of items in list */
+    DWORD count; /* number of items in list */
+    DWORD pad;
+    DWORD_PTR unk;
+    struct proc_thread_attr attrs[1];
+};
 
 /***********************************************************************
  *           create_nt_process
  */
 static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES *tsa,
                                    BOOL inherit, DWORD flags, RTL_USER_PROCESS_PARAMETERS *params,
-                                   RTL_USER_PROCESS_INFORMATION *info, HANDLE parent )
+                                   RTL_USER_PROCESS_INFORMATION *info, HANDLE parent,
+                                   const struct proc_thread_attr *handle_list )
 {
-    NTSTATUS status;
+    OBJECT_ATTRIBUTES process_attr, thread_attr;
+    PS_CREATE_INFO create_info;
+    ULONG_PTR buffer[offsetof( PS_ATTRIBUTE_LIST, Attributes[5] ) / sizeof(ULONG_PTR)];
+    PS_ATTRIBUTE_LIST *attr = (PS_ATTRIBUTE_LIST *)buffer;
     UNICODE_STRING nameW;
+    NTSTATUS status;
+    UINT pos = 0;
 
     if (!params->ImagePathName.Buffer[0]) return STATUS_OBJECT_PATH_NOT_FOUND;
     status = RtlDosPathNameToNtPathName_U_WithStatus( params->ImagePathName.Buffer, &nameW, NULL, NULL );
     if (!status)
     {
         params->DebugFlags = flags;  /* hack, cf. RtlCreateUserProcess implementation */
-        status = RtlCreateUserProcess( &nameW, OBJ_CASE_INSENSITIVE, params,
-                                       psa ? psa->lpSecurityDescriptor : NULL,
-                                       tsa ? tsa->lpSecurityDescriptor : NULL,
-                                       parent, inherit, 0, 0, info );
+
+        RtlNormalizeProcessParams( params );
+
+        attr->Attributes[pos].Attribute    = PS_ATTRIBUTE_IMAGE_NAME;
+        attr->Attributes[pos].Size         = nameW.Length;
+        attr->Attributes[pos].ValuePtr     = nameW.Buffer;
+        attr->Attributes[pos].ReturnLength = NULL;
+        pos++;
+        attr->Attributes[pos].Attribute    = PS_ATTRIBUTE_CLIENT_ID;
+        attr->Attributes[pos].Size         = sizeof(info->ClientId);
+        attr->Attributes[pos].ValuePtr     = &info->ClientId;
+        attr->Attributes[pos].ReturnLength = NULL;
+        pos++;
+        attr->Attributes[pos].Attribute    = PS_ATTRIBUTE_IMAGE_INFO;
+        attr->Attributes[pos].Size         = sizeof(info->ImageInformation);
+        attr->Attributes[pos].ValuePtr     = &info->ImageInformation;
+        attr->Attributes[pos].ReturnLength = NULL;
+        pos++;
+        if (parent)
+        {
+            attr->Attributes[pos].Attribute    = PS_ATTRIBUTE_PARENT_PROCESS;
+            attr->Attributes[pos].Size         = sizeof(parent);
+            attr->Attributes[pos].ValuePtr     = parent;
+            attr->Attributes[pos].ReturnLength = NULL;
+            pos++;
+        }
+        if (inherit && handle_list)
+        {
+            attr->Attributes[pos].Attribute    = PS_ATTRIBUTE_HANDLE_LIST;
+            attr->Attributes[pos].Size         = handle_list->size;
+            attr->Attributes[pos].ValuePtr     = handle_list->value;
+            attr->Attributes[pos].ReturnLength = NULL;
+            pos++;
+        }
+        attr->TotalLength = offsetof( PS_ATTRIBUTE_LIST, Attributes[pos] );
+
+        InitializeObjectAttributes( &process_attr, NULL, 0, NULL, psa ? psa->lpSecurityDescriptor : NULL );
+        InitializeObjectAttributes( &thread_attr, NULL, 0, NULL, tsa ? tsa->lpSecurityDescriptor : NULL );
+
+        status = NtCreateUserProcess( &info->Process, &info->Thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS,
+                                      &process_attr, &thread_attr,
+                                      inherit ? PROCESS_CREATE_FLAGS_INHERIT_HANDLES : 0,
+                                      THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params,
+                                      &create_info, attr );
+
         RtlFreeUnicodeString( &nameW );
     }
     return status;
@@ -292,7 +355,7 @@ static NTSTATUS create_vdm_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE
               winevdm, params->ImagePathName.Buffer, params->CommandLine.Buffer );
     RtlInitUnicodeString( &params->ImagePathName, winevdm );
     RtlInitUnicodeString( &params->CommandLine, newcmdline );
-    status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL );
+    status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL, NULL );
     HeapFree( GetProcessHeap(), 0, newcmdline );
     return status;
 }
@@ -320,7 +383,7 @@ static NTSTATUS create_cmd_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE
     swprintf( newcmdline, len, L"%s /s/c \"%s\"", comspec, params->CommandLine.Buffer );
     RtlInitUnicodeString( &params->ImagePathName, comspec );
     RtlInitUnicodeString( &params->CommandLine, newcmdline );
-    status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL );
+    status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL, NULL );
     RtlFreeHeap( GetProcessHeap(), 0, newcmdline );
     return status;
 }
@@ -414,23 +477,6 @@ done:
     return ret;
 }
 
-struct proc_thread_attr
-{
-    DWORD_PTR attr;
-    SIZE_T size;
-    void *value;
-};
-
-struct _PROC_THREAD_ATTRIBUTE_LIST
-{
-    DWORD mask;  /* bitmask of items in list */
-    DWORD size;  /* max number of items in list */
-    DWORD count; /* number of items in list */
-    DWORD pad;
-    DWORD_PTR unk;
-    struct proc_thread_attr attrs[1];
-};
-
 /**********************************************************************
  *           CreateProcessInternalW   (kernelbase.@)
  */
@@ -441,6 +487,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
                                                       const WCHAR *cur_dir, STARTUPINFOW *startup_info,
                                                       PROCESS_INFORMATION *info, HANDLE *new_token )
 {
+    const struct proc_thread_attr *handle_list = NULL;
     WCHAR name[MAX_PATH];
     WCHAR *p, *tidy_cmdline = cmd_line;
     RTL_USER_PROCESS_PARAMETERS *params = NULL;
@@ -517,6 +564,10 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
                             goto done;
                         }
                         break;
+                    case PROC_THREAD_ATTRIBUTE_HANDLE_LIST:
+                        handle_list = &attrs->attrs[i];
+                        TRACE("PROC_THREAD_ATTRIBUTE_HANDLE_LIST handle count %Iu.\n", attrs->attrs[i].size / sizeof(HANDLE));
+                        break;
                     default:
                         FIXME("Unsupported attribute %#Ix.\n", attrs->attrs[i].attr);
                         break;
@@ -525,7 +576,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
         }
     }
 
-    status = create_nt_process( process_attr, thread_attr, inherit, flags, params, &rtl_info, parent );
+    status = create_nt_process( process_attr, thread_attr, inherit, flags, params, &rtl_info, parent, handle_list );
     switch (status)
     {
     case STATUS_SUCCESS:
-- 
2.28.0




More information about the wine-devel mailing list