#include <stdio.h> 
#include <windows.h> 
 
#define BUFSIZE 4096 
 
BOOL CreateChildProcess(HANDLE in, HANDLE out);
VOID WriteToPipe(VOID); 
VOID ReadFromPipe(VOID); 
VOID ErrorExit(LPTSTR); 
VOID ErrMsg(LPTSTR, BOOL); 
 
HANDLE hInputFile, hSaveStdin, hSaveStdout,
   hRead1,hRead3,hRead4,
   hWrite1,hWrite2,hWrite3;

DWORD main(int argc, char *argv[]) 
{ 

   DWORD dwRead, dwWritten, resR, resW; 
   CHAR chBuf[BUFSIZE]; 
   CHAR chBuf2[BUFSIZE]; 
   BOOL fSuccess; 
 
   PROCESS_INFORMATION piProcInfo; 
   STARTUPINFO siStartInfo; 

// Set the bInheritHandle flag so pipe handles are inherited. 
 
   // The steps for redirecting child process's STDOUT: 
   //     1. Save current STDOUT, to be restored later. 
   //     2. Create anonymous pipe to be STDOUT for child process. 
   //     3. Set STDOUT of the parent process to be write handle to 
   //        the pipe, so it is inherited by the child process. 
   //     4. Create a noninheritable duplicate of the read handle and
   //        close the inheritable read handle. 
 
// Save the handle to the current STDOUT. 
 
   hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
 
// Create a pipe for the child process's STDOUT. 
 

// CR(2D0, 2D4, NULL, 0);
//Dup(c,2d4,c,&2d8,TRUE,2);
//close(2d4);

   if (! CreatePipe(&hRead1, &hWrite1, NULL, 0)) 
      ErrorExit("Stdout pipe creation failed\n"); 
 
// Create noninheritable read handle and close the inheritable read 
// handle. 

    fSuccess = DuplicateHandle(GetCurrentProcess(), hWrite1,
        GetCurrentProcess(), &hWrite2 , 0,
        TRUE,
        DUPLICATE_SAME_ACCESS);
    if( !fSuccess )
        ErrorExit("DuplicateHandle failed");
    CloseHandle(hWrite1);

//cr(2d4, 2Dc,NULL, 0);
//Dup(c,2d4,c,&2E0,TRUE,2);
//close(2d4);
// in = 2e0;
// out = 2d8;

// Save the handle to the current STDIN. 
 
   hSaveStdin = GetStdHandle(STD_INPUT_HANDLE); 
 
// Create a pipe for the child process's STDIN. 
 
   if (! CreatePipe(&hRead3, &hWrite3, NULL, 0)) 
      ErrorExit("Stdin pipe creation failed\n"); 
 
// Duplicate the write handle to the pipe so it is not inherited. 
 
   fSuccess = DuplicateHandle(GetCurrentProcess(), hRead3, 
      GetCurrentProcess(), &hRead4, 0, 
      TRUE,                  
      DUPLICATE_SAME_ACCESS); 
   if (! fSuccess) 
      ErrorExit("DuplicateHandle failed"); 
 
   CloseHandle(hRead3); 
 
// Now create the child process. 
 
// 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.hStdInput = hRead4;
   siStartInfo.hStdOutput = hWrite2; 
   siStartInfo.hStdError = hWrite2;
   siStartInfo.dwFlags = STARTF_USESTDHANDLES;
// Create the child process. 
 
   if (!CreateProcess("child.exe", 
      "child.exe",       // command line 
      NULL,          // process security attributes 
      NULL,          // primary thread security attributes 
      TRUE,          // handles are inherited 
DETACHED_PROCESS, // creation flags
      NULL,          // use parent's environment 
      NULL,          // use parent's current directory 
      &siStartInfo,  // STARTUPINFO pointer 
      &piProcInfo))  // receives PROCESS_INFORMATION 
   ErrorExit("Create process failed"); 

   CloseHandle(hRead4); 
   CloseHandle(hWrite2); 
 
   CloseHandle(piProcInfo.hProcess);

   // Get a handle to the parent's input file. 
 
   strcpy(chBuf, "trassa");
   chBuf2[0] = 0;
   dwRead = strlen(chBuf)+1;
   resW = WriteFile(hWrite3, chBuf, dwRead, &dwWritten, NULL);
   resR = ReadFile( hRead1, chBuf2, BUFSIZE, &dwRead, NULL);

   TerminateThread(piProcInfo.hThread, 0); 
   if (strcmp(chBuf, chBuf2)) {
      printf("WRITE RESULT: %d\n",resW);
      printf("WRITTEN: %d bytes\n",dwWritten);
      printf("READ RESULT: %d\n",resR);
      printf("READ: %d bytes\n",dwRead);
      ErrorExit("Input output mismatched\n"); 
   }
   else {
      printf("INPUT: %s\n",chBuf);
      printf("OUTPUT: %s\n",chBuf2);
   }
   return 0; 
} 
 
VOID ErrorExit (LPTSTR lpszMessage) 
{ 
   fprintf(stderr, "%s\n", lpszMessage); 
   ExitProcess(0); 
} 
 
