Files
ptyqt/core/conptyprocess.h
T
2019-03-17 00:39:50 +03:00

115 lines
3.1 KiB
C++

#ifndef CONPTYPROCESS_H
#define CONPTYPROCESS_H
#include "iptyprocess.h"
#include <QLibrary>
#include <SDKDDKVer.h>
#include <atlconv.h>
#include <consoleapi.h>
#include <process.h>
#include <stdio.h>
//Taken from the RS5 Windows SDK, but redefined here in case we're targeting <= 17134
//Just for compile, ConPty doesn't work with Windows SDK < 17134 or 18346
#ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE
#define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE \
ProcThreadAttributeValue(22, FALSE, TRUE, FALSE)
typedef VOID* HPCON;
#define TOO_OLD_WINSDK
#endif
//ConPTY available only on Windows 10 releazed after 1903 (19H1) Windows release
class WindowsContext
{
public:
typedef HRESULT (*CreatePseudoConsolePtr)(
COORD size, // ConPty Dimensions
HANDLE hInput, // ConPty Input
HANDLE hOutput, // ConPty Output
DWORD dwFlags, // ConPty Flags
HPCON* phPC); // ConPty Reference
typedef HRESULT (*ResizePseudoConsolePtr)(HPCON hPC, COORD size);
typedef VOID (*ClosePseudoConsolePtr)(HPCON hPC);
WindowsContext()
: createPseudoConsole(nullptr)
, resizePseudoConsole(nullptr)
, closePseudoConsole(nullptr)
{
}
bool init()
{
//already initialized
if (createPseudoConsole)
return true;
//try to load symbols from library
//if it fails -> we can't use ConPty API
HANDLE kernel32Handle = LoadLibraryExW(L"kernel32.dll", 0, 0);
if (kernel32Handle != nullptr)
{
createPseudoConsole = (CreatePseudoConsolePtr)GetProcAddress((HMODULE)kernel32Handle, "CreatePseudoConsole");
resizePseudoConsole = (ResizePseudoConsolePtr)GetProcAddress((HMODULE)kernel32Handle, "ResizePseudoConsole");
closePseudoConsole = (ClosePseudoConsolePtr)GetProcAddress((HMODULE)kernel32Handle, "ClosePseudoConsole");
if (createPseudoConsole == NULL || resizePseudoConsole == NULL || closePseudoConsole == NULL)
{
m_lastError = QString("WindowsContext/ConPty error: %1").arg("Invalid on load API functions");
return false;
}
}
else
{
m_lastError = QString("WindowsContext/ConPty error: %1").arg("Unable to load kernel32");
return false;
}
return true;
}
QString lastError()
{
return m_lastError;
}
public:
//vars
CreatePseudoConsolePtr createPseudoConsole;
ResizePseudoConsolePtr resizePseudoConsole;
ClosePseudoConsolePtr closePseudoConsole;
private:
QString m_lastError;
};
class ConPtyProcess : public IWindowsPtyProcess
{
public:
ConPtyProcess();
~ConPtyProcess();
bool startProcess(const QString &shellPath, QStringList environment, qint16 cols, qint16 rows);
bool resize(qint16 cols, qint16 rows);
bool kill();
PtyType type();
#ifdef PTYQT_DEBUG
QString dumpDebugInfo();
#endif
bool isAvailable();
private:
WindowsContext m_winContext;
HPCON m_ptyHandler;
HANDLE m_hShell;
HANDLE m_inPipeShellSide, m_outPipeShellSide;
};
#endif // CONPTYPROCESS_H