#include <stdio.h>
#include <windows.h>
#define BUFSIZE 4096
HANDLE
hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hInputFile, hStdout;
BOOL
CreateChildProcess(
VOID
);
VOID
WriteToPipe(
VOID
);
VOID
ReadFromPipe(
VOID
);
VOID
ErrorExit(
LPTSTR
);
VOID
ErrMsg(
LPTSTR
,
BOOL
);
DWORD
main(
int
argc,
char
*argv[])
{
SECURITY_ATTRIBUTES saAttr;
BOOL
fSuccess;
saAttr.nLength =
sizeof
(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if
(! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
ErrorExit(
"Stdout pipe creation failed\n"
);
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup , 0,
FALSE,
DUPLICATE_SAME_ACCESS);
if
( !fSuccess )
ErrorExit(
"DuplicateHandle failed"
);
CloseHandle(hChildStdoutRd);
if
(! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
ErrorExit(
"Stdin pipe creation failed\n"
);
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup, 0,
FALSE,
DUPLICATE_SAME_ACCESS);
if
(! fSuccess)
ErrorExit(
"DuplicateHandle failed"
);
CloseHandle(hChildStdinWr);
fSuccess = CreateChildProcess();
if
(! fSuccess)
ErrorExit(
"Create process failed"
);
if
(argc == 1)
ErrorExit(
"Please specify an input file"
);
hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
if
(hInputFile == INVALID_HANDLE_VALUE)
ErrorExit(
"CreateFile failed\n"
);
WriteToPipe();
ReadFromPipe();
return
0;
}
BOOL
CreateChildProcess()
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL
bFuncRetn = FALSE;
ZeroMemory( &piProcInfo,
sizeof
(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo,
sizeof
(STARTUPINFO) );
siStartInfo.cb =
sizeof
(STARTUPINFO);
siStartInfo.hStdError = hChildStdoutWr;
siStartInfo.hStdOutput = hChildStdoutWr;
siStartInfo.hStdInput = hChildStdinRd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
bFuncRetn = CreateProcess(NULL,
"child"
,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&siStartInfo,
&piProcInfo);
if
(bFuncRetn == 0)
ErrorExit(
"CreateProcess failed"
);
else
{
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
return
bFuncRetn;
}
}
VOID
WriteToPipe(
VOID
)
{
DWORD
dwRead, dwWritten;
CHAR
chBuf[BUFSIZE];
for
(;;)
{
if
(! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
dwRead == 0)
break
;
if
(! WriteFile(hChildStdinWrDup, chBuf, dwRead,
&dwWritten, NULL))
break
;
}
if
(! CloseHandle(hChildStdinWrDup))
ErrorExit(
"Close pipe failed"
);
}
VOID
ReadFromPipe(
VOID
)
{
DWORD
dwRead, dwWritten;
CHAR
chBuf[BUFSIZE];
if
(!CloseHandle(hChildStdoutWr))
ErrorExit(
"CloseHandle failed"
);
for
(;;)
{
if
( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
NULL) || dwRead == 0)
break
;
if
(! WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL))
break
;
}
}
VOID
ErrorExit (
LPTSTR
lpszMessage)
{
fprintf
(stderr,
"%s\n"
, lpszMessage);
ExitProcess(0);
}