Signed-off-by: Eric Pouech eric.pouech@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)