📄 process.c
字号:
HeapFree(GetProcessHeap(), 0, child_env);
release_memory();
assert(DeleteFileA(resfile) != 0);
}
static void test_SuspendFlag(void)
{
char buffer[MAX_PATH];
PROCESS_INFORMATION info;
STARTUPINFOA startup, us;
DWORD exit_status;
/* let's start simplistic */
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
startup.dwFlags = STARTF_USESHOWWINDOW;
startup.wShowWindow = SW_SHOWNORMAL;
get_file_name(resfile);
sprintf(buffer, "%s tests/process.c %s", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startup, &info), "CreateProcess\n");
ok(GetExitCodeThread(info.hThread, &exit_status) && exit_status == STILL_ACTIVE, "thread still running\n");
Sleep(8000);
ok(GetExitCodeThread(info.hThread, &exit_status) && exit_status == STILL_ACTIVE, "thread still running\n");
ok(ResumeThread(info.hThread) == 1, "Resuming thread\n");
/* wait for child to terminate */
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
GetStartupInfoA(&us);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
okChildInt("StartupInfoA", "dwX", startup.dwX);
okChildInt("StartupInfoA", "dwY", startup.dwY);
okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
okChildInt("StartupInfoA", "dwYSize", startup.dwYSize);
okChildInt("StartupInfoA", "dwXCountChars", startup.dwXCountChars);
okChildInt("StartupInfoA", "dwYCountChars", startup.dwYCountChars);
okChildInt("StartupInfoA", "dwFillAttribute", startup.dwFillAttribute);
okChildInt("StartupInfoA", "dwFlags", startup.dwFlags);
okChildInt("StartupInfoA", "wShowWindow", startup.wShowWindow);
release_memory();
assert(DeleteFileA(resfile) != 0);
}
static void test_DebuggingFlag(void)
{
char buffer[MAX_PATH];
PROCESS_INFORMATION info;
STARTUPINFOA startup, us;
DEBUG_EVENT de;
unsigned dbg = 0;
/* let's start simplistic */
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
startup.dwFlags = STARTF_USESHOWWINDOW;
startup.wShowWindow = SW_SHOWNORMAL;
get_file_name(resfile);
sprintf(buffer, "%s tests/process.c %s", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info), "CreateProcess\n");
/* get all startup events up to the entry point break exception */
do
{
ok(WaitForDebugEvent(&de, INFINITE), "reading debug event\n");
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
if (de.dwDebugEventCode != EXCEPTION_DEBUG_EVENT) dbg++;
} while (de.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT);
ok(dbg, "I have seen a debug event\n");
/* wait for child to terminate */
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
GetStartupInfoA(&us);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
okChildInt("StartupInfoA", "dwX", startup.dwX);
okChildInt("StartupInfoA", "dwY", startup.dwY);
okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
okChildInt("StartupInfoA", "dwYSize", startup.dwYSize);
okChildInt("StartupInfoA", "dwXCountChars", startup.dwXCountChars);
okChildInt("StartupInfoA", "dwYCountChars", startup.dwYCountChars);
okChildInt("StartupInfoA", "dwFillAttribute", startup.dwFillAttribute);
okChildInt("StartupInfoA", "dwFlags", startup.dwFlags);
okChildInt("StartupInfoA", "wShowWindow", startup.wShowWindow);
release_memory();
assert(DeleteFileA(resfile) != 0);
}
static BOOL is_console(HANDLE h)
{
return h != INVALID_HANDLE_VALUE && ((ULONG_PTR)h & 3) == 3;
}
static void test_Console(void)
{
char buffer[MAX_PATH];
PROCESS_INFORMATION info;
STARTUPINFOA startup, us;
SECURITY_ATTRIBUTES sa;
CONSOLE_SCREEN_BUFFER_INFO sbi, sbiC;
DWORD modeIn, modeOut, modeInC, modeOutC;
DWORD cpIn, cpOut, cpInC, cpOutC;
DWORD w;
HANDLE hChildIn, hChildInInh, hChildOut, hChildOutInh, hParentIn, hParentOut;
const char* msg = "This is a std-handle inheritance test.";
unsigned msg_len;
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
startup.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
startup.wShowWindow = SW_SHOWNORMAL;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
startup.hStdInput = CreateFileA("CONIN$", GENERIC_READ|GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, 0);
startup.hStdOutput = CreateFileA("CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, 0);
/* first, we need to be sure we're attached to a console */
if (!is_console(startup.hStdInput) || !is_console(startup.hStdOutput))
{
/* we're not attached to a console, let's do it */
AllocConsole();
startup.hStdInput = CreateFileA("CONIN$", GENERIC_READ|GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, 0);
startup.hStdOutput = CreateFileA("CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, 0);
}
/* now verify everything's ok */
ok(startup.hStdInput != INVALID_HANDLE_VALUE, "Opening ConIn\n");
ok(startup.hStdOutput != INVALID_HANDLE_VALUE, "Opening ConOut\n");
startup.hStdError = startup.hStdOutput;
ok(GetConsoleScreenBufferInfo(startup.hStdOutput, &sbi), "Getting sb info\n");
ok(GetConsoleMode(startup.hStdInput, &modeIn) &&
GetConsoleMode(startup.hStdOutput, &modeOut), "Getting console modes\n");
cpIn = GetConsoleCP();
cpOut = GetConsoleOutputCP();
get_file_name(resfile);
sprintf(buffer, "%s tests/process.c %s console", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
/* wait for child to terminate */
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
/* now get the modification the child has made, and resets parents expected values */
ok(GetConsoleScreenBufferInfo(startup.hStdOutput, &sbiC), "Getting sb info\n");
ok(GetConsoleMode(startup.hStdInput, &modeInC) &&
GetConsoleMode(startup.hStdOutput, &modeOutC), "Getting console modes\n");
SetConsoleMode(startup.hStdInput, modeIn);
SetConsoleMode(startup.hStdOutput, modeOut);
cpInC = GetConsoleCP();
cpOutC = GetConsoleOutputCP();
SetConsoleCP(cpIn);
SetConsoleOutputCP(cpOut);
GetStartupInfoA(&us);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
okChildInt("StartupInfoA", "dwX", startup.dwX);
okChildInt("StartupInfoA", "dwY", startup.dwY);
okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
okChildInt("StartupInfoA", "dwYSize", startup.dwYSize);
okChildInt("StartupInfoA", "dwXCountChars", startup.dwXCountChars);
okChildInt("StartupInfoA", "dwYCountChars", startup.dwYCountChars);
okChildInt("StartupInfoA", "dwFillAttribute", startup.dwFillAttribute);
okChildInt("StartupInfoA", "dwFlags", startup.dwFlags);
okChildInt("StartupInfoA", "wShowWindow", startup.wShowWindow);
/* check child correctly inherited the console */
okChildInt("StartupInfoA", "hStdInput", (DWORD)startup.hStdInput);
okChildInt("StartupInfoA", "hStdOutput", (DWORD)startup.hStdOutput);
okChildInt("StartupInfoA", "hStdError", (DWORD)startup.hStdError);
okChildInt("Console", "SizeX", (DWORD)sbi.dwSize.X);
okChildInt("Console", "SizeY", (DWORD)sbi.dwSize.Y);
okChildInt("Console", "CursorX", (DWORD)sbi.dwCursorPosition.X);
okChildInt("Console", "CursorY", (DWORD)sbi.dwCursorPosition.Y);
okChildInt("Console", "Attributes", sbi.wAttributes);
okChildInt("Console", "winLeft", (DWORD)sbi.srWindow.Left);
okChildInt("Console", "winTop", (DWORD)sbi.srWindow.Top);
okChildInt("Console", "winRight", (DWORD)sbi.srWindow.Right);
okChildInt("Console", "winBottom", (DWORD)sbi.srWindow.Bottom);
okChildInt("Console", "maxWinWidth", (DWORD)sbi.dwMaximumWindowSize.X);
okChildInt("Console", "maxWinHeight", (DWORD)sbi.dwMaximumWindowSize.Y);
okChildInt("Console", "InputCP", cpIn);
okChildInt("Console", "OutputCP", cpOut);
okChildInt("Console", "InputMode", modeIn);
okChildInt("Console", "OutputMode", modeOut);
todo_wine ok(cpInC == 1252, "Wrong console CP (expected 1252 got %ld/%ld)\n", cpInC, cpIn);
todo_wine ok(cpOutC == 1252, "Wrong console-SB CP (expected 1252 got %ld/%ld)\n", cpOutC, cpOut);
ok(modeInC == (modeIn ^ 1), "Wrong console mode\n");
ok(modeOutC == (modeOut ^ 1), "Wrong console-SB mode\n");
ok(sbiC.dwCursorPosition.X == (sbi.dwCursorPosition.X ^ 1), "Wrong cursor position\n");
ok(sbiC.dwCursorPosition.Y == (sbi.dwCursorPosition.Y ^ 1), "Wrong cursor position\n");
release_memory();
assert(DeleteFileA(resfile) != 0);
ok(CreatePipe(&hParentIn, &hChildOut, NULL, 0), "Creating parent-input pipe\n");
ok(DuplicateHandle(GetCurrentProcess(), hChildOut, GetCurrentProcess(),
&hChildOutInh, 0, TRUE, DUPLICATE_SAME_ACCESS),
"Duplicating as inheritable child-output pipe\n");
CloseHandle(hChildOut);
ok(CreatePipe(&hChildIn, &hParentOut, NULL, 0), "Creating parent-output pipe\n");
ok(DuplicateHandle(GetCurrentProcess(), hChildIn, GetCurrentProcess(),
&hChildInInh, 0, TRUE, DUPLICATE_SAME_ACCESS),
"Duplicating as inheritable child-input pipe\n");
CloseHandle(hChildIn);
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
startup.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
startup.wShowWindow = SW_SHOWNORMAL;
startup.hStdInput = hChildInInh;
startup.hStdOutput = hChildOutInh;
startup.hStdError = hChildOutInh;
get_file_name(resfile);
sprintf(buffer, "%s tests/process.c %s stdhandle", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup, &info), "CreateProcess\n");
ok(CloseHandle(hChildInInh), "Closing handle\n");
ok(CloseHandle(hChildOutInh), "Closing handle\n");
msg_len = strlen(msg) + 1;
ok(WriteFile(hParentOut, msg, msg_len, &w, NULL), "Writing to child\n");
ok(w == msg_len, "Should have written %u bytes, actually wrote %lu\n", msg_len, w);
memset(buffer, 0, sizeof(buffer));
ok(ReadFile(hParentIn, buffer, sizeof(buffer), &w, NULL), "Reading from child\n");
ok(strcmp(buffer, msg) == 0, "Should have received '%s'\n", msg);
/* wait for child to terminate */
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
okChildString("StdHandle", "msg", msg);
release_memory();
assert(DeleteFileA(resfile) != 0);
}
static void test_ExitCode(void)
{
char buffer[MAX_PATH];
PROCESS_INFORMATION info;
STARTUPINFOA startup;
DWORD code;
/* let's start simplistic */
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
startup.dwFlags = STARTF_USESHOWWINDOW;
startup.wShowWindow = SW_SHOWNORMAL;
get_file_name(resfile);
sprintf(buffer, "%s tests/process.c %s exit_code", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
/* wait for child to terminate */
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
ok(GetExitCodeProcess(info.hProcess, &code), "Getting exit code\n");
okChildInt("ExitCode", "value", code);
release_memory();
assert(DeleteFileA(resfile) != 0);
}
START_TEST(process)
{
int b = init();
ok(b, "Basic init of CreateProcess test\n");
if (!b) return;
if (myARGC >= 3)
{
doChild(myARGV[2], (myARGC == 3) ? NULL : myARGV[3]);
return;
}
test_Startup();
test_CommandLine();
test_Directory();
test_Environment();
test_SuspendFlag();
test_DebuggingFlag();
test_Console();
test_ExitCode();
/* things that can be tested:
* lookup: check the way program to be executed is searched
* handles: check the handle inheritance stuff (+sec options)
* console: check if console creation parameters work
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -