├── PtyAgent ├── lib │ ├── VERSION.txt │ ├── shared │ │ ├── GetCommitHash.bat │ │ ├── UpdateGenVersion.bat │ │ ├── WinptyVersion.h │ │ ├── WindowsVersion.h │ │ ├── AgentMsg.h │ │ ├── OwnedHandle.cc │ │ ├── PrecompiledHeader.h │ │ ├── WinptyException.h │ │ ├── WinptyVersion.cc │ │ ├── DebugClient.h │ │ ├── OwnedHandle.h │ │ ├── UnixCtrlChars.h │ │ ├── GenRandom.h │ │ ├── StringUtil.cc │ │ ├── WinptyAssert.cc │ │ ├── WinptyException.cc │ │ ├── Mutex.h │ │ ├── TimeMeasurement.h │ │ ├── OsModule.h │ │ ├── StringUtil.h │ │ ├── WinptyAssert.h │ │ ├── BackgroundDesktop.h │ │ ├── Buffer.h │ │ └── WindowsSecurity.h │ ├── LICENSE │ ├── agent │ │ ├── DsrSender.h │ │ ├── ConsoleFont.h │ │ ├── DefaultInputMap.h │ │ ├── AgentCreateDesktop.h │ │ ├── DebugShowInput.h │ │ ├── ConsoleInputReencoding.h │ │ ├── ConsoleLine.h │ │ ├── EventLoop.h │ │ ├── Terminal.h │ │ ├── Coord.h │ │ ├── Win32Console.h │ │ ├── subdir.mk │ │ ├── SimplePool.h │ │ ├── LargeConsoleRead.h │ │ ├── LargeConsoleRead.cc │ │ ├── AgentCreateDesktop.cc │ │ ├── EventLoop.cc │ │ ├── Win32ConsoleBuffer.h │ │ └── InputMap.h │ └── libwinpty │ │ ├── AgentLocation.h │ │ ├── subdir.mk │ │ ├── LibWinptyException.h │ │ ├── WinptyInternal.h │ │ └── AgentLocation.cc ├── PtyAgent.upp ├── PtyAgent.ext └── ReadMe.md ├── PtyProcess ├── lib │ ├── VERSION.txt │ ├── libwinpty.cpp │ ├── libwinpty.h │ ├── LICENSE │ ├── shared │ │ ├── WinptyVersion.h │ │ ├── WindowsVersion.h │ │ ├── AgentMsg.h │ │ ├── OwnedHandle.cc │ │ ├── PrecompiledHeader.h │ │ ├── WinptyException.h │ │ ├── WinptyVersion.cc │ │ ├── DebugClient.h │ │ ├── OwnedHandle.h │ │ ├── UnixCtrlChars.h │ │ ├── GenRandom.h │ │ ├── StringUtil.cc │ │ ├── WinptyException.cc │ │ ├── WinptyAssert.cc │ │ ├── Mutex.h │ │ ├── TimeMeasurement.h │ │ ├── OsModule.h │ │ ├── StringUtil.h │ │ ├── WinptyAssert.h │ │ ├── BackgroundDesktop.h │ │ └── Buffer.h │ └── libwinpty │ │ ├── AgentLocation.h │ │ ├── LibWinptyException.h │ │ ├── WinptyInternal.h │ │ └── AgentLocation.cc ├── PtyProcess.upp ├── Copying ├── src.tpp │ └── Upp_PtyWaitEvent_en-us.tpp └── ReadMe.md ├── examples ├── TerminalLayoutExample │ ├── TerminalLayoutExample.lay │ ├── TerminalLayoutExample.upp │ └── TerminalLayoutExample.h ├── TerminalSplitterExample │ ├── TerminalSplitterExample.upp │ └── main.cpp ├── SshTerminalSplitterExample │ ├── SshTerminalSplitterExample.upp │ └── main.cpp ├── TabbedTerminalExample │ ├── TabbedTerminalExample.upp │ └── main.cpp ├── TerminalInWebBrowserExample │ ├── TerminalInWebBrowserExample.upp │ └── main.cpp ├── SshTerminalExample │ ├── SshTerminalExample.upp │ └── main.cpp ├── TabbedSshTerminalExample │ ├── TabbedSshTerminalExample.upp │ └── main.cpp └── TerminalExample │ ├── TerminalExample.upp │ └── main.cpp ├── Terminal ├── Version ├── Terminal.upp ├── Sixel.h ├── Esc.cpp ├── Copying └── Terminal.usc └── LICENSE /PtyAgent/lib/VERSION.txt: -------------------------------------------------------------------------------- 1 | 0.4.4-dev 2 | -------------------------------------------------------------------------------- /PtyProcess/lib/VERSION.txt: -------------------------------------------------------------------------------- 1 | 0.4.4-dev 2 | -------------------------------------------------------------------------------- /examples/TerminalLayoutExample/TerminalLayoutExample.lay: -------------------------------------------------------------------------------- 1 | LAYOUT(TerminalExampleLayout, 464, 268) 2 | ITEM(Upp::TerminalCtrl, term, AdjustColors(false).InlineImages(true).Hyperlinks(true).WindowActions(true).WindowReports(true).SetFrame(NullFrame()).HSizePosZ(0, 0).VSizePosZ(0, 0)) 3 | END_LAYOUT 4 | 5 | -------------------------------------------------------------------------------- /examples/TerminalSplitterExample/TerminalSplitterExample.upp: -------------------------------------------------------------------------------- 1 | description "Demonstrates a basic terminal splitter, using Terminal package.\377"; 2 | 3 | uses 4 | CtrlLib, 5 | Terminal, 6 | PtyProcess; 7 | 8 | file 9 | main.cpp; 10 | 11 | mainconfig 12 | "" = "GUI", 13 | "" = "GUI WIN10"; 14 | 15 | -------------------------------------------------------------------------------- /examples/SshTerminalSplitterExample/SshTerminalSplitterExample.upp: -------------------------------------------------------------------------------- 1 | description "Demonstrates a multithreaded ssh terminal splitter, using the Terminal and SSH packages.\377"; 2 | 3 | uses 4 | CtrlLib, 5 | Terminal, 6 | Core/SSH; 7 | 8 | file 9 | main.cpp; 10 | 11 | mainconfig 12 | "" = "GUI"; 13 | 14 | -------------------------------------------------------------------------------- /examples/TabbedTerminalExample/TabbedTerminalExample.upp: -------------------------------------------------------------------------------- 1 | description "Demonstrates a simple tabbed terminal setup, using Terminal package.\377"; 2 | 3 | uses 4 | CtrlLib, 5 | TabBar, 6 | Terminal, 7 | PtyProcess; 8 | 9 | file 10 | main.cpp; 11 | 12 | mainconfig 13 | "" = "GUI", 14 | "" = "GUI WIN10"; 15 | 16 | -------------------------------------------------------------------------------- /examples/TerminalInWebBrowserExample/TerminalInWebBrowserExample.upp: -------------------------------------------------------------------------------- 1 | description "Demonstrates the usage of Terminal package with U++ Turtle backend (Thin HTML5 client)\377"; 2 | 3 | uses 4 | Terminal, 5 | Turtle, 6 | PtyProcess; 7 | 8 | file 9 | main.cpp; 10 | 11 | mainconfig 12 | "" = "WIN10", 13 | "" = ""; 14 | 15 | -------------------------------------------------------------------------------- /examples/SshTerminalExample/SshTerminalExample.upp: -------------------------------------------------------------------------------- 1 | description "Demonstrates a simple SSH terminal example, using the Terminal ctrl as a fron end for Core/SSH package.\377"; 2 | 3 | uses 4 | CtrlLib, 5 | Terminal, 6 | Core/SSH; 7 | 8 | file 9 | main.cpp; 10 | 11 | mainconfig 12 | "" = "GUI", 13 | "" = "GUI .TRUECOLOR"; 14 | 15 | -------------------------------------------------------------------------------- /examples/TabbedSshTerminalExample/TabbedSshTerminalExample.upp: -------------------------------------------------------------------------------- 1 | description "Demonstrates a multithreaded ssh terminal with tabs, using the Terminal and SSH packages\377"; 2 | 3 | uses 4 | CtrlLib, 5 | Terminal, 6 | Core/SSH, 7 | TabBar; 8 | 9 | file 10 | main.cpp; 11 | 12 | mainconfig 13 | "" = "GUI", 14 | "" = "GUI .NOGTK"; 15 | 16 | -------------------------------------------------------------------------------- /examples/TerminalExample/TerminalExample.upp: -------------------------------------------------------------------------------- 1 | description "Demonstrates a simple virtual terminal emulator example, using Terminal package and PtyProcess on POSIX-compliant systems\377"; 2 | 3 | uses 4 | CtrlLib, 5 | Terminal, 6 | PtyProcess; 7 | 8 | file 9 | main.cpp; 10 | 11 | mainconfig 12 | "" = "GUI", 13 | "" = "GUI WIN10"; 14 | 15 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/GetCommitHash.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | REM -- Echo the git commit hash. If git isn't available for some reason, 4 | REM -- output nothing instead. 5 | 6 | git rev-parse HEAD >NUL 2>NUL && ( 7 | git rev-parse HEAD 8 | ) || ( 9 | echo none 10 | ) 11 | 12 | REM -- Set ERRORLEVEL to 0 using this cryptic syntax. 13 | (call ) 14 | -------------------------------------------------------------------------------- /PtyAgent/PtyAgent.upp: -------------------------------------------------------------------------------- 1 | description "U++ package for winpty agent executable.\377"; 2 | 3 | noblitz; 4 | 5 | library(WIN32) "advapi32 shell32 user32"; 6 | 7 | options 8 | -DWINPTY_AGENT_ASSERT; 9 | 10 | options(CLANG) -Wno-ignored-attributes; 11 | 12 | file 13 | Meta readonly separator, 14 | PtyAgent.ext, 15 | Info readonly separator, 16 | ReadMe.md, 17 | lib/LICENSE; 18 | 19 | -------------------------------------------------------------------------------- /PtyAgent/PtyAgent.ext: -------------------------------------------------------------------------------- 1 | // Imports the source files of winpty-agent executable, filters out the test code and other files. 2 | 3 | files 4 | lib/include/*.h 5 | lib/include/*.cc 6 | lib/shared/*.h 7 | lib/shared/*.cc 8 | lib/agent/*.h 9 | lib/agent/*.cc 10 | ; 11 | 12 | exclude 13 | lib/shared/*Test* 14 | lib/agent/*Test* 15 | ; 16 | 17 | includes ; -------------------------------------------------------------------------------- /examples/TerminalLayoutExample/TerminalLayoutExample.upp: -------------------------------------------------------------------------------- 1 | description "Demonstrates terminal gui building, layouts, menus, serialization, high performance event loop, etc.\377"; 2 | 3 | uses 4 | CtrlLib, 5 | Terminal, 6 | PtyProcess; 7 | 8 | file 9 | TerminalLayoutExample.h, 10 | main.cpp, 11 | TerminalLayoutExample.lay; 12 | 13 | mainconfig 14 | "" = "GUI", 15 | "" = "GUI WIN10"; 16 | 17 | -------------------------------------------------------------------------------- /Terminal/Version: -------------------------------------------------------------------------------- 1 | # For commit history and changes, see: 2 | # https://github.com/ismail-yilmaz/Terminal/commits/master 3 | 4 | 17/08/2025: 2025.2, Version 1.0 (From now on, only the YYYY.REL[.REV] version format will be used.) 5 | 12/08/2024: 2025.1, Version 0.9 6 | 12/03/2023: 2023.2, Version 0.8 7 | 05/29/2021: 2021.1, Version 0.5 8 | 12/06/2020: 2020.2, Version 0.4 9 | 03/10/2020: 2020.1, Version 0.3 10 | 09/22/2019: 2019.2, Version 0.2 11 | 07/20/2019: 2019.1, Version 0.1 12 | -------------------------------------------------------------------------------- /PtyProcess/PtyProcess.upp: -------------------------------------------------------------------------------- 1 | description "A cross-platform pseudo-terminal process implementation for U++\377"; 2 | 3 | uses 4 | Core; 5 | 6 | library(WIN32) "advapi32 user32"; 7 | 8 | options(WIN32) -DAGENT_EXE=L\"PtyAgent.exe\"; 9 | 10 | file 11 | PtyProcess.h, 12 | PosixPty.cpp, 13 | Win32Pty.cpp, 14 | PtyWaitEvent.cpp, 15 | Library readonly separator, 16 | lib\libwinpty.h, 17 | lib\libwinpty.cpp, 18 | lib\LICENSE, 19 | Meta readonly separator, 20 | ReadMe.md, 21 | Copying, 22 | Docs readonly separator, 23 | src.tpp; 24 | 25 | -------------------------------------------------------------------------------- /PtyProcess/lib/libwinpty.cpp: -------------------------------------------------------------------------------- 1 | #include "libwinpty.h" 2 | 3 | // Upp-libwinpty source files. 4 | 5 | #if (defined(flagWIN32) || defined(flagWIN64)) 6 | #include "libwinpty/winpty.cc" 7 | #include "libwinpty/AgentLocation.cc" 8 | #include "shared/BackgroundDesktop.cc" 9 | #include "shared/Buffer.cc" 10 | #include "shared/DebugClient.cc" 11 | #include "shared/GenRandom.cc" 12 | #include "shared/OwnedHandle.cc" 13 | #include "shared/StringUtil.cc" 14 | #include "shared/WindowsSecurity.cc" 15 | #include "shared/WindowsVersion.cc" 16 | #include "shared/WinptyAssert.cc" 17 | #include "shared/WinptyException.cc" 18 | #include "shared/WinptyVersion.cc" 19 | #endif 20 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/UpdateGenVersion.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem -- Echo the git commit hash. If git isn't available for some reason, 4 | rem -- output nothing instead. 5 | 6 | mkdir ..\gen 2>nul 7 | 8 | set /p VERSION=<..\..\VERSION.txt 9 | set COMMIT=%1 10 | 11 | echo // AUTO-GENERATED BY %0 %*>..\gen\GenVersion.h 12 | echo const char GenVersion_Version[] = "%VERSION%";>>..\gen\GenVersion.h 13 | echo const char GenVersion_Commit[] = "%COMMIT%";>>..\gen\GenVersion.h 14 | 15 | rem -- The winpty.gyp file expects the script to output the include directory, 16 | rem -- relative to src. 17 | echo gen 18 | 19 | rem -- Set ERRORLEVEL to 0 using this cryptic syntax. 20 | (call ) 21 | -------------------------------------------------------------------------------- /Terminal/Terminal.upp: -------------------------------------------------------------------------------- 1 | description "A flexible and powerful terminal emulation widget and library for Ultimate++\377"; 2 | 3 | uses 4 | CtrlLib, 5 | plugin/jpg; 6 | 7 | file 8 | Terminal.h, 9 | Terminal.cpp, 10 | Renderer.cpp, 11 | Keys.cpp, 12 | Tables.cpp, 13 | Modes.cpp, 14 | Charsets.cpp, 15 | Colors.cpp, 16 | Esc.cpp, 17 | Csi.cpp, 18 | Dcs.cpp, 19 | Osc.cpp, 20 | Sgr.cpp, 21 | IO.cpp, 22 | Cell readonly separator, 23 | Cell.h, 24 | Cell.cpp, 25 | Page readonly separator, 26 | Page.h, 27 | Page.cpp, 28 | Parser readonly separator, 29 | Parser.h, 30 | Parser.cpp, 31 | Sixel readonly separator, 32 | Sixel.h, 33 | Sixel.cpp, 34 | Meta readonly separator, 35 | Terminal.usc, 36 | Terminal.key, 37 | Docs readonly separator, 38 | src.tpp, 39 | srcdoc.tpp, 40 | Info readonly separator, 41 | Copying, 42 | Version; 43 | 44 | -------------------------------------------------------------------------------- /PtyProcess/lib/libwinpty.h: -------------------------------------------------------------------------------- 1 | #ifndef _PtyProcess_WinPtyBackend_h_ 2 | #define _PtyProcess_WinPtyBackend_h_ 3 | 4 | // Upp-libwinpty header files. 5 | 6 | #if (defined(flagWIN32) || defined(flagWIN64)) 7 | #define UNICODE 8 | #define COMPILING_WINPTY_STATIC 9 | // #define AGENT_EXE L"PtyAgent.exe" 10 | #include "include/winpty.h" 11 | #include "libwinpty/AgentLocation.h" 12 | #include "shared/AgentMsg.h" 13 | #include "shared/BackgroundDesktop.h" 14 | #include "shared/Buffer.h" 15 | #include "shared/DebugClient.h" 16 | #include "shared/GenRandom.h" 17 | #include "shared/OsModule.h" 18 | #include "shared/OwnedHandle.h" 19 | #include "shared/StringBuilder.h" 20 | #include "shared/StringUtil.h" 21 | #include "shared/WindowsSecurity.h" 22 | #include "shared/WindowsVersion.h" 23 | #include "shared/WinptyAssert.h" 24 | #include "shared/WinptyException.h" 25 | #include "shared/WinptyVersion.h" 26 | #include "shared/winpty_snprintf.h" 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /PtyAgent/lib/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Ryan Prichard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /PtyProcess/lib/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Ryan Prichard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/WinptyVersion.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_VERSION_H 22 | #define WINPTY_VERSION_H 23 | 24 | void dumpVersionToStdout(); 25 | void dumpVersionToTrace(); 26 | 27 | #endif // WINPTY_VERSION_H 28 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/DsrSender.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef DSRSENDER_H 22 | #define DSRSENDER_H 23 | 24 | class DsrSender 25 | { 26 | public: 27 | virtual void sendDsr() = 0; 28 | }; 29 | 30 | #endif // DSRSENDER_H 31 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/WinptyVersion.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_VERSION_H 22 | #define WINPTY_VERSION_H 23 | 24 | void dumpVersionToStdout(); 25 | void dumpVersionToTrace(); 26 | 27 | #endif // WINPTY_VERSION_H 28 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/ConsoleFont.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef CONSOLEFONT_H 22 | #define CONSOLEFONT_H 23 | 24 | #include 25 | 26 | void setSmallFont(HANDLE conout, int columns, bool isNewW10); 27 | 28 | #endif // CONSOLEFONT_H 29 | -------------------------------------------------------------------------------- /Terminal/Sixel.h: -------------------------------------------------------------------------------- 1 | #ifndef _SixelRenderer_h_ 2 | #define _SixelRenderer_h_ 3 | 4 | #include 5 | #include 6 | 7 | namespace Upp{ 8 | 9 | class SixelStream : MemReadStream { 10 | public: 11 | struct Palette : Vector { void Init(); }; 12 | 13 | SixelStream(const void *data, int64 size, Palette *shared_palette = nullptr); 14 | SixelStream(const String& data, Palette *shared_palette = nullptr); 15 | 16 | SixelStream& Background(bool b = true) { background = b; return *this; } 17 | operator Image(); 18 | 19 | private: 20 | void Clear(); 21 | inline void Return(); 22 | inline void LineFeed(); 23 | void SetPalette(); 24 | void GetRasterInfo(); 25 | void GetRepeatCount(); 26 | int ReadParams(); 27 | void CalcYOffests(); 28 | void AdjustBufferSize(); 29 | void PaintSixel(int c); 30 | 31 | private: 32 | ImageBuffer buffer; 33 | Palette private_palette; 34 | Palette* paletteptr; 35 | RGBA ink; 36 | RGBA paper; 37 | int repeat; 38 | int params[8]; 39 | int coords[6]; 40 | Size size; 41 | Point cursor; 42 | bool background:1; 43 | }; 44 | } 45 | #endif 46 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/DefaultInputMap.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef DEFAULT_INPUT_MAP_H 22 | #define DEFAULT_INPUT_MAP_H 23 | 24 | class InputMap; 25 | 26 | void addDefaultEntriesToInputMap(InputMap &inputMap); 27 | 28 | #endif // DEFAULT_INPUT_MAP_H 29 | -------------------------------------------------------------------------------- /PtyAgent/lib/libwinpty/AgentLocation.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LIBWINPTY_AGENT_LOCATION_H 22 | #define LIBWINPTY_AGENT_LOCATION_H 23 | 24 | #include 25 | 26 | std::wstring findAgentProgram(); 27 | 28 | #endif // LIBWINPTY_AGENT_LOCATION_H 29 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/AgentCreateDesktop.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef AGENT_CREATE_DESKTOP_H 22 | #define AGENT_CREATE_DESKTOP_H 23 | 24 | #include 25 | 26 | void handleCreateDesktop(LPCWSTR controlPipeName); 27 | 28 | #endif // AGENT_CREATE_DESKTOP_H 29 | -------------------------------------------------------------------------------- /PtyProcess/lib/libwinpty/AgentLocation.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LIBWINPTY_AGENT_LOCATION_H 22 | #define LIBWINPTY_AGENT_LOCATION_H 23 | 24 | #include 25 | 26 | std::wstring findAgentProgram(); 27 | 28 | #endif // LIBWINPTY_AGENT_LOCATION_H 29 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/WindowsVersion.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_WINDOWS_VERSION_H 22 | #define WINPTY_SHARED_WINDOWS_VERSION_H 23 | 24 | bool isAtLeastWindowsVista(); 25 | bool isAtLeastWindows7(); 26 | bool isAtLeastWindows8(); 27 | void dumpWindowsVersion(); 28 | 29 | #endif // WINPTY_SHARED_WINDOWS_VERSION_H 30 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/WindowsVersion.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_WINDOWS_VERSION_H 22 | #define WINPTY_SHARED_WINDOWS_VERSION_H 23 | 24 | bool isAtLeastWindowsVista(); 25 | bool isAtLeastWindows7(); 26 | bool isAtLeastWindows8(); 27 | void dumpWindowsVersion(); 28 | 29 | #endif // WINPTY_SHARED_WINDOWS_VERSION_H 30 | -------------------------------------------------------------------------------- /examples/TerminalExample/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace Upp; 5 | 6 | // This example demonstrates a simple, cross-platform (POSIX/Windows) 7 | // terminal example. 8 | 9 | #ifdef PLATFORM_POSIX 10 | const char *tshell = "SHELL"; 11 | #elif PLATFORM_WIN32 12 | const char *tshell = "ComSpec"; // Alternatively you can use powershell... 13 | #endif 14 | 15 | struct TerminalExample : TopWindow { 16 | TerminalCtrl term; 17 | PtyProcess pty; 18 | 19 | void Run() 20 | { 21 | SetRect(term.GetStdSize()); // 80 x 24 cells (scaled). 22 | Sizeable().Zoomable().CenterScreen().Add(term.SizePos()); 23 | term.WhenBell = [=]() { BeepExclamation(); }; 24 | term.WhenTitle = [=](String s) { Title(s); }; 25 | term.WhenOutput = [=](String s) { pty.Write(s); }; 26 | term.WhenLink = [=](const String& s) { PromptOK(DeQtf(s)); }; 27 | term.WhenResize = [=]() { pty.SetSize(term.GetPageSize()); }; 28 | term.InlineImages().Hyperlinks().WindowOps(); 29 | pty.Start(GetEnv(tshell), Environment(), GetHomeDirectory()); 30 | PtyWaitEvent we; 31 | we.Add(pty, WAIT_READ | WAIT_IS_EXCEPTION); 32 | OpenMain(); 33 | while(IsOpen() && pty.IsRunning()) { 34 | if(we.Wait(10)) 35 | term.WriteUtf8(pty.Get()); 36 | ProcessEvents(); 37 | } 38 | } 39 | }; 40 | 41 | GUI_APP_MAIN 42 | { 43 | TerminalExample().Run(); 44 | } -------------------------------------------------------------------------------- /Terminal/Esc.cpp: -------------------------------------------------------------------------------- 1 | #include "Terminal.h" 2 | 3 | #define LLOG(x) // RLOG("TerminalCtrl (#" << this << "]: " << x) 4 | #define LTIMING(x) // RTIMING(x) 5 | 6 | namespace Upp { 7 | 8 | void TerminalCtrl::ParseEscapeSequences(const VTInStream::Sequence& seq) 9 | { 10 | LLOG(seq); 11 | 12 | if(Convert7BitC1To8BitC1(seq)) // Redirection 13 | return; 14 | 15 | const CbFunction *p = FindFunctionPtr(seq); 16 | if(p) p->c(*this, seq); 17 | } 18 | 19 | bool TerminalCtrl::Convert7BitC1To8BitC1(const VTInStream::Sequence& seq) 20 | { 21 | bool b = IsLevel1() && seq.intermediate[0] == 0; 22 | if(b) { 23 | byte c = seq.opcode + 64; // Try to shift the final byte (opcode) into C1 region. 24 | b = 0x80 <= c && c <= 0x9F; 25 | if(b) ParseControlChars(c); 26 | } 27 | return b; 28 | } 29 | 30 | void TerminalCtrl::VT52MoveCursor() 31 | { 32 | if(int row = parser.Get() - 31; row >= 1 && row <= 24) 33 | page->MoveToLine(row); 34 | if(int col = parser.Get() - 31; col >= 1 && col <= 80) 35 | page->MoveToColumn(col); 36 | } 37 | 38 | void TerminalCtrl::DisplayAlignmentTest() 39 | { 40 | LLOG("Performing display alignment test..."); 41 | 42 | // According to DEC STD-070, DECALN: 43 | // 1) Resets the margins. 44 | // 2) Clears the EOL flag. 45 | // 3) Sets the page origins to 1, 1. 46 | // 3) Resets SGR. 47 | 48 | // The first two steps are covered in the third step. 49 | 50 | DECom(false); 51 | cellattrs.Normal(); 52 | 53 | for(VTLine& line : *page) 54 | for(VTCell& cell : line) { 55 | cell.Reset(); 56 | cell = 'E'; 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /PtyAgent/lib/agent/DebugShowInput.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef AGENT_DEBUG_SHOW_INPUT_H 22 | #define AGENT_DEBUG_SHOW_INPUT_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | std::string controlKeyStatePrefix(DWORD controlKeyState); 29 | std::string mouseEventToString(const MOUSE_EVENT_RECORD &mer); 30 | void debugShowInput(bool enableMouse, bool escapeInput); 31 | 32 | #endif // AGENT_DEBUG_SHOW_INPUT_H 33 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/AgentMsg.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_AGENT_MSG_H 22 | #define WINPTY_SHARED_AGENT_MSG_H 23 | 24 | struct AgentMsg 25 | { 26 | enum Type { 27 | StartProcess, 28 | SetSize, 29 | GetConsoleProcessList, 30 | }; 31 | }; 32 | 33 | enum class StartProcessResult { 34 | CreateProcessFailed, 35 | ProcessCreated, 36 | }; 37 | 38 | #endif // WINPTY_SHARED_AGENT_MSG_H 39 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/AgentMsg.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_AGENT_MSG_H 22 | #define WINPTY_SHARED_AGENT_MSG_H 23 | 24 | struct AgentMsg 25 | { 26 | enum Type { 27 | StartProcess, 28 | SetSize, 29 | GetConsoleProcessList, 30 | }; 31 | }; 32 | 33 | enum class StartProcessResult { 34 | CreateProcessFailed, 35 | ProcessCreated, 36 | }; 37 | 38 | #endif // WINPTY_SHARED_AGENT_MSG_H 39 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/ConsoleInputReencoding.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef AGENT_CONSOLE_INPUT_REENCODING_H 22 | #define AGENT_CONSOLE_INPUT_REENCODING_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include 29 | 30 | void reencodeEscapedKeyPress( 31 | std::vector &records, 32 | uint16_t virtualKey, 33 | uint32_t codePoint, 34 | uint16_t keyState); 35 | 36 | #endif // AGENT_CONSOLE_INPUT_REENCODING_H 37 | -------------------------------------------------------------------------------- /examples/SshTerminalExample/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace Upp; 5 | 6 | String url = "demo:password@test.rebex.net:22"; // A well-known public SSH test server. 7 | 8 | struct SshTerminal : TerminalCtrl, SshShell { 9 | SshTerminal(SshSession& session) : SshShell(session) 10 | { 11 | SshShell::Timeout(Null); 12 | SshShell::ChunkSize(65536); 13 | SshShell::WhenOutput = [=](const void *data, int size) { TerminalCtrl::Write(data, size); }; 14 | TerminalCtrl::WhenOutput = [=](String data) { SshShell::Send(data); }; 15 | TerminalCtrl::WhenResize = [=]() { SshShell::PageSize(TerminalCtrl::GetPageSize()); }; 16 | TerminalCtrl::InlineImages().Hyperlinks().WindowOps(); 17 | } 18 | 19 | void Run(const String& termtype) 20 | { 21 | SshShell::Run(termtype, TerminalCtrl::GetPageSize()); 22 | if(SshShell::IsError()) 23 | ErrorOK(DeQtf(GetErrorDesc())); 24 | } 25 | }; 26 | 27 | struct SshTerminalExample : TopWindow { 28 | void Run() 29 | { 30 | if(!EditTextNotNull(url, "SSH server", "Url")) 31 | return; 32 | SshSession session; 33 | session.WhenWait = [=]{ ProcessEvents(); }; 34 | if(!session.Timeout(10000).Connect(url)) { 35 | ErrorOK(DeQtf(session.GetErrorDesc())); 36 | return; 37 | } 38 | SshTerminal term(session); 39 | SetRect(term.GetStdSize()); // 80 x 24 cells (scaled) 40 | Sizeable().Zoomable().CenterScreen().Add(term.SizePos()); 41 | OpenMain(); 42 | term.Run("xterm"); 43 | } 44 | }; 45 | 46 | GUI_APP_MAIN 47 | { 48 | SshTerminalExample().Run(); 49 | } 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Terminal package for U++ 2 | ------------------------ 3 | 4 | Copyright (c) 2019-2025, İsmail Yılmaz 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /Terminal/Copying: -------------------------------------------------------------------------------- 1 | Terminal package for U++ 2 | ------------------------ 3 | 4 | Copyright (c) 2019-2024, İsmail Yılmaz 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/OwnedHandle.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "OwnedHandle.h" 22 | 23 | #include "DebugClient.h" 24 | #include "WinptyException.h" 25 | 26 | void OwnedHandle::dispose(bool nothrow) { 27 | if (m_h != nullptr && m_h != INVALID_HANDLE_VALUE) { 28 | if (!CloseHandle(m_h)) { 29 | trace("CloseHandle(%p) failed", m_h); 30 | if (!nothrow) { 31 | throwWindowsError(L"CloseHandle failed"); 32 | } 33 | } 34 | } 35 | m_h = nullptr; 36 | } 37 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/OwnedHandle.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "OwnedHandle.h" 22 | 23 | #include "DebugClient.h" 24 | #include "WinptyException.h" 25 | 26 | void OwnedHandle::dispose(bool nothrow) { 27 | if (m_h != nullptr && m_h != INVALID_HANDLE_VALUE) { 28 | if (!CloseHandle(m_h)) { 29 | trace("CloseHandle(%p) failed", m_h); 30 | if (!nothrow) { 31 | throwWindowsError(L"CloseHandle failed"); 32 | } 33 | } 34 | } 35 | m_h = nullptr; 36 | } 37 | -------------------------------------------------------------------------------- /PtyProcess/Copying: -------------------------------------------------------------------------------- 1 | PtyProcess package for Ultimate++ 2 | --------------------------------- 3 | 4 | Copyright (c) 2018-2025, İsmail Yılmaz 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/ConsoleLine.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef CONSOLE_LINE_H 22 | #define CONSOLE_LINE_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | class ConsoleLine 29 | { 30 | public: 31 | ConsoleLine(); 32 | void reset(); 33 | bool detectChangeAndSetLine(const CHAR_INFO *line, int newLength); 34 | void setLine(const CHAR_INFO *line, int newLength); 35 | void blank(WORD attributes); 36 | private: 37 | int m_prevLength; 38 | std::vector m_prevData; 39 | }; 40 | 41 | #endif // CONSOLE_LINE_H 42 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/PrecompiledHeader.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_PRECOMPILED_HEADER_H 22 | #define WINPTY_PRECOMPILED_HEADER_H 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #endif // WINPTY_PRECOMPILED_HEADER_H 44 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/PrecompiledHeader.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_PRECOMPILED_HEADER_H 22 | #define WINPTY_PRECOMPILED_HEADER_H 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #endif // WINPTY_PRECOMPILED_HEADER_H 44 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/EventLoop.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef EVENTLOOP_H 22 | #define EVENTLOOP_H 23 | 24 | #include 25 | 26 | class NamedPipe; 27 | 28 | class EventLoop 29 | { 30 | public: 31 | virtual ~EventLoop(); 32 | void run(); 33 | 34 | protected: 35 | NamedPipe &createNamedPipe(); 36 | void setPollInterval(int ms); 37 | void shutdown(); 38 | virtual void onPollTimeout() {} 39 | virtual void onPipeIo(NamedPipe &namedPipe) {} 40 | 41 | private: 42 | bool m_exiting = false; 43 | std::vector m_pipes; 44 | int m_pollInterval = 0; 45 | }; 46 | 47 | #endif // EVENTLOOP_H 48 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/WinptyException.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_EXCEPTION_H 22 | #define WINPTY_EXCEPTION_H 23 | 24 | #include 25 | 26 | #if defined(__GNUC__) 27 | #define WINPTY_NOEXCEPT noexcept 28 | #elif defined(_MSC_VER) && _MSC_VER >= 1900 29 | #define WINPTY_NOEXCEPT noexcept 30 | #else 31 | #define WINPTY_NOEXCEPT 32 | #endif 33 | 34 | class WinptyException { 35 | public: 36 | virtual const wchar_t *what() const WINPTY_NOEXCEPT = 0; 37 | virtual ~WinptyException() {} 38 | }; 39 | 40 | void throwWinptyException(const wchar_t *what); 41 | void throwWindowsError(const wchar_t *prefix, DWORD error=GetLastError()); 42 | 43 | #endif // WINPTY_EXCEPTION_H 44 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/WinptyException.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_EXCEPTION_H 22 | #define WINPTY_EXCEPTION_H 23 | 24 | #include 25 | 26 | #if defined(__GNUC__) 27 | #define WINPTY_NOEXCEPT noexcept 28 | #elif defined(_MSC_VER) && _MSC_VER >= 1900 29 | #define WINPTY_NOEXCEPT noexcept 30 | #else 31 | #define WINPTY_NOEXCEPT 32 | #endif 33 | 34 | class WinptyException { 35 | public: 36 | virtual const wchar_t *what() const WINPTY_NOEXCEPT = 0; 37 | virtual ~WinptyException() {} 38 | }; 39 | 40 | void throwWinptyException(const wchar_t *what); 41 | void throwWindowsError(const wchar_t *prefix, DWORD error=GetLastError()); 42 | 43 | #endif // WINPTY_EXCEPTION_H 44 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/WinptyVersion.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "WinptyVersion.h" 22 | 23 | #include 24 | #include 25 | 26 | #include "DebugClient.h" 27 | 28 | // This header is auto-generated by either the Makefile (Unix) or 29 | // UpdateGenVersion.bat (gyp). It is placed in a 'gen' directory, which is 30 | // added to the search path. 31 | //#include "GenVersion.h" 32 | 33 | const char GenVersion_Version[] = "Upp::liibwinpty-plugin: ver. 2021.1 (winpty: 0.4.4-dev)"; 34 | 35 | void dumpVersionToStdout() { 36 | printf("winpty version %s\n", GenVersion_Version); 37 | } 38 | 39 | void dumpVersionToTrace() { 40 | trace("winpty version %s", GenVersion_Version); 41 | } 42 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/WinptyVersion.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "WinptyVersion.h" 22 | 23 | #include 24 | #include 25 | 26 | #include "DebugClient.h" 27 | 28 | // This header is auto-generated by either the Makefile (Unix) or 29 | // UpdateGenVersion.bat (gyp). It is placed in a 'gen' directory, which is 30 | // added to the search path. 31 | //#include "GenVersion.h" 32 | 33 | const char GenVersion_Version[] = "Upp::liibwinpty-plugin: ver. 2021.1 (winpty: 0.4.4-dev)"; 34 | 35 | void dumpVersionToStdout() { 36 | printf("winpty version %s\n", GenVersion_Version); 37 | } 38 | 39 | void dumpVersionToTrace() { 40 | trace("winpty version %s", GenVersion_Version); 41 | } 42 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/DebugClient.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef DEBUGCLIENT_H 22 | #define DEBUGCLIENT_H 23 | 24 | #include "winpty_snprintf.h" 25 | 26 | bool isTracingEnabled(); 27 | bool hasDebugFlag(const char *flag); 28 | void trace(const char *format, ...) WINPTY_SNPRINTF_FORMAT(1, 2); 29 | 30 | // This macro calls trace without evaluating the arguments. 31 | #define TRACE(format, ...) \ 32 | do { \ 33 | if (isTracingEnabled()) { \ 34 | trace((format), ## __VA_ARGS__); \ 35 | } \ 36 | } while (false) 37 | 38 | #endif // DEBUGCLIENT_H 39 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/DebugClient.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef DEBUGCLIENT_H 22 | #define DEBUGCLIENT_H 23 | 24 | #include "winpty_snprintf.h" 25 | 26 | bool isTracingEnabled(); 27 | bool hasDebugFlag(const char *flag); 28 | void trace(const char *format, ...) WINPTY_SNPRINTF_FORMAT(1, 2); 29 | 30 | // This macro calls trace without evaluating the arguments. 31 | #define TRACE(format, ...) \ 32 | do { \ 33 | if (isTracingEnabled()) { \ 34 | trace((format), ## __VA_ARGS__); \ 35 | } \ 36 | } while (false) 37 | 38 | #endif // DEBUGCLIENT_H 39 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/OwnedHandle.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_OWNED_HANDLE_H 22 | #define WINPTY_SHARED_OWNED_HANDLE_H 23 | 24 | #include 25 | 26 | class OwnedHandle { 27 | HANDLE m_h; 28 | public: 29 | OwnedHandle() : m_h(nullptr) {} 30 | explicit OwnedHandle(HANDLE h) : m_h(h) {} 31 | ~OwnedHandle() { dispose(true); } 32 | void dispose(bool nothrow=false); 33 | HANDLE get() const { return m_h; } 34 | HANDLE release() { HANDLE ret = m_h; m_h = nullptr; return ret; } 35 | OwnedHandle(const OwnedHandle &other) = delete; 36 | OwnedHandle(OwnedHandle &&other) : m_h(other.release()) {} 37 | OwnedHandle &operator=(const OwnedHandle &other) = delete; 38 | OwnedHandle &operator=(OwnedHandle &&other) { 39 | dispose(); 40 | m_h = other.release(); 41 | return *this; 42 | } 43 | }; 44 | 45 | #endif // WINPTY_SHARED_OWNED_HANDLE_H 46 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/OwnedHandle.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_OWNED_HANDLE_H 22 | #define WINPTY_SHARED_OWNED_HANDLE_H 23 | 24 | #include 25 | 26 | class OwnedHandle { 27 | HANDLE m_h; 28 | public: 29 | OwnedHandle() : m_h(nullptr) {} 30 | explicit OwnedHandle(HANDLE h) : m_h(h) {} 31 | ~OwnedHandle() { dispose(true); } 32 | void dispose(bool nothrow=false); 33 | HANDLE get() const { return m_h; } 34 | HANDLE release() { HANDLE ret = m_h; m_h = nullptr; return ret; } 35 | OwnedHandle(const OwnedHandle &other) = delete; 36 | OwnedHandle(OwnedHandle &&other) : m_h(other.release()) {} 37 | OwnedHandle &operator=(const OwnedHandle &other) = delete; 38 | OwnedHandle &operator=(OwnedHandle &&other) { 39 | dispose(); 40 | m_h = other.release(); 41 | return *this; 42 | } 43 | }; 44 | 45 | #endif // WINPTY_SHARED_OWNED_HANDLE_H 46 | -------------------------------------------------------------------------------- /examples/TerminalLayoutExample/TerminalLayoutExample.h: -------------------------------------------------------------------------------- 1 | #ifndef _TerminalLayoutExample_TerminalLayoutExample_h 2 | #define _TerminalLayoutExample_TerminalLayoutExample_h 3 | 4 | #include 5 | #include 6 | 7 | // This example demonstrates a simple, cross-platform (POSIX/Windows) 8 | // terminal example. 9 | 10 | // On Windows platform PtyProcess class uses statically linked *winpty* 11 | // library and the supplementary PtyAgent pacakges as its *default* pty 12 | // backend. However, it also supports the Windows 10 (tm) pseudoconsole 13 | // API via the WIN10 compiler flag. This flag can be enabled or disable 14 | // easily via TheIDE's main package configuration dialog. (E.g: "GUI WIN10") 15 | 16 | using namespace Upp; 17 | 18 | #define LAYOUTFILE 19 | #include 20 | 21 | class TerminalExample : public WithTerminalExampleLayout { 22 | public: 23 | TerminalExample(); 24 | void Serialize(Stream& s) override; 25 | void Run(); 26 | 27 | private: 28 | enum class WindowOp : int { 29 | FullScreen, 30 | Maximize, 31 | Minimize, 32 | Resize, 33 | Geometry 34 | }; 35 | 36 | void WindowAction(WindowOp action, Value arg = Null); 37 | void MainMenu(Bar& bar); 38 | void FileMenu(Bar& bar); 39 | void ViewMenu(Bar& bar); 40 | void ContextMenu(Bar& bar); 41 | 42 | void FontZoom(int n); 43 | void LineSpacing(int n); 44 | void InsertCodePoint(); 45 | void Screenshot(); 46 | void About(); 47 | 48 | private: 49 | PtyProcess pty; 50 | MenuBar mainmenu; 51 | }; 52 | 53 | // Helper popup for unicode codepoint input. 54 | 55 | class EditCodePoint : public EditString { 56 | public: 57 | EditCodePoint(TerminalExample& t) : app(t) {} 58 | 59 | void PopUp(); 60 | bool Key(dword key, int count) override; 61 | void LostFocus() override; 62 | 63 | private: 64 | TerminalExample& app; 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /PtyAgent/lib/libwinpty/subdir.mk: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2011-2015 Ryan Prichard 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to 5 | # deal in the Software without restriction, including without limitation the 6 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | # sell copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | # IN THE SOFTWARE. 20 | 21 | ALL_TARGETS += build/winpty.dll 22 | 23 | $(eval $(call def_mingw_target,libwinpty,-DCOMPILING_WINPTY_DLL)) 24 | 25 | LIBWINPTY_OBJECTS = \ 26 | build/libwinpty/libwinpty/AgentLocation.o \ 27 | build/libwinpty/libwinpty/winpty.o \ 28 | build/libwinpty/shared/BackgroundDesktop.o \ 29 | build/libwinpty/shared/Buffer.o \ 30 | build/libwinpty/shared/DebugClient.o \ 31 | build/libwinpty/shared/GenRandom.o \ 32 | build/libwinpty/shared/OwnedHandle.o \ 33 | build/libwinpty/shared/StringUtil.o \ 34 | build/libwinpty/shared/WindowsSecurity.o \ 35 | build/libwinpty/shared/WindowsVersion.o \ 36 | build/libwinpty/shared/WinptyAssert.o \ 37 | build/libwinpty/shared/WinptyException.o \ 38 | build/libwinpty/shared/WinptyVersion.o 39 | 40 | build/libwinpty/shared/WinptyVersion.o : build/gen/GenVersion.h 41 | 42 | build/winpty.dll : $(LIBWINPTY_OBJECTS) 43 | $(info Linking $@) 44 | @$(MINGW_CXX) $(MINGW_LDFLAGS) -shared -o $@ $^ -Wl,--out-implib,build/winpty.lib 45 | 46 | -include $(LIBWINPTY_OBJECTS:.o=.d) 47 | -------------------------------------------------------------------------------- /PtyAgent/lib/libwinpty/LibWinptyException.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LIB_WINPTY_EXCEPTION_H 22 | #define LIB_WINPTY_EXCEPTION_H 23 | 24 | #include "../include/winpty.h" 25 | 26 | #include "../shared/WinptyException.h" 27 | 28 | #include 29 | #include 30 | 31 | class LibWinptyException : public WinptyException { 32 | public: 33 | LibWinptyException(winpty_result_t code, const wchar_t *what) : 34 | m_code(code), m_what(std::make_shared(what)) {} 35 | 36 | winpty_result_t code() const WINPTY_NOEXCEPT { 37 | return m_code; 38 | } 39 | 40 | const wchar_t *what() const WINPTY_NOEXCEPT override { 41 | return m_what->c_str(); 42 | } 43 | 44 | std::shared_ptr whatSharedStr() const WINPTY_NOEXCEPT { 45 | return m_what; 46 | } 47 | 48 | private: 49 | winpty_result_t m_code; 50 | // Using a shared_ptr ensures that copying the object raises no exception. 51 | std::shared_ptr m_what; 52 | }; 53 | 54 | #endif // LIB_WINPTY_EXCEPTION_H 55 | -------------------------------------------------------------------------------- /PtyProcess/lib/libwinpty/LibWinptyException.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LIB_WINPTY_EXCEPTION_H 22 | #define LIB_WINPTY_EXCEPTION_H 23 | 24 | #include "../include/winpty.h" 25 | 26 | #include "../shared/WinptyException.h" 27 | 28 | #include 29 | #include 30 | 31 | class LibWinptyException : public WinptyException { 32 | public: 33 | LibWinptyException(winpty_result_t code, const wchar_t *what) : 34 | m_code(code), m_what(std::make_shared(what)) {} 35 | 36 | winpty_result_t code() const WINPTY_NOEXCEPT { 37 | return m_code; 38 | } 39 | 40 | const wchar_t *what() const WINPTY_NOEXCEPT override { 41 | return m_what->c_str(); 42 | } 43 | 44 | std::shared_ptr whatSharedStr() const WINPTY_NOEXCEPT { 45 | return m_what; 46 | } 47 | 48 | private: 49 | winpty_result_t m_code; 50 | // Using a shared_ptr ensures that copying the object raises no exception. 51 | std::shared_ptr m_what; 52 | }; 53 | 54 | #endif // LIB_WINPTY_EXCEPTION_H 55 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/UnixCtrlChars.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef UNIX_CTRL_CHARS_H 22 | #define UNIX_CTRL_CHARS_H 23 | 24 | inline char decodeUnixCtrlChar(char ch) { 25 | const char ctrlKeys[] = { 26 | /* 0x00 */ '@', /* 0x01 */ 'A', /* 0x02 */ 'B', /* 0x03 */ 'C', 27 | /* 0x04 */ 'D', /* 0x05 */ 'E', /* 0x06 */ 'F', /* 0x07 */ 'G', 28 | /* 0x08 */ 'H', /* 0x09 */ 'I', /* 0x0A */ 'J', /* 0x0B */ 'K', 29 | /* 0x0C */ 'L', /* 0x0D */ 'M', /* 0x0E */ 'N', /* 0x0F */ 'O', 30 | /* 0x10 */ 'P', /* 0x11 */ 'Q', /* 0x12 */ 'R', /* 0x13 */ 'S', 31 | /* 0x14 */ 'T', /* 0x15 */ 'U', /* 0x16 */ 'V', /* 0x17 */ 'W', 32 | /* 0x18 */ 'X', /* 0x19 */ 'Y', /* 0x1A */ 'Z', /* 0x1B */ '[', 33 | /* 0x1C */ '\\', /* 0x1D */ ']', /* 0x1E */ '^', /* 0x1F */ '_', 34 | }; 35 | unsigned char uch = ch; 36 | if (uch < 32) { 37 | return ctrlKeys[uch]; 38 | } else if (uch == 127) { 39 | return '?'; 40 | } else { 41 | return '\0'; 42 | } 43 | } 44 | 45 | #endif // UNIX_CTRL_CHARS_H 46 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/UnixCtrlChars.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef UNIX_CTRL_CHARS_H 22 | #define UNIX_CTRL_CHARS_H 23 | 24 | inline char decodeUnixCtrlChar(char ch) { 25 | const char ctrlKeys[] = { 26 | /* 0x00 */ '@', /* 0x01 */ 'A', /* 0x02 */ 'B', /* 0x03 */ 'C', 27 | /* 0x04 */ 'D', /* 0x05 */ 'E', /* 0x06 */ 'F', /* 0x07 */ 'G', 28 | /* 0x08 */ 'H', /* 0x09 */ 'I', /* 0x0A */ 'J', /* 0x0B */ 'K', 29 | /* 0x0C */ 'L', /* 0x0D */ 'M', /* 0x0E */ 'N', /* 0x0F */ 'O', 30 | /* 0x10 */ 'P', /* 0x11 */ 'Q', /* 0x12 */ 'R', /* 0x13 */ 'S', 31 | /* 0x14 */ 'T', /* 0x15 */ 'U', /* 0x16 */ 'V', /* 0x17 */ 'W', 32 | /* 0x18 */ 'X', /* 0x19 */ 'Y', /* 0x1A */ 'Z', /* 0x1B */ '[', 33 | /* 0x1C */ '\\', /* 0x1D */ ']', /* 0x1E */ '^', /* 0x1F */ '_', 34 | }; 35 | unsigned char uch = ch; 36 | if (uch < 32) { 37 | return ctrlKeys[uch]; 38 | } else if (uch == 127) { 39 | return '?'; 40 | } else { 41 | return '\0'; 42 | } 43 | } 44 | 45 | #endif // UNIX_CTRL_CHARS_H 46 | -------------------------------------------------------------------------------- /examples/TerminalInWebBrowserExample/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // This example demonstrates a simple, cross-platform (POSIX/Windows) 6 | // terminal example, running on the U++ Turtle backend.Turtle allows 7 | // U++ GUI applications to run on modern web browsers that support 8 | // HTML-5 canvas and websockets. Turtle can be switched on or off by 9 | // a compile-time flag. 10 | 11 | #ifdef PLATFORM_POSIX 12 | const char *tshell = "SHELL"; 13 | #elif PLATFORM_WIN32 14 | const char *tshell = "ComSpec"; // Alternatively you can use powershell... 15 | #endif 16 | 17 | using namespace Upp; 18 | 19 | struct TerminalExample : TopWindow { 20 | TerminalCtrl term; 21 | PtyProcess pty; // This class is completely optional 22 | 23 | void Run() 24 | { 25 | SetRect(term.GetStdSize()); // 80 x 24 cells (scaled). 26 | Sizeable().Zoomable().CenterScreen().Add(term.SizePos()); 27 | term.WhenBell = [=]() { BeepExclamation(); }; 28 | term.WhenTitle = [=](String s) { Title(s); }; 29 | term.WhenOutput = [=](String s) { pty.Write(s); }; 30 | term.WhenLink = [=](const String& s) { PromptOK(DeQtf(s)); }; 31 | term.WhenResize = [=]() { pty.SetSize(term.GetPageSize()); }; 32 | term.InlineImages().Hyperlinks().WindowOps(); 33 | pty.Start(GetEnv(tshell), Environment(), GetHomeDirectory()); 34 | PtyWaitEvent we; 35 | we.Add(pty, WAIT_READ | WAIT_IS_EXCEPTION); 36 | OpenMain(); 37 | while(IsOpen() && pty.IsRunning()) { 38 | if(we.Wait(10)) 39 | term.WriteUtf8(pty.Get()); 40 | ProcessEvents(); 41 | } 42 | } 43 | }; 44 | 45 | 46 | void AppMainLoop() 47 | { 48 | // "Main" stuff should go in here... 49 | TerminalExample().Run(); 50 | } 51 | 52 | CONSOLE_APP_MAIN 53 | { 54 | 55 | #ifdef _DEBUG 56 | TurtleServer::DebugMode(); 57 | #endif 58 | 59 | // MemoryLimitKb(100000000); // Can aid preventing DDoS attacks. 60 | 61 | TurtleServer guiserver; 62 | guiserver.Host("localhost"); 63 | guiserver.HtmlPort(8888); 64 | guiserver.MaxConnections(15); 65 | RunTurtleGui(guiserver, AppMainLoop); 66 | } -------------------------------------------------------------------------------- /PtyAgent/lib/shared/GenRandom.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_GEN_RANDOM_H 22 | #define WINPTY_GEN_RANDOM_H 23 | 24 | // The original MinGW requires that we include wincrypt.h. With MinGW-w64 and 25 | // MSVC, including windows.h is sufficient. 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include "OsModule.h" 32 | 33 | class GenRandom { 34 | typedef BOOLEAN WINAPI RtlGenRandom_t(PVOID, ULONG); 35 | 36 | OsModule m_advapi32; 37 | RtlGenRandom_t *m_rtlGenRandom = nullptr; 38 | bool m_cryptProvIsValid = false; 39 | HCRYPTPROV m_cryptProv = 0; 40 | 41 | public: 42 | GenRandom(); 43 | ~GenRandom(); 44 | bool fillBuffer(void *buffer, size_t size); 45 | std::string randomBytes(size_t numBytes); 46 | std::wstring randomHexString(size_t numBytes); 47 | std::wstring uniqueName(); 48 | 49 | // Return true if the crypto context was successfully initialized. 50 | bool valid() const { 51 | return m_rtlGenRandom != nullptr || m_cryptProvIsValid; 52 | } 53 | }; 54 | 55 | #endif // WINPTY_GEN_RANDOM_H 56 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/GenRandom.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_GEN_RANDOM_H 22 | #define WINPTY_GEN_RANDOM_H 23 | 24 | // The original MinGW requires that we include wincrypt.h. With MinGW-w64 and 25 | // MSVC, including windows.h is sufficient. 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include "OsModule.h" 32 | 33 | class GenRandom { 34 | typedef BOOLEAN WINAPI RtlGenRandom_t(PVOID, ULONG); 35 | 36 | OsModule m_advapi32; 37 | RtlGenRandom_t *m_rtlGenRandom = nullptr; 38 | bool m_cryptProvIsValid = false; 39 | HCRYPTPROV m_cryptProv = 0; 40 | 41 | public: 42 | GenRandom(); 43 | ~GenRandom(); 44 | bool fillBuffer(void *buffer, size_t size); 45 | std::string randomBytes(size_t numBytes); 46 | std::wstring randomHexString(size_t numBytes); 47 | std::wstring uniqueName(); 48 | 49 | // Return true if the crypto context was successfully initialized. 50 | bool valid() const { 51 | return m_rtlGenRandom != nullptr || m_cryptProvIsValid; 52 | } 53 | }; 54 | 55 | #endif // WINPTY_GEN_RANDOM_H 56 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/StringUtil.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "StringUtil.h" 22 | 23 | #include 24 | 25 | #include "WinptyAssert.h" 26 | 27 | // Workaround. MinGW (from mingw.org) does not have wcsnlen. MinGW-w64 *does* 28 | // have wcsnlen, but use this function for consistency. 29 | size_t winpty_wcsnlen(const wchar_t *s, size_t maxlen) { 30 | ASSERT(s != NULL); 31 | for (size_t i = 0; i < maxlen; ++i) { 32 | if (s[i] == L'\0') { 33 | return i; 34 | } 35 | } 36 | return maxlen; 37 | } 38 | 39 | std::string utf8FromWide(const std::wstring &input) { 40 | int mblen = WideCharToMultiByte( 41 | CP_UTF8, 0, 42 | input.data(), input.size(), 43 | NULL, 0, NULL, NULL); 44 | if (mblen <= 0) { 45 | return std::string(); 46 | } 47 | std::vector tmp(mblen); 48 | int mblen2 = WideCharToMultiByte( 49 | CP_UTF8, 0, 50 | input.data(), input.size(), 51 | tmp.data(), tmp.size(), 52 | NULL, NULL); 53 | ASSERT(mblen2 == mblen); 54 | return std::string(tmp.data(), tmp.size()); 55 | } 56 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/StringUtil.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "StringUtil.h" 22 | 23 | #include 24 | 25 | #include "WinptyAssert.h" 26 | 27 | // Workaround. MinGW (from mingw.org) does not have wcsnlen. MinGW-w64 *does* 28 | // have wcsnlen, but use this function for consistency. 29 | size_t winpty_wcsnlen(const wchar_t *s, size_t maxlen) { 30 | WINPTY_ASSERT(s != NULL); 31 | for (size_t i = 0; i < maxlen; ++i) { 32 | if (s[i] == L'\0') { 33 | return i; 34 | } 35 | } 36 | return maxlen; 37 | } 38 | 39 | std::string utf8FromWide(const std::wstring &input) { 40 | int mblen = WideCharToMultiByte( 41 | CP_UTF8, 0, 42 | input.data(), input.size(), 43 | NULL, 0, NULL, NULL); 44 | if (mblen <= 0) { 45 | return std::string(); 46 | } 47 | std::vector tmp(mblen); 48 | int mblen2 = WideCharToMultiByte( 49 | CP_UTF8, 0, 50 | input.data(), input.size(), 51 | tmp.data(), tmp.size(), 52 | NULL, NULL); 53 | WINPTY_ASSERT(mblen2 == mblen); 54 | return std::string(tmp.data(), tmp.size()); 55 | } 56 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/WinptyAssert.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "WinptyAssert.h" 22 | 23 | #include 24 | #include 25 | 26 | #include "DebugClient.h" 27 | 28 | void assertTrace(const char *file, int line, const char *cond) { 29 | trace("Assertion failed: %s, file %s, line %d", 30 | cond, file, line); 31 | } 32 | 33 | #ifdef WINPTY_AGENT_ASSERT 34 | 35 | void agentShutdown() { 36 | HWND hwnd = GetConsoleWindow(); 37 | if (hwnd != NULL) { 38 | PostMessage(hwnd, WM_CLOSE, 0, 0); 39 | Sleep(30000); 40 | trace("Agent shutdown: WM_CLOSE did not end agent process"); 41 | } else { 42 | trace("Agent shutdown: GetConsoleWindow() is NULL"); 43 | } 44 | // abort() prints a message to the console, and if it is frozen, then the 45 | // process would hang, so instead use exit(). (We shouldn't ever get here, 46 | // though, because the WM_CLOSE message should have ended this process.) 47 | exit(1); 48 | } 49 | 50 | void agentAssertFail(const char *file, int line, const char *cond) { 51 | assertTrace(file, line, cond); 52 | agentShutdown(); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/WinptyException.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "WinptyException.h" 22 | 23 | #include 24 | #include 25 | 26 | #include "StringBuilder.h" 27 | 28 | namespace { 29 | 30 | class ExceptionImpl : public WinptyException { 31 | public: 32 | ExceptionImpl(const wchar_t *what) : 33 | m_what(std::make_shared(what)) {} 34 | virtual const wchar_t *what() const WINPTY_NOEXCEPT override { 35 | return m_what->c_str(); 36 | } 37 | private: 38 | // Using a shared_ptr ensures that copying the object raises no exception. 39 | std::shared_ptr m_what; 40 | }; 41 | 42 | } // anonymous namespace 43 | 44 | void throwWinptyException(const wchar_t *what) { 45 | throw ExceptionImpl(what); 46 | } 47 | 48 | void throwWindowsError(const wchar_t *prefix, DWORD errorCode) { 49 | WStringBuilder sb(64); 50 | if (prefix != nullptr) { 51 | sb << prefix << L": "; 52 | } 53 | // It might make sense to use FormatMessage here, but IIRC, its API is hard 54 | // to figure out. 55 | sb << L"Windows error " << errorCode; 56 | throwWinptyException(sb.c_str()); 57 | } 58 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/WinptyException.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "WinptyException.h" 22 | 23 | #include 24 | #include 25 | 26 | #include "StringBuilder.h" 27 | 28 | namespace { 29 | 30 | class ExceptionImpl : public WinptyException { 31 | public: 32 | ExceptionImpl(const wchar_t *what) : 33 | m_what(std::make_shared(what)) {} 34 | virtual const wchar_t *what() const WINPTY_NOEXCEPT override { 35 | return m_what->c_str(); 36 | } 37 | private: 38 | // Using a shared_ptr ensures that copying the object raises no exception. 39 | std::shared_ptr m_what; 40 | }; 41 | 42 | } // anonymous namespace 43 | 44 | void throwWinptyException(const wchar_t *what) { 45 | throw ExceptionImpl(what); 46 | } 47 | 48 | void throwWindowsError(const wchar_t *prefix, DWORD errorCode) { 49 | WStringBuilder sb(64); 50 | if (prefix != nullptr) { 51 | sb << prefix << L": "; 52 | } 53 | // It might make sense to use FormatMessage here, but IIRC, its API is hard 54 | // to figure out. 55 | sb << L"Windows error " << errorCode; 56 | throwWinptyException(sb.c_str()); 57 | } 58 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/WinptyAssert.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "WinptyAssert.h" 22 | 23 | #include 24 | #include 25 | 26 | #include "DebugClient.h" 27 | 28 | void assertTrace(const char *file, int line, const char *cond) { 29 | trace("Assertion failed: %s, file %s, line %d", 30 | cond, file, line); 31 | } 32 | 33 | #ifdef WINPTY_AGENT_WINPTY_ASSERT 34 | 35 | void agentShutdown() { 36 | HWND hwnd = GetConsoleWindow(); 37 | if (hwnd != NULL) { 38 | PostMessage(hwnd, WM_CLOSE, 0, 0); 39 | Sleep(30000); 40 | trace("Agent shutdown: WM_CLOSE did not end agent process"); 41 | } else { 42 | trace("Agent shutdown: GetConsoleWindow() is NULL"); 43 | } 44 | // abort() prints a message to the console, and if it is frozen, then the 45 | // process would hang, so instead use exit(). (We shouldn't ever get here, 46 | // though, because the WM_CLOSE message should have ended this process.) 47 | exit(1); 48 | } 49 | 50 | void agentAssertFail(const char *file, int line, const char *cond) { 51 | assertTrace(file, line, cond); 52 | agentShutdown(); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/Mutex.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | // Recent 4.x MinGW and MinGW-w64 gcc compilers lack std::mutex and 22 | // std::lock_guard. I have a 5.2.0 MinGW-w64 compiler packaged through MSYS2 23 | // that *is* new enough, but that's one compiler against several deficient 24 | // ones. Wrap CRITICAL_SECTION instead. 25 | 26 | #ifndef WINPTY_SHARED_MUTEX_H 27 | #define WINPTY_SHARED_MUTEX_H 28 | 29 | #include 30 | 31 | class Mutex { 32 | CRITICAL_SECTION m_mutex; 33 | public: 34 | Mutex() { InitializeCriticalSection(&m_mutex); } 35 | ~Mutex() { DeleteCriticalSection(&m_mutex); } 36 | void lock() { EnterCriticalSection(&m_mutex); } 37 | void unlock() { LeaveCriticalSection(&m_mutex); } 38 | 39 | Mutex(const Mutex &other) = delete; 40 | Mutex &operator=(const Mutex &other) = delete; 41 | }; 42 | 43 | template 44 | class LockGuard { 45 | T &m_lock; 46 | public: 47 | LockGuard(T &lock) : m_lock(lock) { m_lock.lock(); } 48 | ~LockGuard() { m_lock.unlock(); } 49 | 50 | LockGuard(const LockGuard &other) = delete; 51 | LockGuard &operator=(const LockGuard &other) = delete; 52 | }; 53 | 54 | #endif // WINPTY_SHARED_MUTEX_H 55 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/Mutex.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | // Recent 4.x MinGW and MinGW-w64 gcc compilers lack std::mutex and 22 | // std::lock_guard. I have a 5.2.0 MinGW-w64 compiler packaged through MSYS2 23 | // that *is* new enough, but that's one compiler against several deficient 24 | // ones. Wrap CRITICAL_SECTION instead. 25 | 26 | #ifndef WINPTY_SHARED_MUTEX_H 27 | #define WINPTY_SHARED_MUTEX_H 28 | 29 | #include 30 | 31 | class Mutex { 32 | CRITICAL_SECTION m_mutex; 33 | public: 34 | Mutex() { InitializeCriticalSection(&m_mutex); } 35 | ~Mutex() { DeleteCriticalSection(&m_mutex); } 36 | void lock() { EnterCriticalSection(&m_mutex); } 37 | void unlock() { LeaveCriticalSection(&m_mutex); } 38 | 39 | Mutex(const Mutex &other) = delete; 40 | Mutex &operator=(const Mutex &other) = delete; 41 | }; 42 | 43 | template 44 | class LockGuard { 45 | T &m_lock; 46 | public: 47 | LockGuard(T &lock) : m_lock(lock) { m_lock.lock(); } 48 | ~LockGuard() { m_lock.unlock(); } 49 | 50 | LockGuard(const LockGuard &other) = delete; 51 | LockGuard &operator=(const LockGuard &other) = delete; 52 | }; 53 | 54 | #endif // WINPTY_SHARED_MUTEX_H 55 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/TimeMeasurement.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | // Convenience header library for using the high-resolution performance counter 22 | // to measure how long some process takes. 23 | 24 | #ifndef TIME_MEASUREMENT_H 25 | #define TIME_MEASUREMENT_H 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | class TimeMeasurement { 32 | public: 33 | TimeMeasurement() { 34 | static double freq = static_cast(getFrequency()); 35 | m_freq = freq; 36 | m_start = value(); 37 | } 38 | 39 | double elapsed() { 40 | uint64_t elapsedTicks = value() - m_start; 41 | return static_cast(elapsedTicks) / m_freq; 42 | } 43 | 44 | private: 45 | uint64_t getFrequency() { 46 | LARGE_INTEGER freq; 47 | BOOL success = QueryPerformanceFrequency(&freq); 48 | assert(success && "QueryPerformanceFrequency failed"); 49 | return freq.QuadPart; 50 | } 51 | 52 | uint64_t value() { 53 | LARGE_INTEGER ret; 54 | BOOL success = QueryPerformanceCounter(&ret); 55 | assert(success && "QueryPerformanceCounter failed"); 56 | return ret.QuadPart; 57 | } 58 | 59 | uint64_t m_start; 60 | double m_freq; 61 | }; 62 | 63 | #endif // TIME_MEASUREMENT_H 64 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/TimeMeasurement.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | // Convenience header library for using the high-resolution performance counter 22 | // to measure how long some process takes. 23 | 24 | #ifndef TIME_MEASUREMENT_H 25 | #define TIME_MEASUREMENT_H 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | class TimeMeasurement { 32 | public: 33 | TimeMeasurement() { 34 | static double freq = static_cast(getFrequency()); 35 | m_freq = freq; 36 | m_start = value(); 37 | } 38 | 39 | double elapsed() { 40 | uint64_t elapsedTicks = value() - m_start; 41 | return static_cast(elapsedTicks) / m_freq; 42 | } 43 | 44 | private: 45 | uint64_t getFrequency() { 46 | LARGE_INTEGER freq; 47 | BOOL success = QueryPerformanceFrequency(&freq); 48 | assert(success && "QueryPerformanceFrequency failed"); 49 | return freq.QuadPart; 50 | } 51 | 52 | uint64_t value() { 53 | LARGE_INTEGER ret; 54 | BOOL success = QueryPerformanceCounter(&ret); 55 | assert(success && "QueryPerformanceCounter failed"); 56 | return ret.QuadPart; 57 | } 58 | 59 | uint64_t m_start; 60 | double m_freq; 61 | }; 62 | 63 | #endif // TIME_MEASUREMENT_H 64 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/OsModule.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_OS_MODULE_H 22 | #define WINPTY_SHARED_OS_MODULE_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "DebugClient.h" 29 | #include "WinptyAssert.h" 30 | #include "WinptyException.h" 31 | 32 | class OsModule { 33 | HMODULE m_module; 34 | public: 35 | enum class LoadErrorBehavior { Abort, Throw }; 36 | OsModule(const wchar_t *fileName, 37 | LoadErrorBehavior behavior=LoadErrorBehavior::Abort) { 38 | m_module = LoadLibraryW(fileName); 39 | if (behavior == LoadErrorBehavior::Abort) { 40 | ASSERT(m_module != NULL); 41 | } else { 42 | if (m_module == nullptr) { 43 | const auto err = GetLastError(); 44 | throwWindowsError( 45 | (L"LoadLibraryW error: " + std::wstring(fileName)).c_str(), 46 | err); 47 | } 48 | } 49 | } 50 | ~OsModule() { 51 | FreeLibrary(m_module); 52 | } 53 | HMODULE handle() const { return m_module; } 54 | FARPROC proc(const char *funcName) { 55 | FARPROC ret = GetProcAddress(m_module, funcName); 56 | if (ret == NULL) { 57 | trace("GetProcAddress: %s is missing", funcName); 58 | } 59 | return ret; 60 | } 61 | }; 62 | 63 | #endif // WINPTY_SHARED_OS_MODULE_H 64 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/Terminal.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef TERMINAL_H 22 | #define TERMINAL_H 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | #include "Coord.h" 31 | 32 | class NamedPipe; 33 | 34 | class Terminal 35 | { 36 | public: 37 | explicit Terminal(NamedPipe &output, bool plainMode, bool outputColor) 38 | : m_output(output), m_plainMode(plainMode), m_outputColor(outputColor) 39 | { 40 | } 41 | 42 | enum SendClearFlag { OmitClear, SendClear }; 43 | void reset(SendClearFlag sendClearFirst, int64_t newLine); 44 | void sendLine(int64_t line, const CHAR_INFO *lineData, int width, 45 | int cursorColumn); 46 | void showTerminalCursor(int column, int64_t line); 47 | void hideTerminalCursor(); 48 | 49 | private: 50 | void moveTerminalToLine(int64_t line); 51 | 52 | public: 53 | void enableMouseMode(bool enabled); 54 | 55 | private: 56 | NamedPipe &m_output; 57 | int64_t m_remoteLine = 0; 58 | int m_remoteColumn = 0; 59 | bool m_lineDataValid = true; 60 | std::vector m_lineData; 61 | bool m_cursorHidden = false; 62 | int m_remoteColor = -1; 63 | std::string m_termLineWorkingBuffer; 64 | bool m_plainMode = false; 65 | bool m_outputColor = true; 66 | bool m_mouseModeEnabled = false; 67 | }; 68 | 69 | #endif // TERMINAL_H 70 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/OsModule.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_OS_MODULE_H 22 | #define WINPTY_SHARED_OS_MODULE_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "DebugClient.h" 29 | #include "WinptyAssert.h" 30 | #include "WinptyException.h" 31 | 32 | class OsModule { 33 | HMODULE m_module; 34 | public: 35 | enum class LoadErrorBehavior { Abort, Throw }; 36 | OsModule(const wchar_t *fileName, 37 | LoadErrorBehavior behavior=LoadErrorBehavior::Abort) { 38 | m_module = LoadLibraryW(fileName); 39 | if (behavior == LoadErrorBehavior::Abort) { 40 | WINPTY_ASSERT(m_module != NULL); 41 | } else { 42 | if (m_module == nullptr) { 43 | const auto err = GetLastError(); 44 | throwWindowsError( 45 | (L"LoadLibraryW error: " + std::wstring(fileName)).c_str(), 46 | err); 47 | } 48 | } 49 | } 50 | ~OsModule() { 51 | FreeLibrary(m_module); 52 | } 53 | HMODULE handle() const { return m_module; } 54 | FARPROC proc(const char *funcName) { 55 | FARPROC ret = GetProcAddress(m_module, funcName); 56 | if (ret == NULL) { 57 | trace("GetProcAddress: %s is missing", funcName); 58 | } 59 | return ret; 60 | } 61 | }; 62 | 63 | #endif // WINPTY_SHARED_OS_MODULE_H 64 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/Coord.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef COORD_H 22 | #define COORD_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "../shared/winpty_snprintf.h" 29 | 30 | struct Coord : COORD { 31 | Coord() 32 | { 33 | X = 0; 34 | Y = 0; 35 | } 36 | 37 | Coord(SHORT x, SHORT y) 38 | { 39 | X = x; 40 | Y = y; 41 | } 42 | 43 | Coord(COORD other) 44 | { 45 | *(COORD*)this = other; 46 | } 47 | 48 | Coord(const Coord &other) 49 | { 50 | *(COORD*)this = *(const COORD*)&other; 51 | } 52 | 53 | Coord &operator=(const Coord &other) 54 | { 55 | *(COORD*)this = *(const COORD*)&other; 56 | return *this; 57 | } 58 | 59 | bool operator==(const Coord &other) const 60 | { 61 | return X == other.X && Y == other.Y; 62 | } 63 | 64 | bool operator!=(const Coord &other) const 65 | { 66 | return !(*this == other); 67 | } 68 | 69 | Coord operator+(const Coord &other) const 70 | { 71 | return Coord(X + other.X, Y + other.Y); 72 | } 73 | 74 | bool isEmpty() const 75 | { 76 | return X <= 0 || Y <= 0; 77 | } 78 | 79 | std::string toString() const 80 | { 81 | char ret[32]; 82 | winpty_snprintf(ret, "(%d,%d)", X, Y); 83 | return std::string(ret); 84 | } 85 | }; 86 | 87 | #endif // COORD_H 88 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/Win32Console.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef AGENT_WIN32_CONSOLE_H 22 | #define AGENT_WIN32_CONSOLE_H 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | class Win32Console 30 | { 31 | public: 32 | class FreezeGuard { 33 | public: 34 | FreezeGuard(Win32Console &console, bool frozen) : 35 | m_console(console), m_previous(console.frozen()) { 36 | m_console.setFrozen(frozen); 37 | } 38 | ~FreezeGuard() { 39 | m_console.setFrozen(m_previous); 40 | } 41 | FreezeGuard(const FreezeGuard &other) = delete; 42 | FreezeGuard &operator=(const FreezeGuard &other) = delete; 43 | private: 44 | Win32Console &m_console; 45 | bool m_previous; 46 | }; 47 | 48 | Win32Console(); 49 | 50 | HWND hwnd() { return m_hwnd; } 51 | std::wstring title(); 52 | void setTitle(const std::wstring &title); 53 | void setFreezeUsesMark(bool useMark) { m_freezeUsesMark = useMark; } 54 | void setNewW10(bool isNewW10) { m_isNewW10 = isNewW10; } 55 | bool isNewW10() { return m_isNewW10; } 56 | void setFrozen(bool frozen=true); 57 | bool frozen() { return m_frozen; } 58 | 59 | private: 60 | HWND m_hwnd = nullptr; 61 | bool m_frozen = false; 62 | bool m_freezeUsesMark = false; 63 | bool m_isNewW10 = false; 64 | std::vector m_titleWorkBuf; 65 | }; 66 | 67 | #endif // AGENT_WIN32_CONSOLE_H 68 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/subdir.mk: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2011-2015 Ryan Prichard 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to 5 | # deal in the Software without restriction, including without limitation the 6 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | # sell copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | # IN THE SOFTWARE. 20 | 21 | ALL_TARGETS += build/winpty-agent.exe 22 | 23 | $(eval $(call def_mingw_target,agent,-DWINPTY_AGENT_ASSERT)) 24 | 25 | AGENT_OBJECTS = \ 26 | build/agent/agent/Agent.o \ 27 | build/agent/agent/AgentCreateDesktop.o \ 28 | build/agent/agent/ConsoleFont.o \ 29 | build/agent/agent/ConsoleInput.o \ 30 | build/agent/agent/ConsoleInputReencoding.o \ 31 | build/agent/agent/ConsoleLine.o \ 32 | build/agent/agent/DebugShowInput.o \ 33 | build/agent/agent/DefaultInputMap.o \ 34 | build/agent/agent/EventLoop.o \ 35 | build/agent/agent/InputMap.o \ 36 | build/agent/agent/LargeConsoleRead.o \ 37 | build/agent/agent/NamedPipe.o \ 38 | build/agent/agent/Scraper.o \ 39 | build/agent/agent/Terminal.o \ 40 | build/agent/agent/Win32Console.o \ 41 | build/agent/agent/Win32ConsoleBuffer.o \ 42 | build/agent/agent/main.o \ 43 | build/agent/shared/BackgroundDesktop.o \ 44 | build/agent/shared/Buffer.o \ 45 | build/agent/shared/DebugClient.o \ 46 | build/agent/shared/GenRandom.o \ 47 | build/agent/shared/OwnedHandle.o \ 48 | build/agent/shared/StringUtil.o \ 49 | build/agent/shared/WindowsSecurity.o \ 50 | build/agent/shared/WindowsVersion.o \ 51 | build/agent/shared/WinptyAssert.o \ 52 | build/agent/shared/WinptyException.o \ 53 | build/agent/shared/WinptyVersion.o 54 | 55 | build/agent/shared/WinptyVersion.o : build/gen/GenVersion.h 56 | 57 | build/winpty-agent.exe : $(AGENT_OBJECTS) 58 | $(info Linking $@) 59 | @$(MINGW_CXX) $(MINGW_LDFLAGS) -o $@ $^ 60 | 61 | -include $(AGENT_OBJECTS:.o=.d) 62 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/SimplePool.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef SIMPLE_POOL_H 22 | #define SIMPLE_POOL_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "../shared/WinptyAssert.h" 29 | 30 | template 31 | class SimplePool { 32 | public: 33 | ~SimplePool(); 34 | T *alloc(); 35 | void clear(); 36 | private: 37 | struct Chunk { 38 | size_t count; 39 | T *data; 40 | }; 41 | std::vector m_chunks; 42 | }; 43 | 44 | template 45 | SimplePool::~SimplePool() { 46 | clear(); 47 | } 48 | 49 | template 50 | void SimplePool::clear() { 51 | for (size_t ci = 0; ci < m_chunks.size(); ++ci) { 52 | Chunk &chunk = m_chunks[ci]; 53 | for (size_t ti = 0; ti < chunk.count; ++ti) { 54 | chunk.data[ti].~T(); 55 | } 56 | free(chunk.data); 57 | } 58 | m_chunks.clear(); 59 | } 60 | 61 | template 62 | T *SimplePool::alloc() { 63 | if (m_chunks.empty() || m_chunks.back().count == chunkSize) { 64 | T *newData = reinterpret_cast(malloc(sizeof(T) * chunkSize)); 65 | ASSERT(newData != NULL); 66 | Chunk newChunk = { 0, newData }; 67 | m_chunks.push_back(newChunk); 68 | } 69 | Chunk &chunk = m_chunks.back(); 70 | T *ret = &chunk.data[chunk.count++]; 71 | new (ret) T(); 72 | return ret; 73 | } 74 | 75 | #endif // SIMPLE_POOL_H 76 | -------------------------------------------------------------------------------- /PtyAgent/lib/libwinpty/WinptyInternal.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LIBWINPTY_WINPTY_INTERNAL_H 22 | #define LIBWINPTY_WINPTY_INTERNAL_H 23 | 24 | #include 25 | #include 26 | 27 | #include "../include/winpty.h" 28 | 29 | #include "../shared/Mutex.h" 30 | #include "../shared/OwnedHandle.h" 31 | 32 | // The structures in this header are not intended to be accessed directly by 33 | // client programs. 34 | 35 | struct winpty_error_s { 36 | winpty_result_t code; 37 | const wchar_t *msgStatic; 38 | // Use a pointer to a std::shared_ptr so that the struct remains simple 39 | // enough to statically initialize, for the benefit of static error 40 | // objects like kOutOfMemory. 41 | std::shared_ptr *msgDynamic; 42 | }; 43 | 44 | struct winpty_config_s { 45 | uint64_t flags = 0; 46 | int cols = 80; 47 | int rows = 25; 48 | int mouseMode = WINPTY_MOUSE_MODE_AUTO; 49 | DWORD timeoutMs = 30000; 50 | }; 51 | 52 | struct winpty_s { 53 | Mutex mutex; 54 | OwnedHandle agentProcess; 55 | OwnedHandle controlPipe; 56 | DWORD agentTimeoutMs = 0; 57 | OwnedHandle ioEvent; 58 | std::wstring spawnDesktopName; 59 | std::wstring coninPipeName; 60 | std::wstring conoutPipeName; 61 | std::wstring conerrPipeName; 62 | }; 63 | 64 | struct winpty_spawn_config_s { 65 | uint64_t winptyFlags = 0; 66 | std::wstring appname; 67 | std::wstring cmdline; 68 | std::wstring cwd; 69 | std::wstring env; 70 | }; 71 | 72 | #endif // LIBWINPTY_WINPTY_INTERNAL_H 73 | -------------------------------------------------------------------------------- /PtyProcess/lib/libwinpty/WinptyInternal.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LIBWINPTY_WINPTY_INTERNAL_H 22 | #define LIBWINPTY_WINPTY_INTERNAL_H 23 | 24 | #include 25 | #include 26 | 27 | #include "../include/winpty.h" 28 | 29 | #include "../shared/Mutex.h" 30 | #include "../shared/OwnedHandle.h" 31 | 32 | // The structures in this header are not intended to be accessed directly by 33 | // client programs. 34 | 35 | struct winpty_error_s { 36 | winpty_result_t code; 37 | const wchar_t *msgStatic; 38 | // Use a pointer to a std::shared_ptr so that the struct remains simple 39 | // enough to statically initialize, for the benefit of static error 40 | // objects like kOutOfMemory. 41 | std::shared_ptr *msgDynamic; 42 | }; 43 | 44 | struct winpty_config_s { 45 | uint64_t flags = 0; 46 | int cols = 80; 47 | int rows = 25; 48 | int mouseMode = WINPTY_MOUSE_MODE_AUTO; 49 | DWORD timeoutMs = 30000; 50 | }; 51 | 52 | struct winpty_s { 53 | Mutex mutex; 54 | OwnedHandle agentProcess; 55 | OwnedHandle controlPipe; 56 | DWORD agentTimeoutMs = 0; 57 | OwnedHandle ioEvent; 58 | std::wstring spawnDesktopName; 59 | std::wstring coninPipeName; 60 | std::wstring conoutPipeName; 61 | std::wstring conerrPipeName; 62 | }; 63 | 64 | struct winpty_spawn_config_s { 65 | uint64_t winptyFlags = 0; 66 | std::wstring appname; 67 | std::wstring cmdline; 68 | std::wstring cwd; 69 | std::wstring env; 70 | }; 71 | 72 | #endif // LIBWINPTY_WINPTY_INTERNAL_H 73 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/LargeConsoleRead.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef LARGE_CONSOLE_READ_H 22 | #define LARGE_CONSOLE_READ_H 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "SmallRect.h" 30 | #include "../shared/DebugClient.h" 31 | #include "../shared/WinptyAssert.h" 32 | 33 | class Win32ConsoleBuffer; 34 | 35 | class LargeConsoleReadBuffer { 36 | public: 37 | LargeConsoleReadBuffer(); 38 | const SmallRect &rect() const { return m_rect; } 39 | const CHAR_INFO *lineData(int line) const { 40 | validateLineNumber(line); 41 | return &m_data[(line - m_rect.Top) * m_rectWidth]; 42 | } 43 | 44 | private: 45 | CHAR_INFO *lineDataMut(int line) { 46 | validateLineNumber(line); 47 | return &m_data[(line - m_rect.Top) * m_rectWidth]; 48 | } 49 | 50 | void validateLineNumber(int line) const { 51 | if (line < m_rect.Top || line > m_rect.Bottom) { 52 | trace("Fatal error: LargeConsoleReadBuffer: invalid line %d for " 53 | "read rect %s", line, m_rect.toString().c_str()); 54 | abort(); 55 | } 56 | } 57 | 58 | SmallRect m_rect; 59 | int m_rectWidth; 60 | std::vector m_data; 61 | 62 | friend void largeConsoleRead(LargeConsoleReadBuffer &out, 63 | Win32ConsoleBuffer &buffer, 64 | const SmallRect &readArea, 65 | WORD attributesMask); 66 | }; 67 | 68 | #endif // LARGE_CONSOLE_READ_H 69 | -------------------------------------------------------------------------------- /PtyAgent/lib/libwinpty/AgentLocation.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "AgentLocation.h" 22 | 23 | #include 24 | 25 | #include 26 | 27 | #include "../shared/WinptyAssert.h" 28 | 29 | #include "LibWinptyException.h" 30 | 31 | #define AGENT_EXE L"winpty-agent.exe" 32 | 33 | static HMODULE getCurrentModule() { 34 | HMODULE module; 35 | if (!GetModuleHandleExW( 36 | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 37 | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 38 | reinterpret_cast(getCurrentModule), 39 | &module)) { 40 | ASSERT(false && "GetModuleHandleEx failed"); 41 | } 42 | return module; 43 | } 44 | 45 | static std::wstring getModuleFileName(HMODULE module) { 46 | const int bufsize = 4096; 47 | wchar_t path[bufsize]; 48 | int size = GetModuleFileNameW(module, path, bufsize); 49 | ASSERT(size != 0 && size != bufsize); 50 | return std::wstring(path); 51 | } 52 | 53 | static std::wstring dirname(const std::wstring &path) { 54 | std::wstring::size_type pos = path.find_last_of(L"\\/"); 55 | if (pos == std::wstring::npos) { 56 | return L""; 57 | } else { 58 | return path.substr(0, pos); 59 | } 60 | } 61 | 62 | static bool pathExists(const std::wstring &path) { 63 | return GetFileAttributesW(path.c_str()) != 0xFFFFFFFF; 64 | } 65 | 66 | std::wstring findAgentProgram() { 67 | std::wstring progDir = dirname(getModuleFileName(getCurrentModule())); 68 | std::wstring ret = progDir + (L"\\" AGENT_EXE); 69 | if (!pathExists(ret)) { 70 | throw LibWinptyException( 71 | WINPTY_ERROR_AGENT_EXE_MISSING, 72 | (L"agent executable does not exist: '" + ret + L"'").c_str()); 73 | } 74 | return ret; 75 | } 76 | -------------------------------------------------------------------------------- /PtyProcess/lib/libwinpty/AgentLocation.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "AgentLocation.h" 22 | 23 | #include 24 | 25 | #include 26 | 27 | #include "../shared/WinptyAssert.h" 28 | 29 | #include "LibWinptyException.h" 30 | 31 | #ifndef AGENT_EXE 32 | #define AGENT_EXE L"winpty-agent.exe" 33 | #endif 34 | 35 | static HMODULE getCurrentModule() { 36 | HMODULE module; 37 | if (!GetModuleHandleExW( 38 | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 39 | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 40 | reinterpret_cast(getCurrentModule), 41 | &module)) { 42 | WINPTY_ASSERT(false && "GetModuleHandleEx failed"); 43 | } 44 | return module; 45 | } 46 | 47 | static std::wstring getModuleFileName(HMODULE module) { 48 | const int bufsize = 4096; 49 | wchar_t path[bufsize]; 50 | int size = GetModuleFileNameW(module, path, bufsize); 51 | WINPTY_ASSERT(size != 0 && size != bufsize); 52 | return std::wstring(path); 53 | } 54 | 55 | static std::wstring dirname(const std::wstring &path) { 56 | std::wstring::size_type pos = path.find_last_of(L"\\/"); 57 | if (pos == std::wstring::npos) { 58 | return L""; 59 | } else { 60 | return path.substr(0, pos); 61 | } 62 | } 63 | 64 | static bool pathExists(const std::wstring &path) { 65 | return GetFileAttributesW(path.c_str()) != 0xFFFFFFFF; 66 | } 67 | 68 | std::wstring findAgentProgram() { 69 | std::wstring progDir = dirname(getModuleFileName(getCurrentModule())); 70 | std::wstring ret = progDir + (L"\\" AGENT_EXE); 71 | if (!pathExists(ret)) { 72 | throw LibWinptyException( 73 | WINPTY_ERROR_AGENT_EXE_MISSING, 74 | (L"agent executable does not exist: '" + ret + L"'").c_str()); 75 | } 76 | return ret; 77 | } 78 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/StringUtil.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_STRING_UTIL_H 22 | #define WINPTY_SHARED_STRING_UTIL_H 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include "WinptyAssert.h" 33 | 34 | size_t winpty_wcsnlen(const wchar_t *s, size_t maxlen); 35 | std::string utf8FromWide(const std::wstring &input); 36 | 37 | // Return a vector containing each character in the string. 38 | template 39 | std::vector vectorFromString(const std::basic_string &str) { 40 | return std::vector(str.begin(), str.end()); 41 | } 42 | 43 | // Return a vector containing each character in the string, followed by a 44 | // NUL terminator. 45 | template 46 | std::vector vectorWithNulFromString(const std::basic_string &str) { 47 | std::vector ret; 48 | ret.reserve(str.size() + 1); 49 | ret.insert(ret.begin(), str.begin(), str.end()); 50 | ret.push_back('\0'); 51 | return ret; 52 | } 53 | 54 | // A safer(?) version of wcsncpy that is accepted by MSVC's /SDL mode. 55 | template 56 | wchar_t *winpty_wcsncpy(wchar_t (&d)[N], const wchar_t *s) { 57 | ASSERT(s != nullptr); 58 | size_t i = 0; 59 | for (; i < N; ++i) { 60 | if (s[i] == L'\0') { 61 | break; 62 | } 63 | d[i] = s[i]; 64 | } 65 | for (; i < N; ++i) { 66 | d[i] = L'\0'; 67 | } 68 | return d; 69 | } 70 | 71 | // Like wcsncpy, but ensure that the destination buffer is NUL-terminated. 72 | template 73 | wchar_t *winpty_wcsncpy_nul(wchar_t (&d)[N], const wchar_t *s) { 74 | static_assert(N > 0, "array cannot be 0-size"); 75 | winpty_wcsncpy(d, s); 76 | d[N - 1] = L'\0'; 77 | return d; 78 | } 79 | 80 | #endif // WINPTY_SHARED_STRING_UTIL_H 81 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/StringUtil.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_STRING_UTIL_H 22 | #define WINPTY_SHARED_STRING_UTIL_H 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include "WinptyAssert.h" 33 | 34 | size_t winpty_wcsnlen(const wchar_t *s, size_t maxlen); 35 | std::string utf8FromWide(const std::wstring &input); 36 | 37 | // Return a vector containing each character in the string. 38 | template 39 | std::vector vectorFromString(const std::basic_string &str) { 40 | return std::vector(str.begin(), str.end()); 41 | } 42 | 43 | // Return a vector containing each character in the string, followed by a 44 | // NUL terminator. 45 | template 46 | std::vector vectorWithNulFromString(const std::basic_string &str) { 47 | std::vector ret; 48 | ret.reserve(str.size() + 1); 49 | ret.insert(ret.begin(), str.begin(), str.end()); 50 | ret.push_back('\0'); 51 | return ret; 52 | } 53 | 54 | // A safer(?) version of wcsncpy that is accepted by MSVC's /SDL mode. 55 | template 56 | wchar_t *winpty_wcsncpy(wchar_t (&d)[N], const wchar_t *s) { 57 | WINPTY_ASSERT(s != nullptr); 58 | size_t i = 0; 59 | for (; i < N; ++i) { 60 | if (s[i] == L'\0') { 61 | break; 62 | } 63 | d[i] = s[i]; 64 | } 65 | for (; i < N; ++i) { 66 | d[i] = L'\0'; 67 | } 68 | return d; 69 | } 70 | 71 | // Like wcsncpy, but ensure that the destination buffer is NUL-terminated. 72 | template 73 | wchar_t *winpty_wcsncpy_nul(wchar_t (&d)[N], const wchar_t *s) { 74 | static_assert(N > 0, "array cannot be 0-size"); 75 | winpty_wcsncpy(d, s); 76 | d[N - 1] = L'\0'; 77 | return d; 78 | } 79 | 80 | #endif // WINPTY_SHARED_STRING_UTIL_H 81 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/LargeConsoleRead.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "LargeConsoleRead.h" 22 | 23 | #include 24 | 25 | #include "../shared/WindowsVersion.h" 26 | #include "Scraper.h" 27 | #include "Win32ConsoleBuffer.h" 28 | 29 | LargeConsoleReadBuffer::LargeConsoleReadBuffer() : 30 | m_rect(0, 0, 0, 0), m_rectWidth(0) 31 | { 32 | } 33 | 34 | void largeConsoleRead(LargeConsoleReadBuffer &out, 35 | Win32ConsoleBuffer &buffer, 36 | const SmallRect &readArea, 37 | WORD attributesMask) { 38 | ASSERT(readArea.Left >= 0 && 39 | readArea.Top >= 0 && 40 | readArea.Right >= readArea.Left && 41 | readArea.Bottom >= readArea.Top && 42 | readArea.width() <= MAX_CONSOLE_WIDTH); 43 | const size_t count = readArea.width() * readArea.height(); 44 | if (out.m_data.size() < count) { 45 | out.m_data.resize(count); 46 | } 47 | out.m_rect = readArea; 48 | out.m_rectWidth = readArea.width(); 49 | 50 | static const bool useLargeReads = isAtLeastWindows8(); 51 | if (useLargeReads) { 52 | buffer.read(readArea, out.m_data.data()); 53 | } else { 54 | const int maxReadLines = std::max(1, MAX_CONSOLE_WIDTH / readArea.width()); 55 | int curLine = readArea.Top; 56 | while (curLine <= readArea.Bottom) { 57 | const SmallRect subReadArea( 58 | readArea.Left, 59 | curLine, 60 | readArea.width(), 61 | std::min(maxReadLines, readArea.Bottom + 1 - curLine)); 62 | buffer.read(subReadArea, out.lineDataMut(curLine)); 63 | curLine = subReadArea.Bottom + 1; 64 | } 65 | } 66 | if (attributesMask != static_cast(~0)) { 67 | for (size_t i = 0; i < count; ++i) { 68 | out.m_data[i].Attributes &= attributesMask; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/AgentCreateDesktop.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "AgentCreateDesktop.h" 22 | 23 | #include "../shared/BackgroundDesktop.h" 24 | #include "../shared/Buffer.h" 25 | #include "../shared/DebugClient.h" 26 | #include "../shared/StringUtil.h" 27 | 28 | #include "EventLoop.h" 29 | #include "NamedPipe.h" 30 | 31 | namespace { 32 | 33 | static inline WriteBuffer newPacket() { 34 | WriteBuffer packet; 35 | packet.putRawValue(0); // Reserve space for size. 36 | return packet; 37 | } 38 | 39 | class CreateDesktopLoop : public EventLoop { 40 | public: 41 | CreateDesktopLoop(LPCWSTR controlPipeName); 42 | 43 | protected: 44 | virtual void onPipeIo(NamedPipe &namedPipe) override; 45 | 46 | private: 47 | void writePacket(WriteBuffer &packet); 48 | 49 | BackgroundDesktop m_desktop; 50 | NamedPipe &m_pipe; 51 | }; 52 | 53 | CreateDesktopLoop::CreateDesktopLoop(LPCWSTR controlPipeName) : 54 | m_pipe(createNamedPipe()) { 55 | m_pipe.connectToServer(controlPipeName, NamedPipe::OpenMode::Duplex); 56 | auto packet = newPacket(); 57 | packet.putWString(m_desktop.desktopName()); 58 | writePacket(packet); 59 | } 60 | 61 | void CreateDesktopLoop::writePacket(WriteBuffer &packet) { 62 | const auto &bytes = packet.buf(); 63 | packet.replaceRawValue(0, bytes.size()); 64 | m_pipe.write(bytes.data(), bytes.size()); 65 | } 66 | 67 | void CreateDesktopLoop::onPipeIo(NamedPipe &namedPipe) { 68 | if (m_pipe.isClosed()) { 69 | shutdown(); 70 | } 71 | } 72 | 73 | } // anonymous namespace 74 | 75 | void handleCreateDesktop(LPCWSTR controlPipeName) { 76 | try { 77 | CreateDesktopLoop loop(controlPipeName); 78 | loop.run(); 79 | trace("Agent exiting..."); 80 | } catch (const WinptyException &e) { 81 | trace("handleCreateDesktop: internal error: %s", 82 | utf8FromWide(e.what()).c_str()); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/WinptyAssert.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_ASSERT_H 22 | #define WINPTY_ASSERT_H 23 | 24 | #ifdef WINPTY_AGENT_ASSERT 25 | 26 | void agentShutdown(); 27 | void agentAssertFail(const char *file, int line, const char *cond); 28 | 29 | // Calling the standard assert() function does not work in the agent because 30 | // the error message would be printed to the console, and the only way the 31 | // user can see the console is via a working agent! Moreover, the console may 32 | // be frozen, so attempting to write to it would block forever. This custom 33 | // assert function instead sends the message to the DebugServer, then attempts 34 | // to close the console, then quietly exits. 35 | #define ASSERT(cond) \ 36 | do { \ 37 | if (!(cond)) { \ 38 | agentAssertFail(__FILE__, __LINE__, #cond); \ 39 | } \ 40 | } while(0) 41 | 42 | #else 43 | 44 | void assertTrace(const char *file, int line, const char *cond); 45 | 46 | // In the other targets, log the assert failure to the debugserver, then fail 47 | // using the ordinary assert mechanism. In case assert is compiled out, fail 48 | // using abort. The amount of code inlined is unfortunate, but asserts aren't 49 | // used much outside the agent. 50 | #include 51 | #include 52 | #define ASSERT_CONDITION(cond) (false && (cond)) 53 | #define ASSERT(cond) \ 54 | do { \ 55 | if (!(cond)) { \ 56 | assertTrace(__FILE__, __LINE__, #cond); \ 57 | assert(ASSERT_CONDITION(#cond)); \ 58 | abort(); \ 59 | } \ 60 | } while(0) 61 | 62 | #endif 63 | 64 | #endif // WINPTY_ASSERT_H 65 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/WinptyAssert.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_ASSERT_H 22 | #define WINPTY_ASSERT_H 23 | 24 | #ifdef WINPTY_AGENT_WINPTY_ASSERT 25 | 26 | void agentShutdown(); 27 | void agentAssertFail(const char *file, int line, const char *cond); 28 | 29 | // Calling the standard assert() function does not work in the agent because 30 | // the error message would be printed to the console, and the only way the 31 | // user can see the console is via a working agent! Moreover, the console may 32 | // be frozen, so attempting to write to it would block forever. This custom 33 | // assert function instead sends the message to the DebugServer, then attempts 34 | // to close the console, then quietly exits. 35 | #define WINPTY_ASSERT(cond) \ 36 | do { \ 37 | if (!(cond)) { \ 38 | agentAssertFail(__FILE__, __LINE__, #cond); \ 39 | } \ 40 | } while(0) 41 | 42 | #else 43 | 44 | void assertTrace(const char *file, int line, const char *cond); 45 | 46 | // In the other targets, log the assert failure to the debugserver, then fail 47 | // using the ordinary assert mechanism. In case assert is compiled out, fail 48 | // using abort. The amount of code inlined is unfortunate, but asserts aren't 49 | // used much outside the agent. 50 | #include 51 | #include 52 | #define WINPTY_ASSERT_CONDITION(cond) (false && (cond)) 53 | #define WINPTY_ASSERT(cond) \ 54 | do { \ 55 | if (!(cond)) { \ 56 | assertTrace(__FILE__, __LINE__, #cond); \ 57 | assert(WINPTY_ASSERT_CONDITION(#cond)); \ 58 | abort(); \ 59 | } \ 60 | } while(0) 61 | 62 | #endif 63 | 64 | #endif // WINPTY_ASSERT_H 65 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/BackgroundDesktop.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_BACKGROUND_DESKTOP_H 22 | #define WINPTY_SHARED_BACKGROUND_DESKTOP_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "WinptyException.h" 29 | 30 | class BackgroundDesktop { 31 | public: 32 | BackgroundDesktop(); 33 | ~BackgroundDesktop() { dispose(); } 34 | void dispose() WINPTY_NOEXCEPT; 35 | const std::wstring &desktopName() const { return m_newDesktopName; } 36 | 37 | BackgroundDesktop(const BackgroundDesktop &other) = delete; 38 | BackgroundDesktop &operator=(const BackgroundDesktop &other) = delete; 39 | 40 | // We can't default the move constructor and assignment operator with 41 | // MSVC 2013. We *could* if we required at least MSVC 2015 to build. 42 | 43 | BackgroundDesktop(BackgroundDesktop &&other) : 44 | m_originalStation(other.m_originalStation), 45 | m_newStation(other.m_newStation), 46 | m_newDesktop(other.m_newDesktop), 47 | m_newDesktopName(std::move(other.m_newDesktopName)) { 48 | other.m_originalStation = nullptr; 49 | other.m_newStation = nullptr; 50 | other.m_newDesktop = nullptr; 51 | } 52 | BackgroundDesktop &operator=(BackgroundDesktop &&other) { 53 | dispose(); 54 | m_originalStation = other.m_originalStation; 55 | m_newStation = other.m_newStation; 56 | m_newDesktop = other.m_newDesktop; 57 | m_newDesktopName = std::move(other.m_newDesktopName); 58 | other.m_originalStation = nullptr; 59 | other.m_newStation = nullptr; 60 | other.m_newDesktop = nullptr; 61 | return *this; 62 | } 63 | 64 | private: 65 | HWINSTA m_originalStation = nullptr; 66 | HWINSTA m_newStation = nullptr; 67 | HDESK m_newDesktop = nullptr; 68 | std::wstring m_newDesktopName; 69 | }; 70 | 71 | std::wstring getCurrentDesktopName(); 72 | 73 | #endif // WINPTY_SHARED_BACKGROUND_DESKTOP_H 74 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/BackgroundDesktop.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_BACKGROUND_DESKTOP_H 22 | #define WINPTY_SHARED_BACKGROUND_DESKTOP_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "WinptyException.h" 29 | 30 | class BackgroundDesktop { 31 | public: 32 | BackgroundDesktop(); 33 | ~BackgroundDesktop() { dispose(); } 34 | void dispose() WINPTY_NOEXCEPT; 35 | const std::wstring &desktopName() const { return m_newDesktopName; } 36 | 37 | BackgroundDesktop(const BackgroundDesktop &other) = delete; 38 | BackgroundDesktop &operator=(const BackgroundDesktop &other) = delete; 39 | 40 | // We can't default the move constructor and assignment operator with 41 | // MSVC 2013. We *could* if we required at least MSVC 2015 to build. 42 | 43 | BackgroundDesktop(BackgroundDesktop &&other) : 44 | m_originalStation(other.m_originalStation), 45 | m_newStation(other.m_newStation), 46 | m_newDesktop(other.m_newDesktop), 47 | m_newDesktopName(std::move(other.m_newDesktopName)) { 48 | other.m_originalStation = nullptr; 49 | other.m_newStation = nullptr; 50 | other.m_newDesktop = nullptr; 51 | } 52 | BackgroundDesktop &operator=(BackgroundDesktop &&other) { 53 | dispose(); 54 | m_originalStation = other.m_originalStation; 55 | m_newStation = other.m_newStation; 56 | m_newDesktop = other.m_newDesktop; 57 | m_newDesktopName = std::move(other.m_newDesktopName); 58 | other.m_originalStation = nullptr; 59 | other.m_newStation = nullptr; 60 | other.m_newDesktop = nullptr; 61 | return *this; 62 | } 63 | 64 | private: 65 | HWINSTA m_originalStation = nullptr; 66 | HWINSTA m_newStation = nullptr; 67 | HDESK m_newDesktop = nullptr; 68 | std::wstring m_newDesktopName; 69 | }; 70 | 71 | std::wstring getCurrentDesktopName(); 72 | 73 | #endif // WINPTY_SHARED_BACKGROUND_DESKTOP_H 74 | -------------------------------------------------------------------------------- /PtyProcess/src.tpp/Upp_PtyWaitEvent_en-us.tpp: -------------------------------------------------------------------------------- 1 | topic "PtyWaitEvent"; 2 | [i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class] 3 | [l288;2 $$2,2#27521748481378242620020725143825:desc] 4 | [0 $$3,0#96390100711032703541132217272105:end] 5 | [H6;0 $$4,0#05600065144404261032431302351956:begin] 6 | [i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item] 7 | [l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement] 8 | [l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param] 9 | [i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam] 10 | [b42;2 $$9,9#13035079074754324216151401829390:normal] 11 | [2 $$0,0#00000000000000000000000000000000:Default] 12 | [{_} 13 | [ {{10000@(113.42.0) [s0;%% [*@7;4 PtyWaitEvent]]}}&] 14 | [s0; &] 15 | [s1;:Upp`:`:PtyWaitEvent: [@(0.0.255)3 class][3 _][*3 PtyWaitEvent]&] 16 | [s2;%% This class provides a mechanism for waiting on multiple pseudoterminal 17 | (pty) processes to become ready for I/O operations. On windows 18 | it uses I/O Completion Ports (IOCP) to wait for events on process 19 | and pipe handles. On POSIX`-compliant operating systems it uses 20 | the poll() system call to wait for events on pty/file descriptors.&] 21 | [s0;i448;a25;kKO9;:noref:@(0.0.255) &] 22 | [ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&] 23 | [s3; &] 24 | [s5;:Upp`:`:PtyWaitEvent`:`:Clear`(`): [@(0.0.255) void] [* Clear]()&] 25 | [s2;%% Removes all processes from the wait list.&] 26 | [s3; &] 27 | [s4; &] 28 | [s5;:Upp`:`:PtyWaitEvent`:`:Add`(const APtyProcess`&`,dword`): [@(0.0.255) void] 29 | [* Add]([@(0.0.255) const] APtyProcess[@(0.0.255) `&] [*@3 pty], dword 30 | [*@3 events])&] 31 | [s2;%% Adds a [%-*@3 pty] process to the wait set with specified events 32 | to monitor. Events can be WAIT`_READ, WAIT`_WRITE, WAIT`_IS`_EXCEPTION, 33 | or a combination of them.&] 34 | [s3; &] 35 | [s4; &] 36 | [s5;:Upp`:`:PtyWaitEvent`:`:Remove`(const APtyProcess`&`): [@(0.0.255) void] 37 | [* Remove]([@(0.0.255) const ]APtyProcess[@(0.0.255) `&] [*@3 pty])&] 38 | [s2;%% Removes the given [%-*@3 pty] process from the wait list.&] 39 | [s3; &] 40 | [s4; &] 41 | [s5;:Upp`:`:PtyWaitEvent`:`:Wait`(int`): [@(0.0.255) bool] [* Wait]([@(0.0.255) int] 42 | [*@3 timeout])&] 43 | [s2;%% Waits for any of the monitored processes to become ready for 44 | the specified events. Returns true if at least one process has 45 | a pending event, false if timeout occurred with no events.&] 46 | [s3; &] 47 | [s4; &] 48 | [s5;:Upp`:`:PtyWaitEvent`:`:Get`(int`)const: [@8 dword ][* Get]([@(0.0.255) int] 49 | [*@3 i]) [@(0.0.255) const]&] 50 | [s5;:Upp`:`:PtyWaitEvent`:`:operator`[`]`(int`)const: [@8 dword] operator[@(0.0.255) `[`] 51 | ]([@(0.0.255) int] [*@3 i]) [@(0.0.255) const]&] 52 | [s0;l288;%% Returns events that triggered for pty process at index 53 | [%-*@3 i] (indicies are specified by order of Add calls) as binary 54 | or of WAIT`_READ, WAIT`_WRITE, WAIT`_IS`_EXCEPTION. If there 55 | were no events for requested pty, returns 0.&] 56 | [s3; &] 57 | [ {{10000F(128)G(128)@1 [s0;%% [* Constructor detail]]}}&] 58 | [s3; &] 59 | [s5;:Upp`:`:PtyWaitEvent`:`:PtyWaitEvent`(`): [* PtyWaitEvent]()&] 60 | [s2;%% Default constructor.&] 61 | [s3; ]] -------------------------------------------------------------------------------- /examples/SshTerminalSplitterExample/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // This example demonstrates a multithreaded ssh terminal splitter 5 | // It is using the Core/SSH package, therefore it can be compiled 6 | // for, and run on, Windows and POSIX-compliant operating systems. 7 | 8 | using namespace Upp; 9 | 10 | String url = "demo:password@test.rebex.net:22"; // A well-known public SSH test server. 11 | 12 | const int MAXPANECOUNT = 4; // You can increase the number of panes if you like. 13 | 14 | struct SshTerminalPane : TerminalCtrl, SshShell { 15 | Splitter& parent; 16 | SshTerminalPane(SshSession& session, Splitter& ctrl) : SshShell(session), parent(ctrl) 17 | { 18 | SshShell::Timeout(Null); 19 | SshShell::ChunkSize(65536); 20 | SshShell::WhenOutput = [=](const void *data, int size) { GuiLock __; TerminalCtrl::Write(data, size);}; 21 | SshShell::WhenWait = [=]() { if(CoWork::IsCanceled()) SshShell::Abort(); }; 22 | TerminalCtrl::WhenOutput = [=](String data) { SshShell::Send(data); }; 23 | TerminalCtrl::WhenResize = [=]() { SshShell::PageSize(TerminalCtrl::GetPageSize()); }; 24 | TerminalCtrl::InlineImages().Hyperlinks().WindowOps(); 25 | parent.Add(TerminalCtrl::SizePos()); 26 | } 27 | 28 | void Run(const String& termtype) 29 | { 30 | SshShell::Run(termtype, TerminalCtrl::GetPageSize()); 31 | GuiLock __; 32 | parent.Remove(*this); 33 | parent.Layout(); 34 | } 35 | 36 | bool Key(dword key, int count) override 37 | { 38 | // Let the parent handle the SHIFT + CTRL + T key. 39 | return key != K_SHIFT_CTRL_T ? TerminalCtrl::Key(key, count) : false; 40 | } 41 | }; 42 | 43 | struct SshTerminalSplitterExample : TopWindow { 44 | Splitter splitter; 45 | SshSession session; 46 | CoWorkNX workers; // Same as CoWork, but can be used as a member. 47 | 48 | bool Key(dword key, int count) override 49 | { 50 | if(key == K_SHIFT_CTRL_T) AddPane(); 51 | return false; 52 | } 53 | 54 | void AddPane() 55 | { 56 | if(splitter.GetCount() < MAXPANECOUNT) { 57 | workers & [=] { 58 | EnterGuiMutex(); // Note: Ctrl derived classes can only be 59 | SshTerminalPane shell(session, splitter); // initialized in main thread OR vith gui 60 | LeaveGuiMutex(); // mutex. (GuiLock) 61 | shell.Run("xterm"); 62 | }; 63 | } 64 | } 65 | 66 | void Run() 67 | { 68 | if(!EditTextNotNull(url, "SSH server", "Url")) 69 | Exit(1); 70 | 71 | session.WhenWait = [=] { if(IsMainThread()) ProcessEvents(); }; 72 | 73 | if(!session.Timeout(10000).Connect(url)) { 74 | ErrorOK(DeQtf(session.GetErrorDesc())); 75 | Exit(1); 76 | } 77 | 78 | Title(t_("Ssh terminal splitter (Press CTRL + SHIFT + T to split the view)")); 79 | Sizeable().Zoomable().CenterScreen().SetRect(0, 0, 1024, 600); 80 | Add(splitter.Horz()); 81 | AddPane(); 82 | OpenMain(); 83 | while(IsOpen() && !workers.IsFinished()) { 84 | ProcessEvents(); 85 | GuiSleep(10); 86 | } 87 | GuiUnlock __; 88 | workers.Cancel(); 89 | } 90 | }; 91 | 92 | GUI_APP_MAIN 93 | { 94 | SshTerminalSplitterExample().Run(); 95 | } -------------------------------------------------------------------------------- /PtyAgent/ReadMe.md: -------------------------------------------------------------------------------- 1 | # PtyAgent package for U++ 2 | 3 | The U++ package for `winpty-agent` executable. This executable is required on runtime by the default backend of `PtyProcess` package and meant to be built on Windows (tm) platform. 4 | 5 | ## Usage 6 | 7 | You can build the package with either `TheIDE` or `umk` and move the resulting executable (`PtyAgent.exe`) into the directory of the main executable of your app. 8 | 9 | ## Licenses 10 | 11 | ~~~ 12 | PtyAgent package for U++ 13 | ------------------------ 14 | 15 | Copyright (c) 2023, İsmail Yılmaz 16 | All rights reserved. 17 | 18 | Redistribution and use in source and binary forms, with or without 19 | modification, are permitted provided that the following conditions are met: 20 | 21 | * Redistributions of source code must retain the above copyright notice, this 22 | list of conditions and the following disclaimer. 23 | 24 | * Redistributions in binary form must reproduce the above copyright notice, 25 | this list of conditions and the following disclaimer in the documentation 26 | and/or other materials provided with the distribution. 27 | 28 | * Neither the name of the copyright holder nor the names of its 29 | contributors may be used to endorse or promote products derived from 30 | this software without specific prior written permission. 31 | 32 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 33 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 35 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 36 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 38 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 39 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 40 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 41 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 | ~~~ 43 | ~~~ 44 | winpty 45 | ------ 46 | The MIT License (MIT) 47 | 48 | Copyright (c) 2011-2016 Ryan Prichard 49 | 50 | Permission is hereby granted, free of charge, to any person obtaining a copy 51 | of this software and associated documentation files (the "Software"), to 52 | deal in the Software without restriction, including without limitation the 53 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 54 | sell copies of the Software, and to permit persons to whom the Software is 55 | furnished to do so, subject to the following conditions: 56 | 57 | The above copyright notice and this permission notice shall be included in 58 | all copies or substantial portions of the Software. 59 | 60 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 61 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 62 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 63 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 64 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 65 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 66 | IN THE SOFTWARE. 67 | ~~~ 68 | 69 | 70 | -------------------------------------------------------------------------------- /examples/TerminalSplitterExample/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // This example demonstrates a simple, cross-platform (POSIX/Windows) 5 | // terminal splitter example. 6 | 7 | // On Windows platform PtyProcess class uses statically linked *winpty* 8 | // library and the supplementary PtyAgent pacakges as its *default* pty 9 | // backend. However, it also supports the Windows 10 (tm) pseudoconsole 10 | // API via the WIN10 compiler flag. This flag can be enabled or disable 11 | // easily via TheIDE's main package configuration dialog. (E.g: "GUI WIN10") 12 | 13 | #ifdef PLATFORM_POSIX 14 | const char *tshell = "SHELL"; 15 | #elif PLATFORM_WIN32 16 | const char *tshell = "ComSpec"; // Alternatively you can use powershell... 17 | #endif 18 | 19 | const int MAXPANECOUNT = 4; // You can increase the number of panes if you like. 20 | 21 | using namespace Upp; 22 | 23 | PtyWaitEvent& GetEventList() 24 | { 25 | return Single(); 26 | } 27 | 28 | struct TerminalPane : TerminalCtrl, PtyProcess { 29 | Splitter& parent; 30 | TerminalPane(Splitter& ctrl) : parent(ctrl) 31 | { 32 | TerminalCtrl::InlineImages().Hyperlinks().WindowOps(); 33 | TerminalCtrl::WhenBell = [=]() { BeepExclamation(); }; 34 | TerminalCtrl::WhenOutput = [=](String s) { PtyProcess::Write(s); }; 35 | TerminalCtrl::WhenResize = [=]() { PtyProcess::SetSize(GetPageSize()); }; 36 | if(PtyProcess::Start(GetEnv(tshell), Environment(), GetHomeDirectory())) { 37 | AddToEventList(); 38 | parent.Add(TerminalCtrl::SizePos()); 39 | } 40 | } 41 | 42 | ~TerminalPane() 43 | { 44 | RemoveFromEventList(); 45 | } 46 | 47 | void Do() 48 | { 49 | TerminalCtrl::WriteUtf8(PtyProcess::Get()); 50 | if(!PtyProcess::IsRunning()) { 51 | parent.Remove(*this); 52 | parent.Layout(); 53 | } 54 | } 55 | 56 | void AddToEventList() 57 | { 58 | GetEventList().Add(static_cast(*this), WAIT_READ | WAIT_IS_EXCEPTION); 59 | } 60 | 61 | void RemoveFromEventList() 62 | { 63 | GetEventList().Remove(static_cast(*this)); 64 | } 65 | 66 | bool Key(dword key, int count) override 67 | { 68 | // Let the parent handle the SHIFT + CTRL + T key. 69 | return key != K_SHIFT_CTRL_T ? TerminalCtrl::Key(key, count) : false; 70 | } 71 | }; 72 | 73 | struct TerminalSplitterExample : TopWindow { 74 | Splitter splitter; 75 | Array panes; 76 | 77 | bool Key(dword key, int count) override 78 | { 79 | if(key == K_SHIFT_CTRL_T) AddPane(); 80 | return false; 81 | } 82 | 83 | void AddPane() 84 | { 85 | if(splitter.GetCount() < MAXPANECOUNT) 86 | panes.Create(splitter); 87 | } 88 | 89 | void Run() 90 | { 91 | Title(t_("Terminal splitter (Press CTRL + SHIFT + T to split the view)")); 92 | Sizeable().Zoomable().CenterScreen().SetRect(0, 0, 1024, 600); 93 | Add(splitter.Horz()); 94 | AddPane(); 95 | OpenMain(); 96 | while(IsOpen() && splitter.GetCount()) { 97 | ProcessEvents(); 98 | if(GetEventList().Wait(10)) 99 | for(TerminalPane& pane : panes) 100 | pane.Do(); 101 | } 102 | } 103 | }; 104 | 105 | GUI_APP_MAIN 106 | { 107 | TerminalSplitterExample().Run(); 108 | } -------------------------------------------------------------------------------- /Terminal/Terminal.usc: -------------------------------------------------------------------------------- 1 | enum_property CaretStyle { 2 | "TerminalCtrl::Caret::BLOCK", 3 | "TerminalCtrl::Caret::BEAM", 4 | "TerminalCtrl::Caret::UNDERLINE" 5 | }; 6 | 7 | ctrl TerminalCtrl { 8 | group "Complex"; 9 | 10 | 11 | Frame SetFrame = FieldFrame() @1; 12 | Font SetFont = Monospace(); 13 | Color Ink = :SBlack; 14 | Color Paper = :SWhite; 15 | bool NoBackground = false; 16 | bool AdjustColors = true; 17 | bool ShowSizeHint = true; 18 | bool History = true; 19 | int SetHistorySize = 65536; 20 | bool ShowScrollBar = false; 21 | bool BlinkingText = true; 22 | int BlinkInterval = 500; 23 | CaretStyle SetCursorStyle = TerminalCtrl::Caret::BLOCK @1; 24 | bool LockCursor = false; 25 | bool InlineImages = false; 26 | bool Hyperlinks = false; 27 | bool WindowActions = false; 28 | bool WindowReports = false; 29 | bool DelayedRefresh = true; 30 | bool LazyResize = false; 31 | 32 | FontSize() { 33 | return GetTextSize("X", .SetFont); 34 | } 35 | 36 | GetMinSize() { sz = FontSize(); sz.cx *= 2; sz.cy *= 2; return sz; } 37 | GetStdSize() { sz = FontSize(); sz.cx *= 80; sz.cy *= 24; return sz; } 38 | 39 | InflateRect(r, n) { 40 | r.left -= n; 41 | r.top -= n; 42 | r.right += n; 43 | r.bottom += n; 44 | return r; 45 | } 46 | 47 | ViewRect(w) { 48 | r = GetRect(); 49 | DrawCtrlFrame(w, r, .SetFrame); 50 | return r; 51 | } 52 | 53 | ViewSize(w) { 54 | r = ViewRect(w); 55 | return Size(r.right - r.left, r.bottom - r.top); 56 | } 57 | 58 | SizeHint(w) { 59 | wsz = ViewSize(w); 60 | fsz = FontSize(); 61 | hcx = (wsz.cx - (.ShowScrollBar ? fsz.cy : 0)) / fsz.cx; 62 | hcy = wsz.cy / fsz.cy; 63 | return Size(int(hcx), int(hcy)); 64 | } 65 | 66 | PaintCenterRect(w, x, y, sz) { 67 | r = RectC(x - sz.cx / 2, y - sz.cy / 2, sz.cx, sz.cy); 68 | w.DrawRect(InflateRect(r, 7), :SBlack); 69 | DrawCtrlFrame(w, InflateRect(r, 8), "FieldFrame()"); 70 | } 71 | 72 | PaintSizeHint(w, x, y) { 73 | hsz = SizeHint(w); 74 | txt = IntStr(hsz.cx) + " x " + IntStr(hsz.cy); 75 | tsz = GetTextSize(txt, StdFont()); 76 | PaintCenterRect(w, x, y, tsz); 77 | PaintCenterText(w, x, y, txt, StdFont(), :SWhite); 78 | } 79 | 80 | PaintCaret(w, x, y, sz) { 81 | switch(.SetCursorStyle) { 82 | case "TerminalCtrl::Caret::BLOCK": /* NOP */ break; 83 | case "TerminalCtrl::Caret::BEAM": sz.cx = 1; break; 84 | case "TerminalCtrl::Caret::UNDERLINE": y = sz.cy - 1; sz.cy = 1; break; 85 | } 86 | w.DrawRect(x, y, sz.cx, sz.cy, .LockCursor ? :SLtGray : :SBlack); 87 | } 88 | 89 | PaintLine(w, x, y, text) { 90 | fsz = FontSize(); 91 | tsz = GetTextSize(text, .SetFont); 92 | w.DrawText(x, y + 2, text, .SetFont, .Ink); 93 | PaintCaret(w, x + tsz.cx + 4, y + 2, fsz); 94 | } 95 | 96 | Paint(w) { 97 | r = ViewRect(w); 98 | prompt = "[user@hostname ~]$"; 99 | 100 | if(!.NoBackground) 101 | w.DrawRect(r, .Paper); 102 | 103 | PaintLine(w, r.left, r.top, prompt); 104 | 105 | if(.ShowScrollBar) { 106 | rsb = r; 107 | r.right = rsb.left = rsb.right - FontSize().cy; 108 | PaintVScrollBar(w, rsb); 109 | } 110 | 111 | if(.ShowSizeHint) 112 | PaintSizeHint(w, (r.left + r.right) / 2, (r.top + r.bottom) / 2); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/EventLoop.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2012 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #include "EventLoop.h" 22 | 23 | #include 24 | 25 | #include "NamedPipe.h" 26 | #include "../shared/DebugClient.h" 27 | #include "../shared/WinptyAssert.h" 28 | 29 | EventLoop::~EventLoop() { 30 | for (NamedPipe *pipe : m_pipes) { 31 | delete pipe; 32 | } 33 | m_pipes.clear(); 34 | } 35 | 36 | // Enter the event loop. Runs until the I/O or timeout handler calls exit(). 37 | void EventLoop::run() 38 | { 39 | std::vector waitHandles; 40 | DWORD lastTime = GetTickCount(); 41 | while (!m_exiting) { 42 | bool didSomething = false; 43 | 44 | // Attempt to make progress with the pipes. 45 | waitHandles.clear(); 46 | for (size_t i = 0; i < m_pipes.size(); ++i) { 47 | if (m_pipes[i]->serviceIo(&waitHandles)) { 48 | onPipeIo(*m_pipes[i]); 49 | didSomething = true; 50 | } 51 | } 52 | 53 | // Call the timeout if enough time has elapsed. 54 | if (m_pollInterval > 0) { 55 | int elapsed = GetTickCount() - lastTime; 56 | if (elapsed >= m_pollInterval) { 57 | onPollTimeout(); 58 | lastTime = GetTickCount(); 59 | didSomething = true; 60 | } 61 | } 62 | 63 | if (didSomething) 64 | continue; 65 | 66 | // If there's nothing to do, wait. 67 | DWORD timeout = INFINITE; 68 | if (m_pollInterval > 0) 69 | timeout = std::max(0, (int)(lastTime + m_pollInterval - GetTickCount())); 70 | if (waitHandles.size() == 0) { 71 | ASSERT(timeout != INFINITE); 72 | if (timeout > 0) 73 | Sleep(timeout); 74 | } else { 75 | DWORD result = WaitForMultipleObjects(waitHandles.size(), 76 | waitHandles.data(), 77 | FALSE, 78 | timeout); 79 | ASSERT(result != WAIT_FAILED); 80 | } 81 | } 82 | } 83 | 84 | NamedPipe &EventLoop::createNamedPipe() 85 | { 86 | NamedPipe *ret = new NamedPipe(); 87 | m_pipes.push_back(ret); 88 | return *ret; 89 | } 90 | 91 | void EventLoop::setPollInterval(int ms) 92 | { 93 | m_pollInterval = ms; 94 | } 95 | 96 | void EventLoop::shutdown() 97 | { 98 | m_exiting = true; 99 | } 100 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/Win32ConsoleBuffer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef AGENT_WIN32_CONSOLE_BUFFER_H 22 | #define AGENT_WIN32_CONSOLE_BUFFER_H 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include 29 | 30 | #include "Coord.h" 31 | #include "SmallRect.h" 32 | 33 | class ConsoleScreenBufferInfo : public CONSOLE_SCREEN_BUFFER_INFO { 34 | public: 35 | ConsoleScreenBufferInfo() 36 | { 37 | memset(this, 0, sizeof(*this)); 38 | } 39 | 40 | Coord bufferSize() const { return dwSize; } 41 | SmallRect windowRect() const { return srWindow; } 42 | Coord cursorPosition() const { return dwCursorPosition; } 43 | }; 44 | 45 | class Win32ConsoleBuffer { 46 | private: 47 | Win32ConsoleBuffer(HANDLE conout, bool owned) : 48 | m_conout(conout), m_owned(owned) 49 | { 50 | } 51 | 52 | public: 53 | static const int kDefaultAttributes = 7; 54 | 55 | ~Win32ConsoleBuffer() { 56 | if (m_owned) { 57 | CloseHandle(m_conout); 58 | } 59 | } 60 | 61 | static std::unique_ptr openStdout(); 62 | static std::unique_ptr openConout(); 63 | static std::unique_ptr createErrorBuffer(); 64 | 65 | Win32ConsoleBuffer(const Win32ConsoleBuffer &other) = delete; 66 | Win32ConsoleBuffer &operator=(const Win32ConsoleBuffer &other) = delete; 67 | 68 | HANDLE conout(); 69 | void clearLines(int row, int count, const ConsoleScreenBufferInfo &info); 70 | void clearAllLines(const ConsoleScreenBufferInfo &info); 71 | 72 | // Buffer and window sizes. 73 | ConsoleScreenBufferInfo bufferInfo(); 74 | Coord bufferSize(); 75 | SmallRect windowRect(); 76 | void resizeBuffer(const Coord &size); 77 | bool resizeBufferRange(const Coord &initialSize, Coord &finalSize); 78 | bool resizeBufferRange(const Coord &initialSize) { 79 | Coord dummy; 80 | return resizeBufferRange(initialSize, dummy); 81 | } 82 | void moveWindow(const SmallRect &rect); 83 | 84 | // Cursor. 85 | Coord cursorPosition(); 86 | void setCursorPosition(const Coord &point); 87 | 88 | // Screen content. 89 | void read(const SmallRect &rect, CHAR_INFO *data); 90 | void write(const SmallRect &rect, const CHAR_INFO *data); 91 | 92 | void setTextAttribute(WORD attributes); 93 | 94 | private: 95 | HANDLE m_conout = nullptr; 96 | bool m_owned = false; 97 | }; 98 | 99 | #endif // AGENT_WIN32_CONSOLE_BUFFER_H 100 | -------------------------------------------------------------------------------- /PtyProcess/ReadMe.md: -------------------------------------------------------------------------------- 1 | # PtyProcess package for U++ 2 | 3 | A cross-platform pseudoconsole inplementation for U++. 4 | 5 | ## Introduction 6 | 7 | This package provides a unified and simple interface for both POSIX-compliant systems and Windows platforms. On Windows, PtyProcess package can use two backends: 8 | 9 | 1. Statically linked [winpty library and agent](https://github.com/rprichard/winpty). This library allows `PtyProcess` to run native console applications on Windows XP/Vista/7/8/10. You will also need to compile the `PtyAgent` package. This is the **default** backend. 10 | 11 | 2. Native Windows 10 pseudoconsole API (ConPty). This backend requires at least Windows 10 with pty support and it can be switched on via the `WIN10` build flag. 12 | 13 | Additionally, this package provides a `PtyWaitEvent` class that allows `PtyProcess` derived classes to properly wait for events across all supported platforms (Windows, POSIX) 14 | 15 | 16 | 17 | ## License 18 | 19 | ~~~ 20 | PtyProcess package for U++ 21 | -------------------------- 22 | 23 | Copyright (c) 2018-2025, İsmail Yılmaz 24 | All rights reserved. 25 | 26 | Redistribution and use in source and binary forms, with or without 27 | modification, are permitted provided that the following conditions are met: 28 | 29 | * Redistributions of source code must retain the above copyright notice, this 30 | list of conditions and the following disclaimer. 31 | 32 | * Redistributions in binary form must reproduce the above copyright notice, 33 | this list of conditions and the following disclaimer in the documentation 34 | and/or other materials provided with the distribution. 35 | 36 | * Neither the name of the copyright holder nor the names of its 37 | contributors may be used to endorse or promote products derived from 38 | this software without specific prior written permission. 39 | 40 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 41 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 43 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 44 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 46 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 47 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 48 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 49 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 50 | ~~~ 51 | ~~~ 52 | winpty 53 | ------ 54 | The MIT License (MIT) 55 | 56 | Copyright (c) 2011-2016 Ryan Prichard 57 | 58 | Permission is hereby granted, free of charge, to any person obtaining a copy 59 | of this software and associated documentation files (the "Software"), to 60 | deal in the Software without restriction, including without limitation the 61 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 62 | sell copies of the Software, and to permit persons to whom the Software is 63 | furnished to do so, subject to the following conditions: 64 | 65 | The above copyright notice and this permission notice shall be included in 66 | all copies or substantial portions of the Software. 67 | 68 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 69 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 70 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 71 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 72 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 73 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 74 | IN THE SOFTWARE. 75 | ~~~ 76 | 77 | 78 | -------------------------------------------------------------------------------- /examples/TabbedTerminalExample/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // This example demonstrates a simple, cross-platform (POSIX/Windows) 6 | // tabbed terminal example. 7 | 8 | // On Windows platform PtyProcess class uses statically linked *winpty* 9 | // library and the supplementary PtyAgent pacakges as its *default* pty 10 | // backend. However, it also supports the Windows 10 (tm) pseudoconsole 11 | // API via the WIN10 compiler flag. This flag can be enabled or disable 12 | // easily via TheIDE's main package configuration dialog. (E.g: "GUI WIN10") 13 | 14 | #ifdef PLATFORM_POSIX 15 | const char *tshell = "SHELL"; 16 | #elif PLATFORM_WIN32 17 | const char *tshell = "ComSpec"; // Alternatively you can use powershell... 18 | #endif 19 | 20 | const int MAXTABS = 10; 21 | 22 | using namespace Upp; 23 | 24 | PtyWaitEvent& GetEventList() 25 | { 26 | return Single(); 27 | } 28 | 29 | struct TerminalTab : TerminalCtrl, PtyProcess { 30 | TerminalTab() 31 | { 32 | InlineImages().Hyperlinks().WindowOps(); 33 | WhenBell = [=]() { BeepExclamation(); }; 34 | WhenOutput = [=](String s) { PtyProcess::Write(s); }; 35 | WhenResize = [=]() { PtyProcess::SetSize(GetPageSize()); }; 36 | if(Start(GetEnv(tshell), Environment(), GetHomeDirectory())) 37 | AddToEventList(); 38 | } 39 | 40 | ~TerminalTab() 41 | { 42 | RemoveFromEventList(); 43 | } 44 | 45 | bool Do() 46 | { 47 | WriteUtf8(PtyProcess::Get()); 48 | return PtyProcess::IsRunning(); 49 | } 50 | 51 | void AddToEventList() 52 | { 53 | GetEventList().Add(static_cast(*this), WAIT_READ | WAIT_IS_EXCEPTION); 54 | } 55 | 56 | void RemoveFromEventList() 57 | { 58 | GetEventList().Remove(static_cast(*this)); 59 | } 60 | 61 | bool Key(dword key, int count) override 62 | { 63 | // Let the parent handle the SHIFT + CTRL + T key. 64 | return key != K_SHIFT_CTRL_T ? TerminalCtrl::Key(key, count) : false; 65 | } 66 | }; 67 | 68 | struct TabbedTerminal : TopWindow { 69 | TabBarCtrl tabbar; 70 | Array tabs; 71 | 72 | typedef TabbedTerminal CLASSNAME; 73 | 74 | bool Key(dword key, int cnt) override 75 | { 76 | if(key == K_SHIFT_CTRL_T) AddTab(); 77 | return true; 78 | } 79 | 80 | void AddTab() 81 | { 82 | if(tabs.GetCount() < MAXTABS) { 83 | TerminalTab& tt = tabs.Add(); 84 | int64 key = (int64) GetTickCount(); 85 | tabbar.AddCtrl(tt.SizePos(), key, Format("Terminal #%d", tabs.GetCount())); 86 | } 87 | } 88 | 89 | void CloseTab(Value key) 90 | { 91 | Ctrl *c = tabbar.GetCtrl(key); 92 | if(c) 93 | for(int i = 0; i < tabs.GetCount(); i++) 94 | if(&tabs[i] == c) { 95 | tabs.Remove(i); 96 | break; 97 | } 98 | } 99 | 100 | void FocusTab() 101 | { 102 | tabbar.GetCurrentCtrl()->SetFocus(); 103 | } 104 | 105 | void Run() 106 | { 107 | Title(t_("Tabbed terminals example (Press SHIFT+CTRL+T to open a new tab)")); 108 | Sizeable().Zoomable().CenterScreen().Add(tabbar.SortTabs().SizePos()); 109 | SetRect(0, 0, 1024, 640); 110 | tabbar.WhenClose = THISFN(CloseTab); 111 | tabbar.WhenAction = THISFN(FocusTab); 112 | AddTab(); 113 | OpenMain(); 114 | while(IsOpen() && !tabs.IsEmpty()) { 115 | ProcessEvents(); 116 | if(GetEventList().Wait(10)) { 117 | for(int i = 0; i < tabs.GetCount(); i++) { 118 | TerminalTab& tt = tabs[i]; 119 | if(!tt.Do()) { 120 | tabbar.RemoveCtrl(tt); 121 | tabs.Remove(i); 122 | break; 123 | } 124 | } 125 | } 126 | } 127 | } 128 | }; 129 | 130 | GUI_APP_MAIN 131 | { 132 | TabbedTerminal().Run(); 133 | } 134 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/Buffer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_BUFFER_H 22 | #define WINPTY_SHARED_BUFFER_H 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "WinptyException.h" 33 | 34 | class WriteBuffer { 35 | private: 36 | std::vector m_buf; 37 | 38 | public: 39 | WriteBuffer() {} 40 | 41 | template void putRawValue(const T &t) { 42 | putRawData(&t, sizeof(t)); 43 | } 44 | template void replaceRawValue(size_t pos, const T &t) { 45 | replaceRawData(pos, &t, sizeof(t)); 46 | } 47 | 48 | void putRawData(const void *data, size_t len); 49 | void replaceRawData(size_t pos, const void *data, size_t len); 50 | void putInt32(int32_t i); 51 | void putInt64(int64_t i); 52 | void putWString(const wchar_t *str, size_t len); 53 | void putWString(const wchar_t *str) { putWString(str, wcslen(str)); } 54 | void putWString(const std::wstring &str) { putWString(str.data(), str.size()); } 55 | std::vector &buf() { return m_buf; } 56 | 57 | // MSVC 2013 does not generate these automatically, so help it out. 58 | WriteBuffer(WriteBuffer &&other) : m_buf(std::move(other.m_buf)) {} 59 | WriteBuffer &operator=(WriteBuffer &&other) { 60 | m_buf = std::move(other.m_buf); 61 | return *this; 62 | } 63 | }; 64 | 65 | class ReadBuffer { 66 | public: 67 | class DecodeError : public WinptyException { 68 | virtual const wchar_t *what() const WINPTY_NOEXCEPT override { 69 | return L"DecodeError: RPC message decoding error"; 70 | } 71 | }; 72 | 73 | private: 74 | std::vector m_buf; 75 | size_t m_off = 0; 76 | 77 | public: 78 | explicit ReadBuffer(std::vector &&buf) : m_buf(std::move(buf)) {} 79 | 80 | template T getRawValue() { 81 | T ret = {}; 82 | getRawData(&ret, sizeof(ret)); 83 | return ret; 84 | } 85 | 86 | void getRawData(void *data, size_t len); 87 | int32_t getInt32(); 88 | int64_t getInt64(); 89 | std::wstring getWString(); 90 | void assertEof(); 91 | 92 | // MSVC 2013 does not generate these automatically, so help it out. 93 | ReadBuffer(ReadBuffer &&other) : 94 | m_buf(std::move(other.m_buf)), m_off(other.m_off) {} 95 | ReadBuffer &operator=(ReadBuffer &&other) { 96 | m_buf = std::move(other.m_buf); 97 | m_off = other.m_off; 98 | return *this; 99 | } 100 | }; 101 | 102 | #endif // WINPTY_SHARED_BUFFER_H 103 | -------------------------------------------------------------------------------- /examples/TabbedSshTerminalExample/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // This example demonstrates a multithreaded ssh terminal with tabs. 6 | // It is using the Core/SSH package, therefore it can be compiled 7 | // for, and run on, Windows and POSIX-compliant operating systems. 8 | 9 | using namespace Upp; 10 | 11 | String url = "demo:password@test.rebex.net:22"; // A well-known public SSH test server. 12 | const int MAXTABCOUNT = 8; // You can increase the number of tabs if you like. 13 | 14 | struct SshTerminalTab : TerminalCtrl, SshShell { 15 | TabBarCtrl& parent; 16 | SshTerminalTab(SshSession& session, TabBarCtrl& ctrl) : SshShell(session), parent(ctrl) 17 | { 18 | SshShell::Timeout(Null); 19 | SshShell::ChunkSize(65536); 20 | SshShell::WhenOutput = [=](const void *data, int size) { GuiLock __; TerminalCtrl::Write(data, size);}; 21 | SshShell::WhenWait = [=]() { if(CoWork::IsCanceled()) SshShell::Abort(); }; 22 | TerminalCtrl::WhenOutput = [=](String data) { SshShell::Send(data); }; 23 | TerminalCtrl::WhenResize = [=]() { SshShell::PageSize(TerminalCtrl::GetPageSize()); }; 24 | TerminalCtrl::InlineImages().Hyperlinks().WindowOps(); 25 | parent.AddCtrl(TerminalCtrl::SizePos(), Format("Ssh Terminal #%d", SshShell::GetId())); 26 | } 27 | 28 | void Run(const String& termtype) 29 | { 30 | SshShell::Run(termtype, TerminalCtrl::GetPageSize()); 31 | GuiLock __; 32 | parent.RemoveCtrl(*this); 33 | } 34 | 35 | bool Key(dword key, int count) override 36 | { 37 | // Let the parent handle the SHIFT + CTRL + T key. 38 | return key != K_SHIFT_CTRL_T ? TerminalCtrl::Key(key, count) : false; 39 | } 40 | }; 41 | 42 | struct TabbedSshTerminal : TopWindow { 43 | TabBarCtrl tabbar; 44 | SshSession session; 45 | CoWorkNX workers; // Same as CoWork, but can be used as a member. 46 | 47 | typedef TabbedSshTerminal CLASSNAME; 48 | 49 | bool Key(dword key, int cnt) override 50 | { 51 | if(key == K_SHIFT_CTRL_T) AddTab(); 52 | return true; 53 | } 54 | 55 | void AddTab() 56 | { 57 | if(tabbar.GetCount() < MAXTABCOUNT) { 58 | workers & [=] { 59 | EnterGuiMutex(); // Note: Ctrl derived classes can only be 60 | SshTerminalTab shell(session, tabbar); // initialized in main thread OR vith gui 61 | LeaveGuiMutex(); // mutex. (GuiLock) 62 | shell.Run("xterm"); 63 | }; 64 | } 65 | } 66 | 67 | void CloseTab(Value key) 68 | { 69 | GuiLock __; 70 | auto *tab = dynamic_cast(tabbar.GetCtrl(key)); 71 | if(tab && tab->InProgress()) tab->Abort(); 72 | } 73 | 74 | void FocusTab() 75 | { 76 | GuiLock __; 77 | tabbar.GetCurrentCtrl()->SetFocus(); 78 | } 79 | 80 | void Run() 81 | { 82 | if(!EditTextNotNull(url, "SSH server", "Url")) 83 | Exit(1); 84 | 85 | session.WhenWait = [=] { if(IsMainThread()) ProcessEvents(); }; 86 | 87 | if(!session.Timeout(10000).Connect(url)) { 88 | ErrorOK(DeQtf(session.GetErrorDesc())); 89 | Exit(1); 90 | } 91 | 92 | Title(t_("Tabbed terminals example (Press SHIFT + CTRL + T to open a new tab)")); 93 | Sizeable().Zoomable().CenterScreen().Add(tabbar.SortTabs().SizePos()); 94 | SetRect(0, 0, 1024, 640); 95 | tabbar.WhenClose = THISFN(CloseTab); 96 | tabbar.WhenAction = THISFN(FocusTab); 97 | AddTab(); 98 | OpenMain(); 99 | while(IsOpen() && !workers.IsFinished()) { 100 | ProcessEvents(); 101 | GuiSleep(10); 102 | } 103 | GuiUnlock __; 104 | workers.Cancel(); 105 | } 106 | }; 107 | 108 | GUI_APP_MAIN 109 | { 110 | TabbedSshTerminal().Run(); 111 | } 112 | -------------------------------------------------------------------------------- /PtyProcess/lib/shared/Buffer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_SHARED_BUFFER_H 22 | #define WINPTY_SHARED_BUFFER_H 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "WinptyException.h" 33 | 34 | class WriteBuffer { 35 | private: 36 | std::vector m_buf; 37 | 38 | public: 39 | WriteBuffer() {} 40 | 41 | template void putRawValue(const T &t) { 42 | putRawData(&t, sizeof(t)); 43 | } 44 | template void replaceRawValue(size_t pos, const T &t) { 45 | replaceRawData(pos, &t, sizeof(t)); 46 | } 47 | 48 | void putRawData(const void *data, size_t len); 49 | void replaceRawData(size_t pos, const void *data, size_t len); 50 | void putInt32(int32_t i); 51 | void putInt64(int64_t i); 52 | void putWString(const wchar_t *str, size_t len); 53 | void putWString(const wchar_t *str) { putWString(str, wcslen(str)); } 54 | void putWString(const std::wstring &str) { putWString(str.data(), str.size()); } 55 | std::vector &buf() { return m_buf; } 56 | 57 | // MSVC 2013 does not generate these automatically, so help it out. 58 | WriteBuffer(WriteBuffer &&other) : m_buf(std::move(other.m_buf)) {} 59 | WriteBuffer &operator=(WriteBuffer &&other) { 60 | m_buf = std::move(other.m_buf); 61 | return *this; 62 | } 63 | }; 64 | 65 | class ReadBuffer { 66 | public: 67 | class DecodeError : public WinptyException { 68 | virtual const wchar_t *what() const WINPTY_NOEXCEPT override { 69 | return L"DecodeError: RPC message decoding error"; 70 | } 71 | }; 72 | 73 | private: 74 | std::vector m_buf; 75 | size_t m_off = 0; 76 | 77 | public: 78 | explicit ReadBuffer(std::vector &&buf) : m_buf(std::move(buf)) {} 79 | 80 | template T getRawValue() { 81 | T ret = {}; 82 | getRawData(&ret, sizeof(ret)); 83 | return ret; 84 | } 85 | 86 | void getRawData(void *data, size_t len); 87 | int32_t getInt32(); 88 | int64_t getInt64(); 89 | std::wstring getWString(); 90 | void assertEof(); 91 | 92 | // MSVC 2013 does not generate these automatically, so help it out. 93 | ReadBuffer(ReadBuffer &&other) : 94 | m_buf(std::move(other.m_buf)), m_off(other.m_off) {} 95 | ReadBuffer &operator=(ReadBuffer &&other) { 96 | m_buf = std::move(other.m_buf); 97 | m_off = other.m_off; 98 | return *this; 99 | } 100 | }; 101 | 102 | #endif // WINPTY_SHARED_BUFFER_H 103 | -------------------------------------------------------------------------------- /PtyAgent/lib/agent/InputMap.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-2015 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef INPUT_MAP_H 22 | #define INPUT_MAP_H 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include "SimplePool.h" 31 | #include "../shared/WinptyAssert.h" 32 | 33 | class InputMap { 34 | public: 35 | struct Key { 36 | uint16_t virtualKey; 37 | uint32_t unicodeChar; 38 | uint16_t keyState; 39 | 40 | std::string toString() const; 41 | }; 42 | 43 | private: 44 | struct Node; 45 | 46 | struct Branch { 47 | Branch() { 48 | memset(&children, 0, sizeof(children)); 49 | } 50 | 51 | Node *children[256]; 52 | }; 53 | 54 | struct Node { 55 | Node() : childCount(0) { 56 | Key zeroKey = { 0, 0, 0 }; 57 | key = zeroKey; 58 | } 59 | 60 | Key key; 61 | int childCount; 62 | enum { kTinyCount = 8 }; 63 | union { 64 | Branch *branch; 65 | struct { 66 | unsigned char values[kTinyCount]; 67 | Node *children[kTinyCount]; 68 | } tiny; 69 | } u; 70 | 71 | bool hasKey() const { 72 | return key.virtualKey != 0 || key.unicodeChar != 0; 73 | } 74 | }; 75 | 76 | private: 77 | SimplePool m_nodePool; 78 | SimplePool m_branchPool; 79 | Node m_root; 80 | 81 | public: 82 | void set(const char *encoding, int encodingLen, const Key &key); 83 | int lookupKey(const char *input, int inputSize, 84 | Key &keyOut, bool &incompleteOut) const; 85 | void dumpInputMap() const; 86 | 87 | private: 88 | Node *getChild(Node &node, unsigned char ch) { 89 | return const_cast(getChild(static_cast(node), ch)); 90 | } 91 | 92 | const Node *getChild(const Node &node, unsigned char ch) const { 93 | if (node.childCount <= Node::kTinyCount) { 94 | for (int i = 0; i < node.childCount; ++i) { 95 | if (node.u.tiny.values[i] == ch) { 96 | return node.u.tiny.children[i]; 97 | } 98 | } 99 | return NULL; 100 | } else { 101 | return node.u.branch->children[ch]; 102 | } 103 | } 104 | 105 | void setHelper(Node &node, const char *encoding, int encodingLen, const Key &key); 106 | Node &getOrCreateChild(Node &node, unsigned char ch); 107 | void dumpInputMapHelper(const Node &node, std::string &encoding) const; 108 | }; 109 | 110 | const InputMap::Key kKeyZero = { 0, 0, 0 }; 111 | 112 | void dumpInputMap(InputMap &inputMap); 113 | 114 | #endif // INPUT_MAP_H 115 | -------------------------------------------------------------------------------- /PtyAgent/lib/shared/WindowsSecurity.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Ryan Prichard 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | // IN THE SOFTWARE. 20 | 21 | #ifndef WINPTY_WINDOWS_SECURITY_H 22 | #define WINPTY_WINDOWS_SECURITY_H 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | // PSID and PSECURITY_DESCRIPTOR are both pointers to void, but we want 33 | // Sid and SecurityDescriptor to be different types. 34 | struct SidTag { typedef PSID type; }; 35 | struct AclTag { typedef PACL type; }; 36 | struct SecurityDescriptorTag { typedef PSECURITY_DESCRIPTOR type; }; 37 | 38 | template 39 | class SecurityItem { 40 | public: 41 | struct Impl { 42 | virtual ~Impl() {} 43 | }; 44 | 45 | private: 46 | typedef typename T::type P; 47 | P m_v; 48 | std::unique_ptr m_pimpl; 49 | 50 | public: 51 | P get() const { return m_v; } 52 | operator bool() const { return m_v != nullptr; } 53 | 54 | SecurityItem() : m_v(nullptr) {} 55 | SecurityItem(P v, std::unique_ptr &&pimpl) : 56 | m_v(v), m_pimpl(std::move(pimpl)) {} 57 | SecurityItem(SecurityItem &&other) : 58 | m_v(other.m_v), m_pimpl(std::move(other.m_pimpl)) { 59 | other.m_v = nullptr; 60 | } 61 | SecurityItem &operator=(SecurityItem &&other) { 62 | m_v = other.m_v; 63 | other.m_v = nullptr; 64 | m_pimpl = std::move(other.m_pimpl); 65 | return *this; 66 | } 67 | }; 68 | 69 | typedef SecurityItem Sid; 70 | typedef SecurityItem Acl; 71 | typedef SecurityItem SecurityDescriptor; 72 | 73 | Sid getOwnerSid(); 74 | Sid wellKnownSid( 75 | const wchar_t *debuggingName, 76 | SID_IDENTIFIER_AUTHORITY authority, 77 | BYTE authorityCount, 78 | DWORD subAuthority0=0, 79 | DWORD subAuthority1=0); 80 | Sid builtinAdminsSid(); 81 | Sid localSystemSid(); 82 | Sid everyoneSid(); 83 | 84 | SecurityDescriptor createPipeSecurityDescriptorOwnerFullControl(); 85 | SecurityDescriptor createPipeSecurityDescriptorOwnerFullControlEveryoneWrite(); 86 | SecurityDescriptor getObjectSecurityDescriptor(HANDLE handle); 87 | 88 | std::wstring sidToString(PSID sid); 89 | Sid stringToSid(const std::wstring &str); 90 | SecurityDescriptor stringToSd(const std::wstring &str); 91 | std::wstring sdToString(PSECURITY_DESCRIPTOR sd); 92 | 93 | DWORD rejectRemoteClientsPipeFlag(); 94 | 95 | enum class GetNamedPipeClientProcessId_Result { 96 | Success, 97 | Failure, 98 | UnsupportedOs, 99 | }; 100 | 101 | std::tuple 102 | getNamedPipeClientProcessId(HANDLE serverPipe); 103 | 104 | #endif // WINPTY_WINDOWS_SECURITY_H 105 | --------------------------------------------------------------------------------