You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
6.1 KiB
219 lines
6.1 KiB
//
|
|
// ConsoleCom.cpp : Defines the entry point for the console application.
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "ConsoleCom.h"
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
//
|
|
// The one and only application object
|
|
//
|
|
|
|
CWinApp theApp;
|
|
|
|
HANDLE coutPipe, cinPipe, cerrPipe;
|
|
#define CONNECTIMEOUT 1000
|
|
|
|
//
|
|
// Create named pipes for stdin, stdout and stderr
|
|
// Parameter: process id
|
|
//
|
|
BOOL CreateNamedPipes(DWORD pid)
|
|
{
|
|
TCHAR name[256];
|
|
|
|
_stprintf(name, _T("\\\\.\\pipe\\%dcout"), pid);
|
|
if (INVALID_HANDLE_VALUE == (coutPipe = CreateNamedPipe(name,
|
|
PIPE_ACCESS_INBOUND,
|
|
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
|
|
1,
|
|
1024,
|
|
1024,
|
|
CONNECTIMEOUT,
|
|
NULL)))
|
|
return 0;
|
|
_stprintf(name, _T("\\\\.\\pipe\\%dcin"), pid);
|
|
if (INVALID_HANDLE_VALUE == (cinPipe = CreateNamedPipe(name,
|
|
PIPE_ACCESS_OUTBOUND,
|
|
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
|
|
1,
|
|
1024,
|
|
1024,
|
|
CONNECTIMEOUT,
|
|
NULL)))
|
|
return 0;
|
|
_stprintf(name, _T("\\\\.\\pipe\\%dcerr"), pid);
|
|
if (INVALID_HANDLE_VALUE == (cerrPipe = CreateNamedPipe(name,
|
|
PIPE_ACCESS_INBOUND,
|
|
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
|
|
1,
|
|
1024,
|
|
1024,
|
|
CONNECTIMEOUT,
|
|
NULL)))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Close all named pipes
|
|
//
|
|
void CloseNamedPipes()
|
|
{
|
|
CloseHandle(coutPipe);
|
|
CloseHandle(cerrPipe);
|
|
CloseHandle(cinPipe);
|
|
}
|
|
|
|
//
|
|
// Thread function that handles incoming bytesreams to be outputed
|
|
// on stdout
|
|
//
|
|
void __cdecl OutPipeTh(void*)
|
|
{
|
|
TCHAR buffer[1024];
|
|
DWORD count = 0;
|
|
|
|
ConnectNamedPipe(coutPipe, NULL);
|
|
|
|
while(ReadFile(coutPipe, buffer, 1024, &count, NULL))
|
|
{
|
|
buffer[count] = 0;
|
|
cout << buffer << flush;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Thread function that handles incoming bytesreams to be outputed
|
|
// on stderr
|
|
//
|
|
void __cdecl ErrPipeTh(void*)
|
|
{
|
|
TCHAR buffer[1024];
|
|
DWORD count = 0;
|
|
|
|
ConnectNamedPipe(cerrPipe, NULL);
|
|
|
|
while(ReadFile(cerrPipe, buffer, 1024, &count, NULL))
|
|
{
|
|
buffer[count] = 0;
|
|
cerr << buffer << flush;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Thread function that handles incoming bytesreams from stdin
|
|
//
|
|
void __cdecl InPipeTh(void*)
|
|
{
|
|
TCHAR buffer[1024];
|
|
DWORD countr = 0;
|
|
DWORD countw = 0;
|
|
|
|
ConnectNamedPipe(cinPipe, NULL);
|
|
|
|
for(;;)
|
|
{
|
|
if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE),
|
|
buffer,
|
|
1024,
|
|
&countr,
|
|
NULL))
|
|
break;
|
|
|
|
|
|
if (!WriteFile(cinPipe,
|
|
buffer,
|
|
countr,
|
|
&countw,
|
|
NULL))
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Start handler pipe handler threads
|
|
//
|
|
void RunPipeThreads()
|
|
{
|
|
_beginthread(InPipeTh, 0, NULL);
|
|
_beginthread(OutPipeTh, 0, NULL);
|
|
_beginthread(ErrPipeTh, 0, NULL);
|
|
}
|
|
|
|
int __cdecl _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
|
|
{
|
|
ULONG nRetCode = 0;
|
|
|
|
//
|
|
// initialize MFC and print and error on failure
|
|
//
|
|
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
|
|
{
|
|
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
|
|
nRetCode = 1;
|
|
} else {
|
|
//
|
|
// create command line string based on program name
|
|
//
|
|
TCHAR drive[_MAX_DRIVE];
|
|
TCHAR dir[_MAX_DIR];
|
|
TCHAR fname[_MAX_FNAME];
|
|
TCHAR ext[_MAX_EXT];
|
|
|
|
_tsplitpath(argv[0], drive, dir, fname, ext);
|
|
TCHAR cParams[1024];
|
|
_tcscpy(cParams, GetCommandLine() + _tcslen(argv[0]) + 1);
|
|
TCHAR cLine[2028];
|
|
_stprintf(cLine, _T("%s%s%s.exe %s"), drive, dir, fname, cParams);
|
|
|
|
|
|
//
|
|
// create process in suspended mode
|
|
//
|
|
PROCESS_INFORMATION pInfo;
|
|
STARTUPINFO sInfo;
|
|
memset(&sInfo, 0, sizeof(STARTUPINFO));
|
|
sInfo.cb = sizeof(STARTUPINFO);
|
|
//cout << "Calling " << cLine << endl;
|
|
if (!CreateProcess(NULL,
|
|
cLine,
|
|
NULL,
|
|
NULL,
|
|
FALSE,
|
|
CREATE_SUSPENDED,
|
|
NULL,
|
|
NULL,
|
|
&sInfo,
|
|
&pInfo))
|
|
{
|
|
cerr << _T("ERROR: Could not create process.") << endl;
|
|
return 1;
|
|
}
|
|
|
|
if (!CreateNamedPipes(pInfo.dwProcessId))
|
|
{
|
|
cerr << _T("ERROR: Could not create named pipes.") << endl;
|
|
return 1;
|
|
}
|
|
|
|
RunPipeThreads();
|
|
|
|
//
|
|
// resume process
|
|
//
|
|
ResumeThread(pInfo.hThread);
|
|
|
|
WaitForSingleObject(pInfo.hProcess, INFINITE);
|
|
|
|
CloseNamedPipes();
|
|
|
|
GetExitCodeProcess(pInfo.hProcess, (ULONG*)&nRetCode);
|
|
}
|
|
|
|
return (int)nRetCode;
|
|
}
|