// PipeProcess.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include "windows.h" #include <iostream> #include <stdio.h> #define STDIN_PIPE_ERR 1 #define STDOUT_PIPE_ERR 2 #define PROCESS_CREATION_ERR 4 #define HANDLE_CLOSE_ERR 8 #define WRITE_ERROR 16 #define READ_ERROR 32 #define BUFFER_FILLED_ERR 64 #define UNKNOWN_ERR 128 enum ERR_CODE { }; class Pipe{ private: enum ERR_CODE x; HANDLE hChildStdinRd, hChildStdoutRd, hChildStdinWr, hChildStdoutWr; SECURITY_ATTRIBUTES saStdio; PROCESS_INFORMATION pi; STARTUPINFO si; DWORD ERR_CODES; public: Pipe(CHAR* path); ~Pipe(); //friend ostream& operator<<(Pipe &p, LPSTR wrBuffer); //friend istream& operator>>(Pipe &p, LPSTR &rdBuffer); void WriteToPipe(LPSTR wrBuffer, DWORD bytesToWrite); void ReadFromPipe(LPSTR rdBuffer); protected: }; Pipe::Pipe() { ERR_CODES = 0; #pragma region Process Creation //fill memory with 0's to prevent random errors ZeroMemory(&pi , sizeof(PROCESS_INFORMATION)); ZeroMemory(&si , sizeof(STARTUPINFO)); //Standard startup settings si.cb = sizeof(STARTUPINFO); si.hStdError = hChildStdoutWr; si.hStdOutput = hChildStdoutWr; si.hStdInput = hChildStdinRd; si.dwFlags |= STARTF_USESTDHANDLES; //Create the process and log any errors if any occur ERR_CODES |= ~(CreateProcess(NULL, "child", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) * PROCESS_CREATION_ERR ; #pragma endregion Process Creation #pragma region Pipe Creation //Security settings saStdio.nLength = sizeof(SECURITY_ATTRIBUTES); saStdio.lpSecurityDescriptor = NULL; saStdio.bInheritHandle = TRUE; //Pipe creation and error logging ERR_CODES |= (~(CreatePipe(&hChildStdinRd, &hChildStdinWr, &saStdio, 0)) * STDIN_PIPE_ERR) | (~(CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saStdio, 0)) * STDOUT_PIPE_ERR); //Handle settings, inheritance SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0); SetHandleInformation(hChildStdinWr, HANDLE_FLAG_INHERIT, 0); #pragma endregion Pipe Creation } Pipe::~Pipe() { ERR_CODES |= ~(CloseHandle(pi.hProcess) && CloseHandle(pi.hThread) && CloseHandle(hChildStdinRd) && CloseHandle(hChildStdinWr) && CloseHandle(hChildStdoutRd) && CloseHandle(hChildStdoutWr)) * HANDLE_CLOSE_ERR; if (ERR_CODES!=0) printf("Error code: %d",ERR_CODES); } //ostream& Pipe::operator<<(Pipe &p, LPSTR wrBuffer) //{ // DWORD bytesWritten, bytesToWrite=sizeof(string); // if(bytesToWrite==0) // return p; // ERR_CODES |= (~(WriteFile(hChildStdinWr, wrBuffer, bytesToWrite, &bytesWritten, NULL)) * ERR_CODE.WRITE_ERROR); // if (bytesWritten == 0) // return p; // if (bytesWritten < bytesToWrite) // return p<<wrBuffer[bytesWritten]; //} // //istream& Pipe::operator>>(Pipe &p, LPSTR &rdBuffer) //{ // DWORD bytesRead, bytesToRead = sizeof(rdBuffer); // if (bytesToRead == 0) // { // ERR_CODES |= ERR_CODE.BUFFER_FILLED_ERR; // return p; // } // ERR_CODES |= (~(ReadFile(hChildStdoutRd, &rdBuffer, bytesToRead, &bytesRead, NULL)) * ERR_CODE.READ_ERROR); // if (bytesRead == 0) // return p; // if (bytesRead == bytesToRead) // { // ERR_CODES |= ERR_CODE.BUFFER_FILLED_ERR; // return p; // } //} void Pipe::WriteToPipe(LPSTR wrBuffer, DWORD bytesToWrite) { DWORD bytesWritten; if(bytesToWrite==0) return; ERR_CODES |= (~(WriteFile(hChildStdinWr, wrBuffer, bytesToWrite, &bytesWritten, NULL)) * WRITE_ERROR); if (bytesWritten == 0) return; if (bytesWritten < bytesToWrite) WriteToPipe(&wrBuffer[bytesWritten], bytesToWrite - bytesWritten); } void Pipe::ReadFromPipe(LPSTR rdBuffer) { DWORD bytesRead, bytesToRead = sizeof(rdBuffer); if (bytesToRead == 0) { ERR_CODES |= BUFFER_FILLED_ERR; return; } ERR_CODES |= (~(ReadFile(hChildStdoutRd, &rdBuffer, bytesToRead, &bytesRead, NULL)) * READ_ERROR); if (bytesRead == 0) return; if (bytesRead == bytesToRead) { ERR_CODES |= BUFFER_FILLED_ERR; return; } }
|