[PATCH V4 3/3] dlls/kernel32/tests: test when passing non inheritable handles in CreateProcess
Eric Pouech
eric.pouech at gmail.com
Thu Apr 21 10:50:41 CDT 2022
V2:
- fix broken results on Win7
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
---
dlls/kernel32/tests/process.c | 93 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 92 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index ebadc2e8d12..7b11e001537 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -336,7 +336,8 @@ static void doChild(const char* file, const char* option)
HANDLE hFile = CreateFileA(file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
HANDLE snapshot;
PROCESSENTRY32 pe;
- BOOL ret;
+ BOOL ret, bin, bout, berr;
+ DWORD flin, flout, flerr;
if (hFile == INVALID_HANDLE_VALUE) return;
@@ -451,6 +452,18 @@ static void doChild(const char* file, const char* option)
childPrintf(hFile, "CurrDirW=%s\n", encodeW(bufW));
childPrintf(hFile, "\n");
+ bin = GetHandleInformation(GetStdHandle(STD_INPUT_HANDLE), &flin);
+ bout = GetHandleInformation(GetStdHandle(STD_OUTPUT_HANDLE), &flout);
+ berr = GetHandleInformation(GetStdHandle(STD_ERROR_HANDLE), &flerr);
+ if (bin || bout || berr)
+ {
+ childPrintf(hFile, "[StdHandleInfo]\n");
+ if (bin ) childPrintf(hFile, "hStdInput=%lu\n", flin);
+ if (bout) childPrintf(hFile, "hStdOutput=%lu\n", flout);
+ if (berr) childPrintf(hFile, "hStdError=%lu\n", flerr);
+ childPrintf(hFile, "\n");
+ }
+
if (option && strcmp(option, "console") == 0)
{
CONSOLE_SCREEN_BUFFER_INFO sbi;
@@ -523,6 +536,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];
@@ -614,10 +636,17 @@ static void ok_child_int( int line, const char *sect, const char *key, UINT expe
ok_(__FILE__, line)( result == expect, "%s:%s expected %u, but got %u\n", sect, key, expect, result );
}
+static void ok_child_intbrk( int line, const char *sect, const char *key, UINT expect, UINT brk )
+{
+ UINT result = GetPrivateProfileIntA( sect, key, !expect, resfile );
+ ok_(__FILE__, line)( result == expect || broken(result == brk), "%s:%s expected %u, but got %u\n", sect, key, expect, result );
+}
+
#define okChildString(sect, key, expect) ok_child_string(__LINE__, (sect), (key), (expect), 1 )
#define okChildIString(sect, key, expect) ok_child_string(__LINE__, (sect), (key), (expect), 0 )
#define okChildStringWA(sect, key, expect) ok_child_stringWA(__LINE__, (sect), (key), (expect), 1 )
#define okChildInt(sect, key, expect) ok_child_int(__LINE__, (sect), (key), (expect))
+#define okChildIntBroken(sect, key, expect, brk) ok_child_intbrk(__LINE__, (sect), (key), (expect), (brk))
static void test_Startup(void)
{
@@ -1691,6 +1720,68 @@ static void test_Console(void)
release_memory();
DeleteFileA(resfile);
+
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+
+ /* 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\"", 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 okChildIntBroken("StartupInfoA", "hStdInput", 0, /* Win7 */ (DWORD_PTR)startup.hStdInput);
+ todo_wine okChildIntBroken("StartupInfoA", "hStdOutput", 0, /* Win7 */ (DWORD_PTR)startup.hStdOutput);
+ todo_wine okChildIntBroken("StartupInfoA", "hStdError", 0, /* Win7 */ (DWORD_PTR)startup.hStdError);
+ todo_wine okChildIntBroken("StartupInfoW", "hStdInput", 0, /* Win7 */ (DWORD_PTR)startup.hStdInput);
+ todo_wine okChildIntBroken("StartupInfoW", "hStdOutput", 0, /* Win7 */ (DWORD_PTR)startup.hStdOutput);
+ todo_wine okChildIntBroken("StartupInfoW", "hStdError", 0, /* Win7 */ (DWORD_PTR)startup.hStdError);
+ /* even inheritable objects are not inherited */
+ todo_wine ok(!isChildPresent("StdHandleInfo", "hStdInput"), "hStdInput shouldn't be present\n");
+ todo_wine ok(!isChildPresent("StdHandleInfo", "hStdOutput"), "hStdOuput 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\"", 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