Redirecting Input/Output of New Process
I've done some searching around for the past few days and I'm trying to be
able to spawn a process, send some information to its standard input, and
read from its standard output.
I think I'm really close, and I understand that I need to create pipes and
then pass them to the startup info structure given to CreateProcess(), but
something isn't quite right.
I can't tell if sending information to stdin (from my program to the client
process) is working, but it doesn't block, which is partially a good sign.
What I CAN tell is that recieving information from stdout (from the client
program to my program) isn't doing anything. When I do ReadFile(), even for
one byte, on the stdout stream, it blocks indefinitely. The program SHOULD
have at least output its header, so something doesn't seem quite right here.
This is my code for redirecting the outputs:
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(saAttr);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
HANDLE outStream, inStream, childOutStream, childInStream;
HANDLE self = GetCurrentProcess();
PROCESS_INFORMATION *pi = new PROCESS_INFORMATION;
// Create our input/output pipes
try
{
// create stdout
HANDLE tmp;
if (!CreatePipe(&tmp, &childOutStream, &saAttr, 0))
throw (unsigned int)1;
if (!DuplicateHandle(self, tmp, self, &outStream, 0, FALSE,
DUPLICATE_SAME_ACCESS))
throw (unsigned int)1;
// Close the original version
CloseHandle(tmp);
// create stdin
if (!CreatePipe(&childInStream, &tmp, &saAttr, 0))
throw (unsigned int) 1;
if (!DuplicateHandle(self, tmp, self, &inStream, 0, FALSE,
DUPLICATE_SAME_ACCESS))
throw (unsigned int) 1;
// Close the original
CloseHandle(tmp);
}
catch(...)
{
CloseHandle(inStream);
CloseHandle(outStream);
CloseHandle(childOutStream);
CloseHandle(childInStream);
throw;
}
// Build the startup info
STARTUPINFOA siInfo;
ZeroMemory(&siInfo, sizeof(siInfo)); // cheap trick since most
of it is zero...
siInfo.cb = sizeof(siInfo);
siInfo.dwFlags = STARTF_USESTDHANDLES | // use our new stdin/stdout
STARTF_USESHOWWINDOW; // Do not create a new
console window (hide it)
siInfo.hStdInput = inStream;
siInfo.hStdOutput = outStream;
siInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
char* str = new char[strlen(exe)+2+5+1];
sprintf(str, "\"%s\" -int", exe);
// Execute!
if (!CreateProcessA(NULL, str, NULL, NULL, TRUE, 0, NULL, NULL, &siInfo,
pi))
{
delete[] str;
CloseHandle(inStream);
CloseHandle(outStream);
CloseHandle(childOutStream);
CloseHandle(childInStream);
throw (unsigned int)-1;
}
Everything seems to go as planned, but when I execute...
char buf[1];
if (!ReadFile(outStream, buf, 1, &nBytes, NULL))
throw GetLastError();
It just sits there forever.
I'm sure this is just something extremely trivial I'm missing. Any ideas?
Thanks,
-- Matt