If PAExec as STDInput has pipe, the program hangs up in the blocking call of ReadFile and does not exit at completion of a command. Perhaps, it is better to make so:
// Listens our console, and if the user types in something,
// we will pass it to the remote machine.
// ReadConsole return after pressing the ENTER
UINT WINAPI ListenRemoteStdInputPipeThread(void p)
{
//giThreadsWorking already incremented
ListenParam pLP = (ListenParam*)p;
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
char szInputBuffer[SIZEOF_BUFFER] = {0};
DWORD nBytesRead = 0;
DWORD nBytesWrote = 0;
HANDLE hWritePipe = CreateEvent(NULL, TRUE, FALSE, NULL);
DWORD oldMode = 0;
GetConsoleMode(hInput, &oldMode);
//DWORD newMode = oldMode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
//SetConsoleMode(hInput, newMode);
bool bWaitForKeyPress = true;
//detect if input redirected from file (in which case we don't want to wait for keyboard hits)
HANDLE hEvent = NULL;
DWORD fileType = GetFileType(hInput);
if (FILE_TYPE_CHAR != fileType) {
// DWORD inputSize = GetFileSize(hInput, NULL);
// if (INVALID_FILE_SIZE != inputSize)
bWaitForKeyPress = false;
if (fileType == FILE_TYPE_PIPE)
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
while(false == gbStop)
{
if(bWaitForKeyPress)
{
bool bBail = false;
while(0 == _kbhit())
{
if(WAIT_OBJECT_0 == WaitForSingleObject(pLP->hStop, 0))
{
bBail = true;
break;
}
Sleep(100);
}
if(bBail)
break;
}
nBytesRead = 0;
//if ( !ReadConsole( hInput, szInputBuffer, SIZEOF_BUFFER, &nBytesRead, NULL ) ) -- returns UNICODE which is not what we want
if (fileType == FILE_TYPE_PIPE) {
OVERLAPPED olR = { 0 };
olR.hEvent = hEvent;
if (!ReadFile(hInput, szInputBuffer, SIZEOF_BUFFER - 1, &nBytesRead, &olR) || (nBytesRead == 0))
{
DWORD dwErr = GetLastError();
if (dwErr == ERROR_NO_DATA)
break;
}
if (gbStop)
break;
HANDLE waits[2];
waits[0] = pLP->hStop;
waits[1] = olR.hEvent;
DWORD ret = WaitForMultipleObjects(2, waits, FALSE, INFINITE);
if (ret == WAIT_OBJECT_0)
break; //need to exit
_ASSERT(ret == WAIT_OBJECT_0 + 1); //data in buffer now
GetOverlappedResult(hInput, &olR, &nBytesRead, FALSE);
}
else if (!ReadFile( hInput, szInputBuffer, SIZEOF_BUFFER - 1, &nBytesRead, NULL))
{
DWORD dwErr = GetLastError();
if ( dwErr == ERROR_NO_DATA)
break;
}
if(gbStop)
break;
if(bWaitForKeyPress)
{
//suppress the input from being printed in the output since it was already shown locally
EnterCriticalSection(&pLP->cs);
szInputBuffer[nBytesRead] = '\0';
pLP->inputSentToSuppressInOutput.push_back(szInputBuffer);
LeaveCriticalSection(&pLP->cs);
}
// Send it to remote process' stdin
OVERLAPPED olW = {0};
olW.hEvent = hWritePipe;
if (!WriteFile( pLP->pSettings->hStdIn, szInputBuffer, nBytesRead, &nBytesWrote, &olW))
{
DWORD gle = GetLastError();
break;
}
if(gbStop)
break;
HANDLE waits[2];
waits[0] = pLP->hStop;
waits[1] = olW.hEvent;
DWORD ret = WaitForMultipleObjects(2, waits, FALSE, INFINITE);
if(ret == WAIT_OBJECT_0)
break; //need to exit
_ASSERT(ret == WAIT_OBJECT_0 + 1); //write finished
FlushFileBuffers(pLP->pSettings->hStdIn);
}
CloseHandle(hWritePipe);
if (hEvent) CloseHandle(hEvent);
SetConsoleMode(hInput, oldMode);
InterlockedDecrement(&pLP->workerThreads);
return 0;
If PAExec as STDInput has pipe, the program hangs up in the blocking call of ReadFile and does not exit at completion of a command. Perhaps, it is better to make so:
// Listens our console, and if the user types in something, // we will pass it to the remote machine. // ReadConsole return after pressing the ENTER UINT WINAPI ListenRemoteStdInputPipeThread(void p) { //giThreadsWorking already incremented ListenParam pLP = (ListenParam*)p;
}