Compare commits

...

21 Commits

Author SHA1 Message Date
Ryan Prichard
bbdc8b82ae Fix compilation errors related to C++11's new user-defined string literals 2015-12-17 20:10:07 -06:00
Peter Rekdal Sunde
4f38a876ec Merge pull request #2 from cjfromthesea/patch-1
Include <algorithm> for std::min and std::max
2014-08-08 08:33:06 +02:00
Christian Howe
86690addf4 Include <algorithm> for std::min and std::max 2014-08-07 21:18:04 -04:00
Peter Sunde
25e3186e9e ensure that we always set envArg to NULL if string is empty 2013-10-21 00:42:16 +02:00
Peter Sunde
d4b5cb8a33 revert to original code 2013-10-20 20:25:53 +02:00
Peter Sunde
1db59898e3 should be 'libraries' not 'library' 2013-10-19 20:08:46 +02:00
Peter Sunde
efc82affdf add missing library 2013-10-19 20:00:23 +02:00
Peter Sunde
9325995ae4 cleanup 2013-09-20 15:51:58 +02:00
Peter Sunde
587e5125a7 fix null termination for environment 2013-09-20 15:51:46 +02:00
Peter Sunde
237c36b7db pass raw environment string 2013-09-20 14:21:39 +02:00
Peter Sunde
515dea18de ged rid of msvs warnings (these needs to fixed upstream, but these are not critical for day to day operations anyway) 2013-09-20 14:12:48 +02:00
Peter Sunde
b4fea62fb0 Merge remote-tracking branch 'vendor/master' 2013-09-20 10:40:54 +02:00
Peter Sunde
4bdd7b32b5 Remove garbage added by me. 2013-02-27 08:50:12 +01:00
Peter Rekdal
8aa7662093 Update winpty.gyp 2013-02-27 07:31:58 +01:00
Peter Sunde
1cb199b1f0 Resolve merge conflicts 2013-02-27 06:54:37 +01:00
Peter Sunde
3f1bbcd9af Allow thirdparty to host datapipe themself. Also replace winpty_close() with winpty_exit() since closing the control pipe will cause child process to exit. 2013-02-27 06:51:02 +01:00
Peter Sunde
7091af176a Improve error message 2013-02-27 06:48:35 +01:00
Peter Sunde
857ed8934b Remove unnecessary header files 2013-02-27 06:48:08 +01:00
Peter Sunde
964f5a63f8 Update gyp file. 2012-12-20 13:30:16 +01:00
Peter Sunde
747a5401e8 Remove data pipe names from winpty_open 2012-12-17 13:33:32 +01:00
Peter Sunde
5363fb6c21 Allow building with gyp and Visual Studio. 2012-12-17 13:20:30 +01:00
7 changed files with 148 additions and 49 deletions

View File

@ -192,7 +192,7 @@ void Agent::handlePacket(ReadBuffer &packet)
int Agent::handleStartProcessPacket(ReadBuffer &packet)
{
BOOL success;
BOOL success;
ASSERT(m_childProcess == NULL);
std::wstring program = packet.getWString();
@ -212,7 +212,11 @@ int Agent::handleStartProcessPacket(ReadBuffer &packet)
cmdlineArg = &cmdlineCopy[0];
}
LPCWSTR cwdArg = cwd.empty() ? NULL : cwd.c_str();
LPCWSTR envArg = env.empty() ? NULL : env.data();
LPCWSTR envArg = env.empty() ? NULL : env.c_str();
if(envArg != NULL && wcscmp(envArg, L"")) {
envArg = NULL;
}
STARTUPINFO sui;
PROCESS_INFORMATION pi;

View File

@ -24,6 +24,7 @@
#include <windows.h>
#include <string>
#include <vector>
#include <algorithm>
class EventLoop;

View File

@ -57,7 +57,7 @@ Terminal::Terminal(NamedPipe *output) :
void Terminal::reset(bool sendClearFirst, int newLine)
{
if (sendClearFirst)
m_output->write(CSI"1;1H"CSI"2J");
m_output->write(CSI"1;1H" CSI"2J");
m_remoteLine = newLine;
m_cursorHidden = false;
m_cursorPos = std::pair<int, int>(0, newLine);
@ -162,7 +162,7 @@ void Terminal::finishOutput(const std::pair<int, int> &newCursorPos)
if (m_cursorHidden) {
moveTerminalToLine(newCursorPos.second);
char buffer[32];
sprintf(buffer, CSI"%dG"CSI"?25h", newCursorPos.first + 1);
sprintf(buffer, CSI"%dG" CSI"?25h", newCursorPos.first + 1);
m_output->write(buffer);
m_cursorHidden = false;
}
@ -187,7 +187,7 @@ void Terminal::moveTerminalToLine(int line)
if (line < m_remoteLine) {
// CUrsor Up (CUU)
char buffer[32];
sprintf(buffer, "\r"CSI"%dA", m_remoteLine - line);
sprintf(buffer, "\r" CSI"%dA", m_remoteLine - line);
m_output->write(buffer);
m_remoteLine = line;
} else if (line > m_remoteLine) {

View File

@ -32,6 +32,7 @@
#define WINPTY_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -49,6 +50,16 @@ typedef struct winpty_s winpty_t;
*/
WINPTY_API winpty_t *winpty_open(int cols, int rows);
/**
* Starts a new winpty instance with the given size.
*
* This function creates a new agent process and connects to it.
* By using this method you are responsible for creating your own named
* pipe server for communicating with the child process.
*
*/
WINPTY_API winpty_t *winpty_open_use_own_datapipe(const wchar_t *dataPipe, int cols, int rows);
/*
* Start a child process. Either (but not both) of appname and cmdline may
* be NULL. cwd and env may be NULL. env is a pointer to an environment
@ -88,7 +99,7 @@ WINPTY_API int winpty_set_size(winpty_t *pc, int cols, int rows);
/*
* Closes the winpty.
*/
WINPTY_API void winpty_close(winpty_t *pc);
WINPTY_API void winpty_exit(winpty_t *pc);
#ifdef __cplusplus
}

View File

@ -27,9 +27,59 @@
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
std::string to_utf8(const wchar_t* buffer, int len)
{
int nChars = ::WideCharToMultiByte(
CP_UTF8,
0,
buffer,
len,
NULL,
0,
NULL,
NULL);
if (nChars == 0) return "";
std::string newbuffer;
newbuffer.resize(nChars) ;
::WideCharToMultiByte(
CP_UTF8,
0,
buffer,
len,
const_cast< char* >(newbuffer.c_str()),
nChars,
NULL,
NULL);
return newbuffer;
}
std::string to_utf8(const std::wstring& str)
{
return to_utf8(str.c_str(), (int)str.size());
}
std::wstring to_wstring(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
#include "../shared/DebugClient.h"
#include "../shared/AgentMsg.h"
#include "../shared/Buffer.h"
#include "../shared/c99_snprintf.h"
// TODO: Error handling, handle out-of-memory.
@ -86,7 +136,7 @@ static bool pathExists(const std::wstring &path)
static std::wstring findAgentProgram()
{
std::wstring progDir = dirname(getModuleFileName(getCurrentModule()));
std::wstring ret = progDir + L"\\"AGENT_EXE;
std::wstring ret = progDir + (L"\\" AGENT_EXE);
assert(pathExists(ret));
return ret;
}
@ -117,10 +167,13 @@ static bool connectNamedPipe(HANDLE handle, bool overlapped)
static void writePacket(winpty_t *pc, const WriteBuffer &packet)
{
std::string payload = packet.str();
int32_t payloadSize = payload.size();
DWORD actual;
BOOL success = WriteFile(pc->controlPipe, &payloadSize, sizeof(int32_t), &actual, NULL);
assert(success && actual == sizeof(int32_t));
success = WriteFile(pc->controlPipe, payload.c_str(), payloadSize, &actual, NULL);
assert(success && (int32_t)actual == payloadSize);
}
@ -259,10 +312,13 @@ WINPTY_API winpty_t *winpty_open(int cols, int rows)
// Start pipes.
std::wstringstream pipeName;
pipeName << L"\\\\.\\pipe\\winpty-" << GetCurrentProcessId()
<< L"-" << InterlockedIncrement(&consoleCounter);
std::wstring controlPipeName = pipeName.str() + L"-control";
std::wstring dataPipeName = pipeName.str() + L"-data";
// Allow custom pipe names.
pipeName << L"\\\\.\\pipe\\winpty-" << GetCurrentProcessId()
<< L"-" << InterlockedIncrement(&consoleCounter);
std::wstring controlPipeName = pipeName.str() + L"-control";
std::wstring dataPipeName = pipeName.str() + L"-data";
pc->controlPipe = createNamedPipe(controlPipeName, false);
if (pc->controlPipe == INVALID_HANDLE_VALUE) {
delete pc;
@ -353,31 +409,67 @@ WINPTY_API winpty_t *winpty_open(int cols, int rows)
return pc;
}
WINPTY_API winpty_t *winpty_open_use_own_datapipe(const wchar_t *dataPipe, int cols, int rows)
{
winpty_t *pc = new winpty_t;
// Setup pipes.
std::wstringstream pipeName;
pipeName << L"\\\\.\\pipe\\winpty-" << GetCurrentProcessId()
<< L"-" << InterlockedIncrement(&consoleCounter);
std::wstring controlPipeName = pipeName.str() + L"-control";
// The callee provides his own pipe implementation for handling sending/recieving
// data between the started child process.
std::wstring dataPipeName(to_wstring(to_utf8(dataPipe)));
// Create control pipe
pc->controlPipe = createNamedPipe(controlPipeName, false);
if (pc->controlPipe == INVALID_HANDLE_VALUE) {
delete pc;
return NULL;
}
// Setup a background desktop for the agent.
BackgroundDesktop desktop = setupBackgroundDesktop();
// Start the agent.
startAgentProcess(desktop, controlPipeName, dataPipeName, cols, rows);
// Test control pipe connection.
if (!connectNamedPipe(pc->controlPipe, false)) {
delete pc;
return NULL;
}
// Restore desktop.
restoreOriginalDesktop(desktop);
WriteBuffer packet;
packet.putInt(AgentMsg::Ping);
writePacket(pc, packet);
if (readInt32(pc) != 0) {
delete pc;
return NULL;
}
return pc;
}
WINPTY_API int winpty_start_process(winpty_t *pc,
const wchar_t *appname,
const wchar_t *cmdline,
const wchar_t *cwd,
const wchar_t *env)
{
WriteBuffer packet;
packet.putInt(AgentMsg::StartProcess);
packet.putWString(appname ? appname : L"");
packet.putWString(cmdline ? cmdline : L"");
packet.putWString(cwd ? cwd : L"");
std::wstring envStr;
if (env != NULL) {
const wchar_t *p = env;
while (*p != L'\0') {
p += wcslen(p) + 1;
}
p++;
envStr.assign(env, p);
// Can a Win32 environment be empty? If so, does it end with one NUL or
// two? Add an extra NUL just in case it matters.
envStr.push_back(L'\0');
}
packet.putWString(envStr);
packet.putWString(env ? env : L"");
packet.putWString(getDesktopFullName());
writePacket(pc, packet);
return readInt32(pc);
@ -406,9 +498,10 @@ WINPTY_API int winpty_set_size(winpty_t *pc, int cols, int rows)
return readInt32(pc);
}
WINPTY_API void winpty_close(winpty_t *pc)
WINPTY_API void winpty_exit(winpty_t *pc)
{
CloseHandle(pc->controlPipe);
CloseHandle(pc->dataPipe);
delete pc;
CloseHandle(pc->controlPipe);
if(pc->dataPipe > 0) {
CloseHandle(pc->dataPipe);
}
}

View File

@ -99,4 +99,4 @@ void trace(const char *format, ...)
fullMessage[sizeof(fullMessage) - 1] = '\0';
sendToDebugServer(fullMessage);
}
}

View File

@ -6,37 +6,28 @@
'include_dirs' : [
'include',
],
'libraries' : [
'user32.lib'
],
'defines' : [
'UNICODE',
'_UNICODE',
'_WIN32_WINNT=0x0501',
'NOMINMAX',
],
'msvs_disabled_warnings': [ 4267, 4244, 4530, 4267, 4800 ],
'sources' : [
'agent/Agent.h',
'agent/Agent.cc',
'agent/AgentAssert.h',
'agent/AgentAssert.cc',
'agent/ConsoleInput.cc',
'agent/ConsoleInput.h',
'agent/Coord.h',
'agent/Coord.cc',
'agent/DsrSender.h',
'agent/EventLoop.cc',
'agent/NamedPipe.h',
'agent/NamedPipe.cc',
'agent/SmallRect.h',
'agent/SmallRect.cc',
'agent/Terminal.h',
'agent/Terminal.cc',
'agent/Win32Console.cc',
'agent/Win32Console.h',
'agent/main.cc',
'shared/AgentMsg.h',
'shared/Buffer.h',
'shared/DebugClient.h',
'shared/DebugClient.cc',
'shared/c99_snprintf.h',
],
},
{
@ -45,6 +36,9 @@
'include_dirs' : [
'include',
],
'libraries' : [
'user32.lib'
],
'defines' : [
'UNICODE',
'_UNICODE',
@ -52,15 +46,11 @@
'NOMINMAX',
'WINPTY',
],
'msvs_disabled_warnings': [ 4267, 4800 ],
'sources' : [
'include/winpty.h',
'libwinpty/winpty.cc',
'shared/AgentMsg.h',
'shared/Buffer.h',
'shared/DebugClient.h',
'shared/DebugClient.cc',
'shared/c99_snprintf.h',
],
},
],
}
}