[PATCH] dlls/kernel32/tests: test when passing non inheritable handles in CreateProcess

Eric Pouech eric.pouech at gmail.com
Wed Apr 20 04:30:40 CDT 2022


Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 dlls/kernel32/tests/process.c |   82 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index ebadc2e8d12..6d05b18c44f 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -512,7 +512,22 @@ static void     doChild(const char* file, const char* option)
             ok(WriteFile(hStdOut, buf, r, &w, NULL) && w == r, "Writing message to output pipe\n");
         }
     }
+    if (option && strcmp(option, "stdinfo") == 0)
+    {
+        DWORD flin, flout, flerr;
 
+        BOOL bin  = GetHandleInformation(GetStdHandle(STD_INPUT_HANDLE), &flin);
+        BOOL bout = GetHandleInformation(GetStdHandle(STD_OUTPUT_HANDLE), &flout);
+        BOOL berr = GetHandleInformation(GetStdHandle(STD_ERROR_HANDLE), &flerr);
+        if (bin || bout || berr)
+        {
+            childPrintf(hFile, "[StdHandleInfo]\n");
+            if (bin ) childPrintf(hFile, "hStdInput=%lu",  flin);
+            if (bout) childPrintf(hFile, "hStdOutput=%lu", flout);
+            if (berr) childPrintf(hFile, "hStdError=%lu",  flerr);
+            childPrintf(hFile, "\n");
+        }
+    }
     if (option && strcmp(option, "exit_code") == 0)
     {
         childPrintf(hFile, "[ExitCode]\nvalue=%d\n\n", 123);
@@ -523,6 +538,15 @@ static void     doChild(const char* file, const char* option)
     CloseHandle(hFile);
 }
 
+static BOOL isChildPresent( const char* sect, const char* key )
+{
+    char        buf[1024+4*MAX_LISTED_ENV_VAR];
+
+    GetPrivateProfileStringA(sect, key, "-", buf, sizeof(buf), resfile);
+    if (buf[0] == '\0' || (buf[0] == '-' && buf[1] == '\0')) return FALSE;
+    return TRUE;
+}
+
 static char* getChildString(const char* sect, const char* key)
 {
     char        buf[1024+4*MAX_LISTED_ENV_VAR];
@@ -1691,6 +1715,64 @@ static void test_Console(void)
 
     release_memory();
     DeleteFileA(resfile);
+
+    /* test passing in startupinfo inheritable and non inheritable handles (CreateProcess not inheriting handles) */
+    memset(&startup, 0, sizeof(startup));
+    startup.cb = sizeof(startup);
+    startup.dwFlags = STARTF_USESTDHANDLES;
+    startup.hStdInput = CreateFileA("NUL", GENERIC_READ|GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, 0);
+    startup.hStdOutput = CreateFileA("NUL", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
+    startup.hStdError = (HANDLE)(DWORD_PTR)0x00585840;
+    ok(startup.hStdInput != INVALID_HANDLE_VALUE, "failed to open NUL\n");
+    ok(startup.hStdOutput != INVALID_HANDLE_VALUE, "failed to open NUL\n");
+    sprintf(buffer, "\"%s\" process dump \"%s\" stdinfo", selfname, resfile);
+    ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
+    wait_and_close_child_process(&info);
+    CloseHandle(startup.hStdInput);
+
+    reload_child_info(resfile);
+    /* handles values have been zero:ed */
+    todo_wine okChildInt("StartupInfoA", "hStdInput", 0);
+    todo_wine okChildInt("StartupInfoA", "hStdOutput", 0);
+    todo_wine okChildInt("StartupInfoA", "hStdError", 0);
+    todo_wine okChildInt("StartupInfoW", "hStdInput", 0);
+    todo_wine okChildInt("StartupInfoW", "hStdOutput", 0);
+    todo_wine okChildInt("StartupInfoW", "hStdError", 0);
+    /* even inheritable objects are not inherited */
+    todo_wine ok(!isChildPresent("StdHandleInfo", "hStdInput"), "shouldn't inherit handle\n");
+    ok(!isChildPresent("StdHandleInfo", "hStdOutput"), "hStdOutput shouldn't be present\n");
+    ok(!isChildPresent("StdHandleInfo", "hStdError"), "hStdError shouldn't be present\n");
+    release_memory();
+    DeleteFileA(resfile);
+
+    /* test passing in startupinfo inheritable and non inheritable handles (CreateProcess inhering handles)) */
+    memset(&startup, 0, sizeof(startup));
+    startup.cb = sizeof(startup);
+    startup.dwFlags = STARTF_USESTDHANDLES;
+    startup.hStdInput = CreateFileA("NUL", GENERIC_READ|GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, 0);
+    startup.hStdOutput = CreateFileA("NUL", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
+    startup.hStdError = (HANDLE)(DWORD_PTR)0x00585840;
+    ok(startup.hStdInput != INVALID_HANDLE_VALUE, "failed to open NUL\n");
+    ok(startup.hStdOutput != INVALID_HANDLE_VALUE, "failed to open NUL\n");
+    sprintf(buffer, "\"%s\" process dump \"%s\" stdinfo", selfname, resfile);
+    ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
+    wait_and_close_child_process(&info);
+    CloseHandle(startup.hStdInput);
+
+    reload_child_info(resfile);
+    /* handles values are available */
+    okChildInt("StartupInfoA", "hStdInput", (DWORD_PTR)startup.hStdInput);
+    okChildInt("StartupInfoA", "hStdOutput", (DWORD_PTR)startup.hStdOutput);
+    okChildInt("StartupInfoA", "hStdError", (DWORD_PTR)startup.hStdError);
+    okChildInt("StartupInfoW", "hStdInput", (DWORD_PTR)startup.hStdInput);
+    okChildInt("StartupInfoW", "hStdOutput", (DWORD_PTR)startup.hStdOutput);
+    okChildInt("StartupInfoW", "hStdError", (DWORD_PTR)startup.hStdError);
+    /* only inheritable objects are inherited */
+    okChildInt("StdHandleInfo", "hStdInput", HANDLE_FLAG_INHERIT);
+    ok(!isChildPresent("StdHandleInfo", "hStdOutput"), "hStdOutput shouldn't be present\n");
+    ok(!isChildPresent("StdHandleInfo", "hStdError"), "hStdError shouldn't be present\n");
+    release_memory();
+    DeleteFileA(resfile);
 }
 
 static  void    test_ExitCode(void)




More information about the wine-devel mailing list