Paul Gofman : kernel32/tests: Add a basic test for PROC_THREAD_ATTRIBUTE_PARENT_PROCESS process creation attribute.

Alexandre Julliard julliard at winehq.org
Thu Dec 5 17:14:11 CST 2019


Module: wine
Branch: master
Commit: 52d8ea3aa8e576ac626cb309686dfdbe14ee4d9a
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=52d8ea3aa8e576ac626cb309686dfdbe14ee4d9a

Author: Paul Gofman <gofmanp at gmail.com>
Date:   Thu Dec  5 16:38:54 2019 +0300

kernel32/tests: Add a basic test for PROC_THREAD_ATTRIBUTE_PARENT_PROCESS process creation attribute.

Signed-off-by: Paul Gofman <gofmanp at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/process.c | 126 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 124 insertions(+), 2 deletions(-)

diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index f181536e7a..a3118d11bf 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -36,6 +36,7 @@
 #include "tlhelp32.h"
 
 #include "wine/test.h"
+#include "wine/heap.h"
 
 /* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */
 #define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000)
@@ -3808,6 +3809,120 @@ static void test_ProcThreadAttributeList(void)
     pDeleteProcThreadAttributeList(&list);
 }
 
+/* level 0: Main test process
+ * level 1: Process created by level 0 process without handle inheritance
+ * level 2: Process created by level 1 process with handle inheritance and level 0
+ *          process parent substitute. */
+void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
+{
+    PROCESS_BASIC_INFORMATION pbi;
+    char buffer[MAX_PATH + 64];
+    HANDLE write_pipe = NULL;
+    PROCESS_INFORMATION info;
+    SECURITY_ATTRIBUTES sa;
+    STARTUPINFOEXA si;
+    DWORD parent_id;
+    NTSTATUS status;
+    ULONG pbi_size;
+    HANDLE parent;
+    DWORD size;
+    BOOL ret;
+
+    struct
+    {
+        HANDLE parent;
+        DWORD parent_id;
+    }
+    parent_data;
+
+    if (!pInitializeProcThreadAttributeList)
+    {
+        win_skip("No support for ProcThreadAttributeList.\n");
+        return;
+    }
+
+    memset(&sa, 0, sizeof(sa));
+    sa.nLength = sizeof(sa);
+    sa.bInheritHandle = TRUE;
+
+    if (!level)
+    {
+        ret = CreatePipe(&read_pipe, &write_pipe, &sa, 0);
+        ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+        parent_data.parent = OpenProcess(PROCESS_CREATE_PROCESS | PROCESS_QUERY_INFORMATION, TRUE, GetCurrentProcessId());
+        parent_data.parent_id = GetCurrentProcessId();
+    }
+    else
+    {
+        status = NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), &pbi_size);
+        ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
+        parent_id = pbi.InheritedFromUniqueProcessId;
+
+        memset(&parent_data, 0, sizeof(parent_data));
+        ret = ReadFile(read_pipe, &parent_data, sizeof(parent_data), &size, NULL);
+        todo_wine_if(level == 2) ok((level == 2 && ret) || (level == 1 && !ret && GetLastError() == ERROR_INVALID_HANDLE),
+                "Got unexpected ret %#x, level %u, GetLastError() %u.\n",
+                ret, level, GetLastError());
+    }
+
+    if (level == 2)
+    {
+        todo_wine ok(parent_id == parent_data.parent_id, "Got parent id %u, parent_data.parent_id %u.\n",
+                parent_id, parent_data.parent_id);
+        return;
+    }
+
+    memset(&si, 0, sizeof(si));
+    si.StartupInfo.cb = sizeof(si.StartupInfo);
+
+    if (level)
+    {
+        SIZE_T size;
+
+        ret = pInitializeProcThreadAttributeList(NULL, 1, 0, &size);
+        ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+                "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+        si.lpAttributeList = heap_alloc(size);
+        ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+        ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+        parent = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, parent_id);
+
+        ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+                &parent, sizeof(parent), NULL, NULL);
+        ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+    }
+
+    sprintf(buffer, "\"%s\" tests/process.c parent %u %p", selfname, level + 1, read_pipe);
+    ret = CreateProcessA(NULL, buffer, NULL, NULL, level == 1, level == 1 ? EXTENDED_STARTUPINFO_PRESENT : 0,
+            NULL, NULL, (STARTUPINFOA *)&si, &info);
+    ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+    if (level)
+    {
+        pDeleteProcThreadAttributeList(si.lpAttributeList);
+        heap_free(si.lpAttributeList);
+        CloseHandle(parent);
+    }
+    else
+    {
+        ret = WriteFile(write_pipe, &parent_data, sizeof(parent_data), &size, NULL);
+    }
+
+    /* wait for child to terminate */
+    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+    CloseHandle(info.hThread);
+    CloseHandle(info.hProcess);
+
+    if (!level)
+    {
+        CloseHandle(read_pipe);
+        CloseHandle(write_pipe);
+        CloseHandle(parent_data.parent);
+    }
+}
+
 START_TEST(process)
 {
     HANDLE job;
@@ -3851,11 +3966,18 @@ START_TEST(process)
             CloseHandle(info.hThread);
             return;
         }
+        else if (!strcmp(myARGV[2], "parent") && myARGC >= 5)
+        {
+            HANDLE h;
+
+            sscanf(myARGV[4], "%p", &h);
+            test_parent_process_attribute(atoi(myARGV[3]), h);
+            return;
+        }
 
         ok(0, "Unexpected command %s\n", myARGV[2]);
         return;
     }
-
     hproc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, GetCurrentProcessId());
     if (hproc)
     {
@@ -3865,7 +3987,6 @@ START_TEST(process)
     else
         win_skip("PROCESS_QUERY_LIMITED_INFORMATION is not supported on this platform\n");
     test_process_info(GetCurrentProcess());
-
     test_TerminateProcess();
     test_Startup();
     test_CommandLine();
@@ -3919,4 +4040,5 @@ START_TEST(process)
     test_jobInheritance(job);
     test_BreakawayOk(job);
     CloseHandle(job);
+    test_parent_process_attribute(0, NULL);
 }




More information about the wine-cvs mailing list