#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#define bufsize 4096
handle hchildstdinrd, hchildstdinwr, hchildstdoutrd, hchildstdoutwr, hinputfile, hstdout;
bool createchildprocess(void);
void writetopipe(void);
void readfrompipe(void);
void errorexit(lpstr);
int main(int argc, tchar *argv[])
{
security_attributes saattr;
bool fsuccess;
// set the binherithandle flag so pipe handles are inherited.
saattr.nlength = sizeof(security_attributes);
saattr.binherithandle = true;
saattr.lpsecuritydescriptor = null;
// get the handle to the current stdout.
hstdout = getstdhandle(std_output_handle);
// create a pipe for the child process's stdout.
if (!createpipe(&hchildstdoutrd, &hchildstdoutwr, &saattr, 0))
errorexit("stdout pipe creation failed\n");
// ensure the read handle to the pipe for stdout is not inherited.
sethandleinformation(hchildstdoutrd, handle_flag_inherit, 0);
// create a pipe for the child process's stdin.
if (!createpipe(&hchildstdinrd, &hchildstdinwr, &saattr, 0))
errorexit("stdin pipe creation failed\n");
// ensure the write handle to the pipe for stdin is not inherited.
sethandleinformation(hchildstdinwr, handle_flag_inherit, 0);
// now create the child process.
fsuccess = createchildprocess();
if (!fsuccess)
errorexit("create process failed with");
// get a handle to the parent's input file.
if (argc == 1)
errorexit("please specify an input file");
printf("\ncontents of %s:\n\n", argv[1]);
hinputfile = createfile(argv[1], generic_read, 0, null, open_existing, file_attribute_readonly, null);
if (hinputfile == invalid_handle_value)
errorexit("createfile failed");
// write to pipe that is the standard input for a child process.
writetopipe();
// read from pipe that is the standard output for child process.
readfrompipe();
return 0;
}
bool createchildprocess()
{
tchar szcmdline[] = text("cmd");
process_information piprocinfo;
startupinfo sistartinfo;
bool bfuncretn = false;
// set up members of the process_information structure.
zeromemory(&piprocinfo, sizeof(process_information));
// set up members of the startupinfo structure.
zeromemory(&sistartinfo, sizeof(startupinfo) );
sistartinfo.cb = sizeof(startupinfo);
sistartinfo.hstderror = hchildstdoutwr;
sistartinfo.hstdoutput = hchildstdoutwr;
sistartinfo.hstdinput = hchildstdinrd;
sistartinfo.dwflags |= startf_usestdhandles;
// create the child process.
bfuncretn = createprocess(null,
szcmdline, // command line
null, // process security attributes
null, // primary thread security attributes
true, // handles are inherited
0, // creation flags
null, // use parent's environment
null, // use parent's current directory
&sistartinfo, // startupinfo pointer
&piprocinfo); // receives process_information
if (bfuncretn == 0)
errorexit("createprocess failed\n");
else
{
closehandle(piprocinfo.hprocess);
closehandle(piprocinfo.hthread);
return bfuncretn;
}
return (true);
}
void writetopipe(void)
{
dword dwread, dwwritten;
char chbuf[bufsize];
// read from a file and write its contents to a pipe.
for (;;)
{
if (!readfile(hinputfile, chbuf, bufsize, &dwread, null) || dwread == 0)
break;
if (!writefile(hchildstdinwr, chbuf, dwread, &dwwritten, null))
break;
}
// close the pipe handle so the child process stops reading.
if (!closehandle(hchildstdinwr))
errorexit("close pipe failed\n");
}
void readfrompipe(void)
{
dword dwread, dwwritten;
char chbuf[bufsize];
// close the write end of the pipe before reading from the read end of the pipe.
if (!closehandle(hchildstdoutwr))
errorexit("closing handle failed");
// read output from the child process, and write to parent's stdout.
for (;;)
{
if (!readfile(hchildstdoutrd, chbuf, bufsize, &dwread, null) || dwread == 0)
break;
if (!writefile(hstdout, chbuf, dwread, &dwwritten, null))
break;
}
}
void errorexit (lpstr lpszmessage)
{
fprintf(stderr, "%s\n", lpszmessage);
exitprocess(0);
}
|