@shitiandmw/node-pty 1.1.0-agent.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +69 -0
- package/README.md +170 -0
- package/binding.gyp +111 -0
- package/deps/.editorconfig +2 -0
- package/deps/winpty/.drone.yml +17 -0
- package/deps/winpty/.gitattributes +19 -0
- package/deps/winpty/LICENSE +21 -0
- package/deps/winpty/Makefile +166 -0
- package/deps/winpty/README.md +151 -0
- package/deps/winpty/RELEASES.md +280 -0
- package/deps/winpty/VERSION.txt +1 -0
- package/deps/winpty/configure +167 -0
- package/deps/winpty/misc/BufferResizeTests.cc +90 -0
- package/deps/winpty/misc/ChangeScreenBuffer.cc +53 -0
- package/deps/winpty/misc/ClearConsole.cc +72 -0
- package/deps/winpty/misc/ConinMode.cc +117 -0
- package/deps/winpty/misc/ConinMode.ps1 +116 -0
- package/deps/winpty/misc/ConoutMode.cc +113 -0
- package/deps/winpty/misc/DebugClient.py +42 -0
- package/deps/winpty/misc/DebugServer.py +63 -0
- package/deps/winpty/misc/DumpLines.py +5 -0
- package/deps/winpty/misc/EnableExtendedFlags.txt +46 -0
- package/deps/winpty/misc/Font-Report-June2016/CP437-Consolas.txt +528 -0
- package/deps/winpty/misc/Font-Report-June2016/CP437-Lucida.txt +633 -0
- package/deps/winpty/misc/Font-Report-June2016/CP932.txt +630 -0
- package/deps/winpty/misc/Font-Report-June2016/CP936.txt +630 -0
- package/deps/winpty/misc/Font-Report-June2016/CP949.txt +630 -0
- package/deps/winpty/misc/Font-Report-June2016/CP950.txt +630 -0
- package/deps/winpty/misc/Font-Report-June2016/MinimumWindowWidths.txt +16 -0
- package/deps/winpty/misc/Font-Report-June2016/Results.txt +4 -0
- package/deps/winpty/misc/Font-Report-June2016/Windows10SetFontBugginess.txt +144 -0
- package/deps/winpty/misc/FontSurvey.cc +100 -0
- package/deps/winpty/misc/FormatChar.h +21 -0
- package/deps/winpty/misc/FreezePerfTest.cc +62 -0
- package/deps/winpty/misc/GetCh.cc +20 -0
- package/deps/winpty/misc/GetConsolePos.cc +41 -0
- package/deps/winpty/misc/GetFont.cc +261 -0
- package/deps/winpty/misc/IdentifyConsoleWindow.ps1 +51 -0
- package/deps/winpty/misc/IsNewConsole.cc +87 -0
- package/deps/winpty/misc/MouseInputNotes.txt +90 -0
- package/deps/winpty/misc/MoveConsoleWindow.cc +34 -0
- package/deps/winpty/misc/Notes.txt +219 -0
- package/deps/winpty/misc/OSVersion.cc +27 -0
- package/deps/winpty/misc/ScreenBufferFreezeInactive.cc +101 -0
- package/deps/winpty/misc/ScreenBufferTest.cc +671 -0
- package/deps/winpty/misc/ScreenBufferTest2.cc +151 -0
- package/deps/winpty/misc/SelectAllTest.cc +45 -0
- package/deps/winpty/misc/SetBufferSize.cc +32 -0
- package/deps/winpty/misc/SetCursorPos.cc +10 -0
- package/deps/winpty/misc/SetFont.cc +145 -0
- package/deps/winpty/misc/SetWindowRect.cc +36 -0
- package/deps/winpty/misc/ShowArgv.cc +12 -0
- package/deps/winpty/misc/ShowConsoleInput.cc +40 -0
- package/deps/winpty/misc/Spew.py +5 -0
- package/deps/winpty/misc/TestUtil.cc +172 -0
- package/deps/winpty/misc/UnicodeDoubleWidthTest.cc +102 -0
- package/deps/winpty/misc/UnicodeWideTest1.cc +246 -0
- package/deps/winpty/misc/UnicodeWideTest2.cc +130 -0
- package/deps/winpty/misc/UnixEcho.cc +89 -0
- package/deps/winpty/misc/Utf16Echo.cc +46 -0
- package/deps/winpty/misc/VeryLargeRead.cc +122 -0
- package/deps/winpty/misc/VkEscapeTest.cc +56 -0
- package/deps/winpty/misc/Win10ResizeWhileFrozen.cc +52 -0
- package/deps/winpty/misc/Win10WrapTest1.cc +57 -0
- package/deps/winpty/misc/Win10WrapTest2.cc +30 -0
- package/deps/winpty/misc/Win32Echo1.cc +26 -0
- package/deps/winpty/misc/Win32Echo2.cc +19 -0
- package/deps/winpty/misc/Win32Test1.cc +46 -0
- package/deps/winpty/misc/Win32Test2.cc +70 -0
- package/deps/winpty/misc/Win32Test3.cc +78 -0
- package/deps/winpty/misc/Win32Write1.cc +44 -0
- package/deps/winpty/misc/WindowsBugCrashReader.cc +27 -0
- package/deps/winpty/misc/WriteConsole.cc +106 -0
- package/deps/winpty/misc/build32.sh +9 -0
- package/deps/winpty/misc/build64.sh +9 -0
- package/deps/winpty/misc/color-test.sh +212 -0
- package/deps/winpty/misc/font-notes.txt +300 -0
- package/deps/winpty/misc/winbug-15048.cc +201 -0
- package/deps/winpty/ship/build-pty4j-libpty.bat +36 -0
- package/deps/winpty/ship/common_ship.py +53 -0
- package/deps/winpty/ship/make_msvc_package.py +165 -0
- package/deps/winpty/ship/ship.py +108 -0
- package/deps/winpty/src/agent/Agent.cc +613 -0
- package/deps/winpty/src/agent/Agent.h +103 -0
- package/deps/winpty/src/agent/AgentCreateDesktop.cc +84 -0
- package/deps/winpty/src/agent/AgentCreateDesktop.h +28 -0
- package/deps/winpty/src/agent/ConsoleFont.cc +632 -0
- package/deps/winpty/src/agent/ConsoleFont.h +28 -0
- package/deps/winpty/src/agent/ConsoleInput.cc +852 -0
- package/deps/winpty/src/agent/ConsoleInput.h +109 -0
- package/deps/winpty/src/agent/ConsoleInputReencoding.cc +121 -0
- package/deps/winpty/src/agent/ConsoleInputReencoding.h +36 -0
- package/deps/winpty/src/agent/ConsoleLine.cc +152 -0
- package/deps/winpty/src/agent/ConsoleLine.h +41 -0
- package/deps/winpty/src/agent/Coord.h +87 -0
- package/deps/winpty/src/agent/DebugShowInput.cc +239 -0
- package/deps/winpty/src/agent/DebugShowInput.h +32 -0
- package/deps/winpty/src/agent/DefaultInputMap.cc +422 -0
- package/deps/winpty/src/agent/DefaultInputMap.h +28 -0
- package/deps/winpty/src/agent/DsrSender.h +30 -0
- package/deps/winpty/src/agent/EventLoop.cc +99 -0
- package/deps/winpty/src/agent/EventLoop.h +47 -0
- package/deps/winpty/src/agent/InputMap.cc +246 -0
- package/deps/winpty/src/agent/InputMap.h +114 -0
- package/deps/winpty/src/agent/LargeConsoleRead.cc +71 -0
- package/deps/winpty/src/agent/LargeConsoleRead.h +68 -0
- package/deps/winpty/src/agent/NamedPipe.cc +378 -0
- package/deps/winpty/src/agent/NamedPipe.h +125 -0
- package/deps/winpty/src/agent/Scraper.cc +699 -0
- package/deps/winpty/src/agent/Scraper.h +103 -0
- package/deps/winpty/src/agent/SimplePool.h +75 -0
- package/deps/winpty/src/agent/SmallRect.h +143 -0
- package/deps/winpty/src/agent/Terminal.cc +535 -0
- package/deps/winpty/src/agent/Terminal.h +69 -0
- package/deps/winpty/src/agent/UnicodeEncoding.h +157 -0
- package/deps/winpty/src/agent/UnicodeEncodingTest.cc +189 -0
- package/deps/winpty/src/agent/Win32Console.cc +107 -0
- package/deps/winpty/src/agent/Win32Console.h +67 -0
- package/deps/winpty/src/agent/Win32ConsoleBuffer.cc +193 -0
- package/deps/winpty/src/agent/Win32ConsoleBuffer.h +99 -0
- package/deps/winpty/src/agent/main.cc +114 -0
- package/deps/winpty/src/agent/subdir.mk +61 -0
- package/deps/winpty/src/configurations.gypi +60 -0
- package/deps/winpty/src/debugserver/DebugServer.cc +117 -0
- package/deps/winpty/src/debugserver/subdir.mk +41 -0
- package/deps/winpty/src/include/winpty.h +242 -0
- package/deps/winpty/src/include/winpty_constants.h +131 -0
- package/deps/winpty/src/libwinpty/AgentLocation.cc +75 -0
- package/deps/winpty/src/libwinpty/AgentLocation.h +28 -0
- package/deps/winpty/src/libwinpty/LibWinptyException.h +54 -0
- package/deps/winpty/src/libwinpty/WinptyInternal.h +72 -0
- package/deps/winpty/src/libwinpty/subdir.mk +46 -0
- package/deps/winpty/src/libwinpty/winpty.cc +970 -0
- package/deps/winpty/src/shared/AgentMsg.h +38 -0
- package/deps/winpty/src/shared/BackgroundDesktop.cc +122 -0
- package/deps/winpty/src/shared/BackgroundDesktop.h +73 -0
- package/deps/winpty/src/shared/Buffer.cc +103 -0
- package/deps/winpty/src/shared/Buffer.h +102 -0
- package/deps/winpty/src/shared/DebugClient.cc +187 -0
- package/deps/winpty/src/shared/DebugClient.h +38 -0
- package/deps/winpty/src/shared/GenRandom.cc +138 -0
- package/deps/winpty/src/shared/GenRandom.h +55 -0
- package/deps/winpty/src/shared/GetCommitHash.bat +13 -0
- package/deps/winpty/src/shared/Mutex.h +54 -0
- package/deps/winpty/src/shared/OsModule.h +63 -0
- package/deps/winpty/src/shared/OwnedHandle.cc +36 -0
- package/deps/winpty/src/shared/OwnedHandle.h +45 -0
- package/deps/winpty/src/shared/PrecompiledHeader.h +43 -0
- package/deps/winpty/src/shared/StringBuilder.h +227 -0
- package/deps/winpty/src/shared/StringBuilderTest.cc +114 -0
- package/deps/winpty/src/shared/StringUtil.cc +55 -0
- package/deps/winpty/src/shared/StringUtil.h +80 -0
- package/deps/winpty/src/shared/TimeMeasurement.h +63 -0
- package/deps/winpty/src/shared/UnixCtrlChars.h +45 -0
- package/deps/winpty/src/shared/UpdateGenVersion.bat +20 -0
- package/deps/winpty/src/shared/WindowsSecurity.cc +460 -0
- package/deps/winpty/src/shared/WindowsSecurity.h +104 -0
- package/deps/winpty/src/shared/WindowsVersion.cc +252 -0
- package/deps/winpty/src/shared/WindowsVersion.h +29 -0
- package/deps/winpty/src/shared/WinptyAssert.cc +55 -0
- package/deps/winpty/src/shared/WinptyAssert.h +64 -0
- package/deps/winpty/src/shared/WinptyException.cc +57 -0
- package/deps/winpty/src/shared/WinptyException.h +43 -0
- package/deps/winpty/src/shared/WinptyVersion.cc +42 -0
- package/deps/winpty/src/shared/WinptyVersion.h +27 -0
- package/deps/winpty/src/shared/winpty_snprintf.h +99 -0
- package/deps/winpty/src/subdir.mk +5 -0
- package/deps/winpty/src/tests/subdir.mk +28 -0
- package/deps/winpty/src/tests/trivial_test.cc +158 -0
- package/deps/winpty/src/unix-adapter/InputHandler.cc +114 -0
- package/deps/winpty/src/unix-adapter/InputHandler.h +56 -0
- package/deps/winpty/src/unix-adapter/OutputHandler.cc +80 -0
- package/deps/winpty/src/unix-adapter/OutputHandler.h +53 -0
- package/deps/winpty/src/unix-adapter/Util.cc +86 -0
- package/deps/winpty/src/unix-adapter/Util.h +31 -0
- package/deps/winpty/src/unix-adapter/WakeupFd.cc +70 -0
- package/deps/winpty/src/unix-adapter/WakeupFd.h +42 -0
- package/deps/winpty/src/unix-adapter/main.cc +729 -0
- package/deps/winpty/src/unix-adapter/subdir.mk +41 -0
- package/deps/winpty/src/winpty.gyp +234 -0
- package/deps/winpty/vcbuild.bat +83 -0
- package/lib/conpty_console_list_agent.js +16 -0
- package/lib/conpty_console_list_agent.js.map +1 -0
- package/lib/eventEmitter2.js +47 -0
- package/lib/eventEmitter2.js.map +1 -0
- package/lib/eventEmitter2.test.js +30 -0
- package/lib/eventEmitter2.test.js.map +1 -0
- package/lib/index.js +52 -0
- package/lib/index.js.map +1 -0
- package/lib/interfaces.js +7 -0
- package/lib/interfaces.js.map +1 -0
- package/lib/shared/conout.js +11 -0
- package/lib/shared/conout.js.map +1 -0
- package/lib/terminal.js +190 -0
- package/lib/terminal.js.map +1 -0
- package/lib/terminal.test.js +139 -0
- package/lib/terminal.test.js.map +1 -0
- package/lib/testUtils.test.js +28 -0
- package/lib/testUtils.test.js.map +1 -0
- package/lib/types.js +7 -0
- package/lib/types.js.map +1 -0
- package/lib/unixTerminal.js +346 -0
- package/lib/unixTerminal.js.map +1 -0
- package/lib/unixTerminal.test.js +351 -0
- package/lib/unixTerminal.test.js.map +1 -0
- package/lib/utils.js +39 -0
- package/lib/utils.js.map +1 -0
- package/lib/windowsConoutConnection.js +125 -0
- package/lib/windowsConoutConnection.js.map +1 -0
- package/lib/windowsPtyAgent.js +320 -0
- package/lib/windowsPtyAgent.js.map +1 -0
- package/lib/windowsPtyAgent.test.js +90 -0
- package/lib/windowsPtyAgent.test.js.map +1 -0
- package/lib/windowsTerminal.js +199 -0
- package/lib/windowsTerminal.js.map +1 -0
- package/lib/windowsTerminal.test.js +219 -0
- package/lib/windowsTerminal.test.js.map +1 -0
- package/lib/worker/conoutSocketWorker.js +22 -0
- package/lib/worker/conoutSocketWorker.js.map +1 -0
- package/package.json +68 -0
- package/prebuilds/darwin-arm64/pty.node +0 -0
- package/prebuilds/darwin-arm64/spawn-helper +0 -0
- package/prebuilds/darwin-x64/pty.node +0 -0
- package/prebuilds/darwin-x64/spawn-helper +0 -0
- package/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
- package/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
- package/prebuilds/win32-arm64/conpty.node +0 -0
- package/prebuilds/win32-arm64/conpty.pdb +0 -0
- package/prebuilds/win32-arm64/conpty_console_list.node +0 -0
- package/prebuilds/win32-arm64/conpty_console_list.pdb +0 -0
- package/prebuilds/win32-arm64/pty.node +0 -0
- package/prebuilds/win32-arm64/pty.pdb +0 -0
- package/prebuilds/win32-arm64/winpty-agent.exe +0 -0
- package/prebuilds/win32-arm64/winpty-agent.pdb +0 -0
- package/prebuilds/win32-arm64/winpty.dll +0 -0
- package/prebuilds/win32-arm64/winpty.pdb +0 -0
- package/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
- package/prebuilds/win32-x64/conpty/conpty.dll +0 -0
- package/prebuilds/win32-x64/conpty.node +0 -0
- package/prebuilds/win32-x64/conpty.pdb +0 -0
- package/prebuilds/win32-x64/conpty_console_list.node +0 -0
- package/prebuilds/win32-x64/conpty_console_list.pdb +0 -0
- package/prebuilds/win32-x64/pty.node +0 -0
- package/prebuilds/win32-x64/pty.pdb +0 -0
- package/prebuilds/win32-x64/winpty-agent.exe +0 -0
- package/prebuilds/win32-x64/winpty-agent.pdb +0 -0
- package/prebuilds/win32-x64/winpty.dll +0 -0
- package/prebuilds/win32-x64/winpty.pdb +0 -0
- package/scripts/gen-compile-commands.js +8 -0
- package/scripts/increment-version.js +54 -0
- package/scripts/post-install.js +99 -0
- package/scripts/prebuild.js +39 -0
- package/scripts/sync-prebuild.js +31 -0
- package/scripts/verify-darwin-fd-leak.js +63 -0
- package/src/conpty_console_list_agent.ts +15 -0
- package/src/eventEmitter2.test.ts +30 -0
- package/src/eventEmitter2.ts +48 -0
- package/src/index.ts +52 -0
- package/src/interfaces.ts +130 -0
- package/src/native.d.ts +54 -0
- package/src/shared/conout.ts +15 -0
- package/src/terminal.test.ts +119 -0
- package/src/terminal.ts +211 -0
- package/src/testUtils.test.ts +23 -0
- package/src/tsconfig.json +22 -0
- package/src/types.ts +15 -0
- package/src/unix/pty.cc +808 -0
- package/src/unix/spawn-helper.cc +23 -0
- package/src/unixTerminal.test.ts +367 -0
- package/src/unixTerminal.ts +388 -0
- package/src/utils.ts +29 -0
- package/src/win/conpty.cc +583 -0
- package/src/win/conpty.h +41 -0
- package/src/win/conpty_console_list.cc +44 -0
- package/src/win/path_util.cc +95 -0
- package/src/win/path_util.h +26 -0
- package/src/win/winpty.cc +333 -0
- package/src/windowsConoutConnection.ts +82 -0
- package/src/windowsPtyAgent.test.ts +94 -0
- package/src/windowsPtyAgent.ts +321 -0
- package/src/windowsTerminal.test.ts +229 -0
- package/src/windowsTerminal.ts +203 -0
- package/src/worker/conoutSocketWorker.ts +22 -0
- package/third_party/conpty/1.23.251008001/win10-arm64/OpenConsole.exe +0 -0
- package/third_party/conpty/1.23.251008001/win10-arm64/conpty.dll +0 -0
- package/third_party/conpty/1.23.251008001/win10-x64/OpenConsole.exe +0 -0
- package/third_party/conpty/1.23.251008001/win10-x64/conpty.dll +0 -0
- package/typings/node-pty.d.ts +211 -0
|
@@ -0,0 +1,38 @@
|
|
|
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
|
|
@@ -0,0 +1,122 @@
|
|
|
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 "BackgroundDesktop.h"
|
|
22
|
+
|
|
23
|
+
#include <memory>
|
|
24
|
+
|
|
25
|
+
#include "DebugClient.h"
|
|
26
|
+
#include "StringUtil.h"
|
|
27
|
+
#include "WinptyException.h"
|
|
28
|
+
|
|
29
|
+
namespace {
|
|
30
|
+
|
|
31
|
+
static std::wstring getObjectName(HANDLE object) {
|
|
32
|
+
BOOL success;
|
|
33
|
+
DWORD lengthNeeded = 0;
|
|
34
|
+
GetUserObjectInformationW(object, UOI_NAME,
|
|
35
|
+
nullptr, 0,
|
|
36
|
+
&lengthNeeded);
|
|
37
|
+
ASSERT(lengthNeeded % sizeof(wchar_t) == 0);
|
|
38
|
+
std::unique_ptr<wchar_t[]> tmp(
|
|
39
|
+
new wchar_t[lengthNeeded / sizeof(wchar_t)]);
|
|
40
|
+
success = GetUserObjectInformationW(object, UOI_NAME,
|
|
41
|
+
tmp.get(), lengthNeeded,
|
|
42
|
+
nullptr);
|
|
43
|
+
if (!success) {
|
|
44
|
+
throwWindowsError(L"GetUserObjectInformationW failed");
|
|
45
|
+
}
|
|
46
|
+
return std::wstring(tmp.get());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static std::wstring getDesktopName(HWINSTA winsta, HDESK desk) {
|
|
50
|
+
return getObjectName(winsta) + L"\\" + getObjectName(desk);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
} // anonymous namespace
|
|
54
|
+
|
|
55
|
+
// Get a non-interactive window station for the agent.
|
|
56
|
+
// TODO: review security w.r.t. windowstation and desktop.
|
|
57
|
+
BackgroundDesktop::BackgroundDesktop() {
|
|
58
|
+
try {
|
|
59
|
+
m_originalStation = GetProcessWindowStation();
|
|
60
|
+
if (m_originalStation == nullptr) {
|
|
61
|
+
throwWindowsError(
|
|
62
|
+
L"BackgroundDesktop ctor: "
|
|
63
|
+
L"GetProcessWindowStation returned NULL");
|
|
64
|
+
}
|
|
65
|
+
m_newStation =
|
|
66
|
+
CreateWindowStationW(nullptr, 0, WINSTA_ALL_ACCESS, nullptr);
|
|
67
|
+
if (m_newStation == nullptr) {
|
|
68
|
+
throwWindowsError(
|
|
69
|
+
L"BackgroundDesktop ctor: CreateWindowStationW returned NULL");
|
|
70
|
+
}
|
|
71
|
+
if (!SetProcessWindowStation(m_newStation)) {
|
|
72
|
+
throwWindowsError(
|
|
73
|
+
L"BackgroundDesktop ctor: SetProcessWindowStation failed");
|
|
74
|
+
}
|
|
75
|
+
m_newDesktop = CreateDesktopW(
|
|
76
|
+
L"Default", nullptr, nullptr, 0, GENERIC_ALL, nullptr);
|
|
77
|
+
if (m_newDesktop == nullptr) {
|
|
78
|
+
throwWindowsError(
|
|
79
|
+
L"BackgroundDesktop ctor: CreateDesktopW failed");
|
|
80
|
+
}
|
|
81
|
+
m_newDesktopName = getDesktopName(m_newStation, m_newDesktop);
|
|
82
|
+
TRACE("Created background desktop: %s",
|
|
83
|
+
utf8FromWide(m_newDesktopName).c_str());
|
|
84
|
+
} catch (...) {
|
|
85
|
+
dispose();
|
|
86
|
+
throw;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
void BackgroundDesktop::dispose() WINPTY_NOEXCEPT {
|
|
91
|
+
if (m_originalStation != nullptr) {
|
|
92
|
+
SetProcessWindowStation(m_originalStation);
|
|
93
|
+
m_originalStation = nullptr;
|
|
94
|
+
}
|
|
95
|
+
if (m_newDesktop != nullptr) {
|
|
96
|
+
CloseDesktop(m_newDesktop);
|
|
97
|
+
m_newDesktop = nullptr;
|
|
98
|
+
}
|
|
99
|
+
if (m_newStation != nullptr) {
|
|
100
|
+
CloseWindowStation(m_newStation);
|
|
101
|
+
m_newStation = nullptr;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
std::wstring getCurrentDesktopName() {
|
|
106
|
+
// MSDN says that the handles returned by GetProcessWindowStation and
|
|
107
|
+
// GetThreadDesktop do not need to be passed to CloseWindowStation and
|
|
108
|
+
// CloseDesktop, respectively.
|
|
109
|
+
const HWINSTA winsta = GetProcessWindowStation();
|
|
110
|
+
if (winsta == nullptr) {
|
|
111
|
+
throwWindowsError(
|
|
112
|
+
L"getCurrentDesktopName: "
|
|
113
|
+
L"GetProcessWindowStation returned NULL");
|
|
114
|
+
}
|
|
115
|
+
const HDESK desk = GetThreadDesktop(GetCurrentThreadId());
|
|
116
|
+
if (desk == nullptr) {
|
|
117
|
+
throwWindowsError(
|
|
118
|
+
L"getCurrentDesktopName: "
|
|
119
|
+
L"GetThreadDesktop returned NULL");
|
|
120
|
+
}
|
|
121
|
+
return getDesktopName(winsta, desk);
|
|
122
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
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 <windows.h>
|
|
25
|
+
|
|
26
|
+
#include <string>
|
|
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
|
|
@@ -0,0 +1,103 @@
|
|
|
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 "Buffer.h"
|
|
22
|
+
|
|
23
|
+
#include <stdint.h>
|
|
24
|
+
|
|
25
|
+
#include "DebugClient.h"
|
|
26
|
+
#include "WinptyAssert.h"
|
|
27
|
+
|
|
28
|
+
// Define the READ_BUFFER_CHECK() macro. It *must* evaluate its condition,
|
|
29
|
+
// exactly once.
|
|
30
|
+
#define READ_BUFFER_CHECK(cond) \
|
|
31
|
+
do { \
|
|
32
|
+
if (!(cond)) { \
|
|
33
|
+
trace("decode error: %s", #cond); \
|
|
34
|
+
throw DecodeError(); \
|
|
35
|
+
} \
|
|
36
|
+
} while (false)
|
|
37
|
+
|
|
38
|
+
enum class Piece : uint8_t { Int32, Int64, WString };
|
|
39
|
+
|
|
40
|
+
void WriteBuffer::putRawData(const void *data, size_t len) {
|
|
41
|
+
const auto p = reinterpret_cast<const char*>(data);
|
|
42
|
+
m_buf.insert(m_buf.end(), p, p + len);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
void WriteBuffer::replaceRawData(size_t pos, const void *data, size_t len) {
|
|
46
|
+
ASSERT(pos <= m_buf.size() && len <= m_buf.size() - pos);
|
|
47
|
+
const auto p = reinterpret_cast<const char*>(data);
|
|
48
|
+
std::copy(p, p + len, &m_buf[pos]);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
void WriteBuffer::putInt32(int32_t i) {
|
|
52
|
+
putRawValue(Piece::Int32);
|
|
53
|
+
putRawValue(i);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void WriteBuffer::putInt64(int64_t i) {
|
|
57
|
+
putRawValue(Piece::Int64);
|
|
58
|
+
putRawValue(i);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// len is in characters, excluding NUL, i.e. the number of wchar_t elements
|
|
62
|
+
void WriteBuffer::putWString(const wchar_t *str, size_t len) {
|
|
63
|
+
putRawValue(Piece::WString);
|
|
64
|
+
putRawValue(static_cast<uint64_t>(len));
|
|
65
|
+
putRawData(str, sizeof(wchar_t) * len);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void ReadBuffer::getRawData(void *data, size_t len) {
|
|
69
|
+
ASSERT(m_off <= m_buf.size());
|
|
70
|
+
READ_BUFFER_CHECK(len <= m_buf.size() - m_off);
|
|
71
|
+
const char *const inp = &m_buf[m_off];
|
|
72
|
+
std::copy(inp, inp + len, reinterpret_cast<char*>(data));
|
|
73
|
+
m_off += len;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
int32_t ReadBuffer::getInt32() {
|
|
77
|
+
READ_BUFFER_CHECK(getRawValue<Piece>() == Piece::Int32);
|
|
78
|
+
return getRawValue<int32_t>();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
int64_t ReadBuffer::getInt64() {
|
|
82
|
+
READ_BUFFER_CHECK(getRawValue<Piece>() == Piece::Int64);
|
|
83
|
+
return getRawValue<int64_t>();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
std::wstring ReadBuffer::getWString() {
|
|
87
|
+
READ_BUFFER_CHECK(getRawValue<Piece>() == Piece::WString);
|
|
88
|
+
const uint64_t charLen = getRawValue<uint64_t>();
|
|
89
|
+
READ_BUFFER_CHECK(charLen <= SIZE_MAX / sizeof(wchar_t));
|
|
90
|
+
// To be strictly conforming, we can't use the convenient wstring
|
|
91
|
+
// constructor, because the string in m_buf mightn't be aligned.
|
|
92
|
+
std::wstring ret;
|
|
93
|
+
if (charLen > 0) {
|
|
94
|
+
const size_t byteLen = charLen * sizeof(wchar_t);
|
|
95
|
+
ret.resize(charLen);
|
|
96
|
+
getRawData(&ret[0], byteLen);
|
|
97
|
+
}
|
|
98
|
+
return ret;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
void ReadBuffer::assertEof() {
|
|
102
|
+
READ_BUFFER_CHECK(m_off == m_buf.size());
|
|
103
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
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 <stdint.h>
|
|
25
|
+
#include <string.h>
|
|
26
|
+
|
|
27
|
+
#include <algorithm>
|
|
28
|
+
#include <utility>
|
|
29
|
+
#include <vector>
|
|
30
|
+
#include <string>
|
|
31
|
+
|
|
32
|
+
#include "WinptyException.h"
|
|
33
|
+
|
|
34
|
+
class WriteBuffer {
|
|
35
|
+
private:
|
|
36
|
+
std::vector<char> m_buf;
|
|
37
|
+
|
|
38
|
+
public:
|
|
39
|
+
WriteBuffer() {}
|
|
40
|
+
|
|
41
|
+
template <typename T> void putRawValue(const T &t) {
|
|
42
|
+
putRawData(&t, sizeof(t));
|
|
43
|
+
}
|
|
44
|
+
template <typename T> 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<char> &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<char> m_buf;
|
|
75
|
+
size_t m_off = 0;
|
|
76
|
+
|
|
77
|
+
public:
|
|
78
|
+
explicit ReadBuffer(std::vector<char> &&buf) : m_buf(std::move(buf)) {}
|
|
79
|
+
|
|
80
|
+
template <typename T> 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
|
|
@@ -0,0 +1,187 @@
|
|
|
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 "DebugClient.h"
|
|
22
|
+
|
|
23
|
+
#include <windows.h>
|
|
24
|
+
#include <stdio.h>
|
|
25
|
+
#include <stdlib.h>
|
|
26
|
+
#include <string.h>
|
|
27
|
+
|
|
28
|
+
#include <algorithm>
|
|
29
|
+
#include <string>
|
|
30
|
+
|
|
31
|
+
#include "winpty_snprintf.h"
|
|
32
|
+
|
|
33
|
+
const wchar_t *const kPipeName = L"\\\\.\\pipe\\DebugServer";
|
|
34
|
+
|
|
35
|
+
void *volatile g_debugConfig;
|
|
36
|
+
|
|
37
|
+
namespace {
|
|
38
|
+
|
|
39
|
+
// It would be easy to accidentally trample on the Windows LastError value
|
|
40
|
+
// by adding logging/debugging code. Ensure that can't happen by saving and
|
|
41
|
+
// restoring the value. This saving and restoring doesn't happen along the
|
|
42
|
+
// fast path.
|
|
43
|
+
class PreserveLastError {
|
|
44
|
+
public:
|
|
45
|
+
PreserveLastError() : m_lastError(GetLastError()) {}
|
|
46
|
+
~PreserveLastError() { SetLastError(m_lastError); }
|
|
47
|
+
private:
|
|
48
|
+
DWORD m_lastError;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
} // anonymous namespace
|
|
52
|
+
|
|
53
|
+
static void sendToDebugServer(const char *message)
|
|
54
|
+
{
|
|
55
|
+
HANDLE tracePipe = INVALID_HANDLE_VALUE;
|
|
56
|
+
|
|
57
|
+
do {
|
|
58
|
+
// The default impersonation level is SECURITY_IMPERSONATION, which allows
|
|
59
|
+
// a sufficiently authorized named pipe server to impersonate the client.
|
|
60
|
+
// There's no need for impersonation in this debugging system, so reduce
|
|
61
|
+
// the impersonation level to SECURITY_IDENTIFICATION, which allows a
|
|
62
|
+
// server to merely identify us.
|
|
63
|
+
tracePipe = CreateFileW(
|
|
64
|
+
kPipeName,
|
|
65
|
+
GENERIC_READ | GENERIC_WRITE,
|
|
66
|
+
0, NULL, OPEN_EXISTING,
|
|
67
|
+
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION,
|
|
68
|
+
NULL);
|
|
69
|
+
} while (tracePipe == INVALID_HANDLE_VALUE &&
|
|
70
|
+
GetLastError() == ERROR_PIPE_BUSY &&
|
|
71
|
+
WaitNamedPipeW(kPipeName, NMPWAIT_WAIT_FOREVER));
|
|
72
|
+
|
|
73
|
+
if (tracePipe != INVALID_HANDLE_VALUE) {
|
|
74
|
+
DWORD newMode = PIPE_READMODE_MESSAGE;
|
|
75
|
+
SetNamedPipeHandleState(tracePipe, &newMode, NULL, NULL);
|
|
76
|
+
char response[16];
|
|
77
|
+
DWORD actual = 0;
|
|
78
|
+
TransactNamedPipe(tracePipe,
|
|
79
|
+
const_cast<char*>(message), strlen(message),
|
|
80
|
+
response, sizeof(response), &actual, NULL);
|
|
81
|
+
CloseHandle(tracePipe);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Get the current UTC time as milliseconds from the epoch (ignoring leap
|
|
86
|
+
// seconds). Use the Unix epoch for consistency with DebugClient.py. There
|
|
87
|
+
// are 134774 days between 1601-01-01 (the Win32 epoch) and 1970-01-01 (the
|
|
88
|
+
// Unix epoch).
|
|
89
|
+
static long long unixTimeMillis()
|
|
90
|
+
{
|
|
91
|
+
FILETIME fileTime;
|
|
92
|
+
GetSystemTimeAsFileTime(&fileTime);
|
|
93
|
+
long long msTime = (((long long)fileTime.dwHighDateTime << 32) +
|
|
94
|
+
fileTime.dwLowDateTime) / 10000;
|
|
95
|
+
return msTime - 134774LL * 24 * 3600 * 1000;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static const char *getDebugConfig()
|
|
99
|
+
{
|
|
100
|
+
if (g_debugConfig == NULL) {
|
|
101
|
+
PreserveLastError preserve;
|
|
102
|
+
const int bufSize = 256;
|
|
103
|
+
char buf[bufSize];
|
|
104
|
+
DWORD actualSize =
|
|
105
|
+
GetEnvironmentVariableA("WINPTY_DEBUG", buf, bufSize);
|
|
106
|
+
if (actualSize == 0 || actualSize >= static_cast<DWORD>(bufSize)) {
|
|
107
|
+
buf[0] = '\0';
|
|
108
|
+
}
|
|
109
|
+
const size_t len = strlen(buf) + 1;
|
|
110
|
+
char *newConfig = new char[len];
|
|
111
|
+
std::copy(buf, buf + len, newConfig);
|
|
112
|
+
void *oldValue = InterlockedCompareExchangePointer(
|
|
113
|
+
&g_debugConfig, newConfig, NULL);
|
|
114
|
+
if (oldValue != NULL) {
|
|
115
|
+
delete [] newConfig;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return static_cast<const char*>(g_debugConfig);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
bool isTracingEnabled()
|
|
122
|
+
{
|
|
123
|
+
static bool disabled, enabled;
|
|
124
|
+
if (disabled) {
|
|
125
|
+
return false;
|
|
126
|
+
} else if (enabled) {
|
|
127
|
+
return true;
|
|
128
|
+
} else {
|
|
129
|
+
// Recognize WINPTY_DEBUG=1 for backwards compatibility.
|
|
130
|
+
PreserveLastError preserve;
|
|
131
|
+
bool value = hasDebugFlag("trace") || hasDebugFlag("1");
|
|
132
|
+
disabled = !value;
|
|
133
|
+
enabled = value;
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
bool hasDebugFlag(const char *flag)
|
|
139
|
+
{
|
|
140
|
+
if (strchr(flag, ',') != NULL) {
|
|
141
|
+
trace("INTERNAL ERROR: hasDebugFlag flag has comma: '%s'", flag);
|
|
142
|
+
abort();
|
|
143
|
+
}
|
|
144
|
+
const char *const configCStr = getDebugConfig();
|
|
145
|
+
if (configCStr[0] == '\0') {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
PreserveLastError preserve;
|
|
149
|
+
std::string config(configCStr);
|
|
150
|
+
std::string flagStr(flag);
|
|
151
|
+
config = "," + config + ",";
|
|
152
|
+
flagStr = "," + flagStr + ",";
|
|
153
|
+
return config.find(flagStr) != std::string::npos;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
void trace(const char *format, ...)
|
|
157
|
+
{
|
|
158
|
+
if (!isTracingEnabled())
|
|
159
|
+
return;
|
|
160
|
+
|
|
161
|
+
PreserveLastError preserve;
|
|
162
|
+
char message[1024];
|
|
163
|
+
|
|
164
|
+
va_list ap;
|
|
165
|
+
va_start(ap, format);
|
|
166
|
+
winpty_vsnprintf(message, format, ap);
|
|
167
|
+
message[sizeof(message) - 1] = '\0';
|
|
168
|
+
va_end(ap);
|
|
169
|
+
|
|
170
|
+
const int currentTime = (int)(unixTimeMillis() % (100000 * 1000));
|
|
171
|
+
|
|
172
|
+
char moduleName[1024];
|
|
173
|
+
moduleName[0] = '\0';
|
|
174
|
+
GetModuleFileNameA(NULL, moduleName, sizeof(moduleName));
|
|
175
|
+
const char *baseName = strrchr(moduleName, '\\');
|
|
176
|
+
baseName = (baseName != NULL) ? baseName + 1 : moduleName;
|
|
177
|
+
|
|
178
|
+
char fullMessage[1024];
|
|
179
|
+
winpty_snprintf(fullMessage,
|
|
180
|
+
"[%05d.%03d %s,p%04d,t%04d]: %s",
|
|
181
|
+
currentTime / 1000, currentTime % 1000,
|
|
182
|
+
baseName, (int)GetCurrentProcessId(), (int)GetCurrentThreadId(),
|
|
183
|
+
message);
|
|
184
|
+
fullMessage[sizeof(fullMessage) - 1] = '\0';
|
|
185
|
+
|
|
186
|
+
sendToDebugServer(fullMessage);
|
|
187
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|