| | #include <windows.h> |
| |
|
| | #include "TestUtil.cc" |
| |
|
| | const char *g_prefix = ""; |
| |
|
| | static void dumpHandles() { |
| | trace("%sSTDIN=0x%I64x STDOUT=0x%I64x STDERR=0x%I64x", |
| | g_prefix, |
| | (long long)GetStdHandle(STD_INPUT_HANDLE), |
| | (long long)GetStdHandle(STD_OUTPUT_HANDLE), |
| | (long long)GetStdHandle(STD_ERROR_HANDLE)); |
| | } |
| |
|
| | static HANDLE createBuffer() { |
| |
|
| | |
| | SECURITY_ATTRIBUTES sa = {0}; |
| | sa.nLength = sizeof(sa); |
| | sa.bInheritHandle = TRUE; |
| |
|
| | trace("%sCreating a new buffer...", g_prefix); |
| | HANDLE conout = CreateConsoleScreenBuffer( |
| | GENERIC_READ | GENERIC_WRITE, |
| | FILE_SHARE_READ | FILE_SHARE_WRITE, |
| | &sa, |
| | CONSOLE_TEXTMODE_BUFFER, NULL); |
| |
|
| | trace("%sCreating a new buffer... 0x%I64x", g_prefix, (long long)conout); |
| | return conout; |
| | } |
| |
|
| | static const char *successOrFail(BOOL ret) { |
| | return ret ? "ok" : "FAILED"; |
| | } |
| |
|
| | static void setConsoleActiveScreenBuffer(HANDLE conout) { |
| | trace("%sSetConsoleActiveScreenBuffer(0x%I64x) called...", |
| | g_prefix, (long long)conout); |
| | trace("%sSetConsoleActiveScreenBuffer(0x%I64x) called... %s", |
| | g_prefix, (long long)conout, |
| | successOrFail(SetConsoleActiveScreenBuffer(conout))); |
| | } |
| |
|
| | static void writeTest(HANDLE conout, const char *msg) { |
| | char writeData[256]; |
| | sprintf(writeData, "%s%s\n", g_prefix, msg); |
| |
|
| | trace("%sWriting to 0x%I64x: '%s'...", |
| | g_prefix, (long long)conout, msg); |
| | DWORD actual = 0; |
| | BOOL ret = WriteConsoleA(conout, writeData, strlen(writeData), &actual, NULL); |
| | trace("%sWriting to 0x%I64x: '%s'... %s", |
| | g_prefix, (long long)conout, msg, |
| | successOrFail(ret && actual == strlen(writeData))); |
| | } |
| |
|
| | static HANDLE startChildInSameConsole(const wchar_t *args, BOOL |
| | bInheritHandles=FALSE) { |
| | wchar_t program[1024]; |
| | wchar_t cmdline[1024]; |
| | GetModuleFileNameW(NULL, program, 1024); |
| | swprintf(cmdline, L"\"%ls\" %ls", program, args); |
| |
|
| | STARTUPINFOW sui; |
| | PROCESS_INFORMATION pi; |
| | memset(&sui, 0, sizeof(sui)); |
| | memset(&pi, 0, sizeof(pi)); |
| | sui.cb = sizeof(sui); |
| |
|
| | CreateProcessW(program, cmdline, |
| | NULL, NULL, |
| | bInheritHandles, |
| | 0, |
| | NULL, NULL, |
| | &sui, &pi); |
| |
|
| | return pi.hProcess; |
| | } |
| |
|
| | static HANDLE dup(HANDLE h, HANDLE targetProcess) { |
| | HANDLE h2 = INVALID_HANDLE_VALUE; |
| | BOOL ret = DuplicateHandle( |
| | GetCurrentProcess(), h, |
| | targetProcess, &h2, |
| | 0, TRUE, DUPLICATE_SAME_ACCESS); |
| | trace("dup(0x%I64x) to process 0x%I64x... %s, 0x%I64x", |
| | (long long)h, |
| | (long long)targetProcess, |
| | successOrFail(ret), |
| | (long long)h2); |
| | return h2; |
| | } |
| |
|
| | int main(int argc, char *argv[]) { |
| | if (argc == 1) { |
| | startChildProcess(L"parent"); |
| | return 0; |
| | } |
| |
|
| | if (!strcmp(argv[1], "parent")) { |
| | g_prefix = "parent: "; |
| | dumpHandles(); |
| | HANDLE hChild = startChildInSameConsole(L"child"); |
| |
|
| | |
| | HANDLE orig1 = GetStdHandle(STD_OUTPUT_HANDLE); |
| | HANDLE new1 = createBuffer(); |
| |
|
| | Sleep(2000); |
| | setConsoleActiveScreenBuffer(new1); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | HANDLE orig2 = dup(orig1, GetCurrentProcess()); |
| | HANDLE new2 = dup(new1, GetCurrentProcess()); |
| |
|
| | dup(orig1, hChild); |
| | dup(new1, hChild); |
| |
|
| | |
| | |
| | writeTest(orig1, "write to orig1"); |
| | writeTest(orig2, "write to orig2"); |
| | writeTest(new1, "write to new1"); |
| | writeTest(new2, "write to new2"); |
| |
|
| | Sleep(120000); |
| | return 0; |
| | } |
| |
|
| | if (!strcmp(argv[1], "child")) { |
| | g_prefix = "child: "; |
| | dumpHandles(); |
| | Sleep(4000); |
| | for (unsigned int i = 0x1; i <= 0xB0; ++i) { |
| | char msg[256]; |
| | sprintf(msg, "Write to handle 0x%x", i); |
| | HANDLE h = reinterpret_cast<HANDLE>(i); |
| | writeTest(h, msg); |
| | } |
| | Sleep(120000); |
| | return 0; |
| | } |
| |
|
| | return 0; |
| | } |
| |
|