Merge pull request #130 from the-ress/get-console-process-list

Add winpty_get_console_process_list
This commit is contained in:
Ryan Prichard 2017-10-07 20:34:18 -07:00 committed by GitHub
commit 850661d02b
5 changed files with 65 additions and 0 deletions

View File

@ -27,6 +27,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <algorithm>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -332,6 +333,9 @@ void Agent::handlePacket(ReadBuffer &packet)
// at once, we can ignore the early ones. // at once, we can ignore the early ones.
handleSetSizePacket(packet); handleSetSizePacket(packet);
break; break;
case AgentMsg::GetConsoleProcessList:
handleGetConsoleProcessListPacket(packet);
break;
default: default:
trace("Unrecognized message, id:%d", type); trace("Unrecognized message, id:%d", type);
} }
@ -426,6 +430,33 @@ void Agent::handleSetSizePacket(ReadBuffer &packet)
writePacket(reply); writePacket(reply);
} }
void Agent::handleGetConsoleProcessListPacket(ReadBuffer &packet)
{
packet.assertEof();
auto processList = std::vector<DWORD>(64);
auto processCount = GetConsoleProcessList(&processList[0], processList.size());
// The process list can change while we're trying to read it
while (processList.size() < processCount) {
// Multiplying by two caps the number of iterations
const auto newSize = std::max<DWORD>(processList.size() * 2, processCount);
processList.resize(newSize);
processCount = GetConsoleProcessList(&processList[0], processList.size());
}
if (processCount == 0) {
trace("GetConsoleProcessList failed");
}
auto reply = newPacket();
reply.putInt32(processCount);
for (DWORD i = 0; i < processCount; i++) {
reply.putInt32(processList[i]);
}
writePacket(reply);
}
void Agent::pollConinPipe() void Agent::pollConinPipe()
{ {
const std::string newData = m_coninPipe->readAllToString(); const std::string newData = m_coninPipe->readAllToString();

View File

@ -59,6 +59,7 @@ private:
void writePacket(WriteBuffer &packet); void writePacket(WriteBuffer &packet);
void handleStartProcessPacket(ReadBuffer &packet); void handleStartProcessPacket(ReadBuffer &packet);
void handleSetSizePacket(ReadBuffer &packet); void handleSetSizePacket(ReadBuffer &packet);
void handleGetConsoleProcessListPacket(ReadBuffer &packet);
void pollConinPipe(); void pollConinPipe();
protected: protected:

View File

@ -218,6 +218,11 @@ WINPTY_API BOOL
winpty_set_size(winpty_t *wp, int cols, int rows, winpty_set_size(winpty_t *wp, int cols, int rows,
winpty_error_ptr_t *err /*OPTIONAL*/); winpty_error_ptr_t *err /*OPTIONAL*/);
/* Gets a list of processes attached to the console. */
WINPTY_API int
winpty_get_console_process_list(winpty_t *wp, int *processList, const int processCount,
winpty_error_ptr_t *err /*OPTIONAL*/);
/* Frees the winpty_t object and the OS resources contained in it. This /* Frees the winpty_t object and the OS resources contained in it. This
* call breaks the connection with the agent, which should then close its * call breaks the connection with the agent, which should then close its
* console, terminating the processes attached to it. * console, terminating the processes attached to it.

View File

@ -935,6 +935,33 @@ winpty_set_size(winpty_t *wp, int cols, int rows,
} API_CATCH(FALSE) } API_CATCH(FALSE)
} }
WINPTY_API int
winpty_get_console_process_list(winpty_t *wp, int *processList, const int processCount,
winpty_error_ptr_t *err /*OPTIONAL*/) {
API_TRY {
ASSERT(wp != nullptr);
ASSERT(processList != nullptr);
LockGuard<Mutex> lock(wp->mutex);
RpcOperation rpc(*wp);
auto packet = newPacket();
packet.putInt32(AgentMsg::GetConsoleProcessList);
writePacket(*wp, packet);
auto reply = readPacket(*wp);
auto actualProcessCount = reply.getInt32();
if (actualProcessCount <= processCount) {
for (auto i = 0; i < actualProcessCount; i++) {
processList[i] = reply.getInt32();
}
}
reply.assertEof();
rpc.success();
return actualProcessCount;
} API_CATCH(0)
}
WINPTY_API void winpty_free(winpty_t *wp) { WINPTY_API void winpty_free(winpty_t *wp) {
// At least in principle, CloseHandle can fail, so this deletion can // At least in principle, CloseHandle can fail, so this deletion can
// fail. It won't throw an exception, but maybe there's an error that // fail. It won't throw an exception, but maybe there's an error that

View File

@ -26,6 +26,7 @@ struct AgentMsg
enum Type { enum Type {
StartProcess, StartProcess,
SetSize, SetSize,
GetConsoleProcessList,
}; };
}; };