buninu-linux 0.7.2 → 0.7.3
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/initramfs/buninu/CHANGELOG.md +5 -0
- package/initramfs/buninu/apps/bunmsh/CHANGELOG.md +15 -0
- package/initramfs/buninu/apps/bunmsh/PORTING.md +6 -2
- package/initramfs/buninu/apps/bunmsh/help/README.md +3 -1
- package/initramfs/buninu/apps/bunmsh/help/ln.md +3 -1
- package/initramfs/buninu/apps/bunmsh/package.json +1 -1
- package/initramfs/buninu/apps/bunmsh/src/shell.js +173 -84
- package/initramfs/buninu/apps/bunmsh/test/reference.test.js +95 -1
- package/initramfs/buninu/apps/bunmsh/test/shell1.test.js +91 -0
- package/initramfs/buninu/apps/jsgotty/LICENSES/MIT-microsoft-terminal-conpty.txt +21 -0
- package/initramfs/buninu/apps/jsgotty/LICENSES/MIT-ws.txt +20 -0
- package/initramfs/buninu/apps/jsgotty/LICENSES/NOTICE-microsoft-terminal-conpty.md +535 -0
- package/initramfs/buninu/apps/jsgotty/NOTICE +100 -0
- package/initramfs/buninu/apps/jsgotty/conpty/OpenConsole.exe +0 -0
- package/initramfs/buninu/apps/jsgotty/conpty/conpty.dll +0 -0
- package/initramfs/buninu/apps/jsgotty/gotty.js +24 -0
- package/initramfs/buninu/apps/jsgotty/package-lock.json +2 -2
- package/initramfs/buninu/apps/jsgotty/package.json +6 -2
- package/initramfs/buninu/apps/jsgotty/windows-conpty.js +135 -0
- package/initramfs/buninu/package.json +1 -1
- package/package.json +1 -1
|
@@ -19,3 +19,103 @@ Included third-party component:
|
|
|
19
19
|
|
|
20
20
|
The bundled file [static/js/zmodem.js] is byte-for-byte identical to the
|
|
21
21
|
upstream npm release zmodem.js version 0.1.10 dist/zmodem.js.
|
|
22
|
+
|
|
23
|
+
2. ConPTY - Windows pseudoconsole library and console host
|
|
24
|
+
(conpty/conpty.dll, conpty/OpenConsole.exe), part of Windows Terminal
|
|
25
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
26
|
+
Licensed under the MIT License
|
|
27
|
+
Upstream: https://github.com/microsoft/terminal
|
|
28
|
+
Local copy of license text:
|
|
29
|
+
LICENSES/MIT-microsoft-terminal-conpty.txt
|
|
30
|
+
Upstream third-party notices for Windows Terminal:
|
|
31
|
+
LICENSES/NOTICE-microsoft-terminal-conpty.md
|
|
32
|
+
|
|
33
|
+
The bundled files in [conpty/] are byte-for-byte identical to the win-x64
|
|
34
|
+
binaries in the official NuGet package
|
|
35
|
+
Microsoft.Windows.Console.ConPTY 1.25.260710002-preview, published with the
|
|
36
|
+
Windows Terminal Preview v1.25.1912.0 release
|
|
37
|
+
(https://github.com/microsoft/terminal/releases/tag/v1.25.1912.0):
|
|
38
|
+
|
|
39
|
+
conpty/conpty.dll (runtimes/win-x64/native/conpty.dll)
|
|
40
|
+
SHA-256 e2fe87e2258c4e46ffc5157f727218cc25f34a174902f72eb8a5b49edd9a6458
|
|
41
|
+
conpty/OpenConsole.exe (build/native/runtimes/x64/OpenConsole.exe)
|
|
42
|
+
SHA-256 2525c351aa136d555e5df9a3c9d6ce9be43f785e37e3c993b8f23b3f0a53c7fa
|
|
43
|
+
|
|
44
|
+
The license and notice files are taken verbatim from the microsoft/terminal
|
|
45
|
+
repository at tag v1.25.1912.0. The notice file lists third-party components
|
|
46
|
+
used across Windows Terminal; it is included in full because the subset built
|
|
47
|
+
into these two binaries is not documented separately.
|
|
48
|
+
|
|
49
|
+
3. node-pty 1.1.0 - forkpty(3) bindings for Node.js (lib/node-pty)
|
|
50
|
+
Copyright (c) 2012-2015, Christopher Jeffrey
|
|
51
|
+
Copyright (c) 2016, Daniel Imms
|
|
52
|
+
Copyright (c) 2018 - present Microsoft Corporation
|
|
53
|
+
Licensed under the MIT License
|
|
54
|
+
Upstream: https://github.com/microsoft/node-pty
|
|
55
|
+
License text: lib/node-pty/LICENSE
|
|
56
|
+
|
|
57
|
+
node-pty in turn bundles:
|
|
58
|
+
|
|
59
|
+
a. winpty 0.4.4-dev (lib/node-pty/deps/winpty,
|
|
60
|
+
lib/node-pty/prebuilds/win32-*/winpty.dll and winpty-agent.exe)
|
|
61
|
+
Copyright (c) 2011-2016 Ryan Prichard
|
|
62
|
+
Licensed under the MIT License
|
|
63
|
+
Upstream: https://github.com/rprichard/winpty
|
|
64
|
+
License text: lib/node-pty/deps/winpty/LICENSE
|
|
65
|
+
|
|
66
|
+
b. ConPTY 1.23.251008001 from Windows Terminal
|
|
67
|
+
(lib/node-pty/prebuilds/win32-*/conpty/conpty.dll and OpenConsole.exe)
|
|
68
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
69
|
+
Licensed under the MIT License; see item 2 for the license and
|
|
70
|
+
Windows Terminal notice files.
|
|
71
|
+
|
|
72
|
+
The prebuilt binaries under [lib/node-pty/prebuilds] and the license files
|
|
73
|
+
lib/node-pty/LICENSE and lib/node-pty/deps/winpty/LICENSE are byte-for-byte
|
|
74
|
+
identical to those in the upstream npm release node-pty 1.1.0; they are not
|
|
75
|
+
rebuilt by this project.
|
|
76
|
+
|
|
77
|
+
The files in [patches/] (windowsPtyAgent.js, windowsTerminal.js) are modified
|
|
78
|
+
copies of node-pty source files; they keep node-pty's copyright headers and
|
|
79
|
+
remain under its MIT License.
|
|
80
|
+
|
|
81
|
+
4. npm dependencies committed under [node_modules/]
|
|
82
|
+
|
|
83
|
+
a. ws 8.21.0 - WebSocket client and server
|
|
84
|
+
Copyright (c) 2011 Einar Otto Stangvik
|
|
85
|
+
Copyright (c) 2013 Arnout Kazemier and contributors
|
|
86
|
+
Copyright (c) 2016 Luigi Pinca and contributors
|
|
87
|
+
Licensed under the MIT License
|
|
88
|
+
License text: node_modules/ws/LICENSE (also LICENSES/MIT-ws.txt,
|
|
89
|
+
which single executables carry because ws is bundled into them)
|
|
90
|
+
|
|
91
|
+
b. node-addon-api 7.1.1 - C++ headers used to build node-pty
|
|
92
|
+
Copyright (c) 2017 Node.js API collaborators
|
|
93
|
+
Licensed under the MIT License
|
|
94
|
+
License text: node_modules/node-addon-api/LICENSE.md
|
|
95
|
+
|
|
96
|
+
5. Web client assets under [static/]
|
|
97
|
+
|
|
98
|
+
static/js/gotty.js is a webpack bundle. The licenses of every package it
|
|
99
|
+
contains (xterm.js and its fit, web-links, webgl and unicode11 addons,
|
|
100
|
+
Bootstrap, Popper, Preact, crc-32, zmodem.js, css-loader, style-loader)
|
|
101
|
+
are listed in static/js/gotty.licenses.txt, with the retained banners in
|
|
102
|
+
static/js/gotty.js.LICENSE.txt.
|
|
103
|
+
|
|
104
|
+
static/js/xterm-addon-unicode11.js is byte-for-byte identical to
|
|
105
|
+
lib/addon-unicode11.js of the npm release @xterm/addon-unicode11 0.9.0, and
|
|
106
|
+
static/css/xterm.css comes from xterm.js
|
|
107
|
+
(Copyright (c) 2014 The xterm.js authors; Copyright (c) 2012-2013
|
|
108
|
+
Christopher Jeffrey; MIT License, text in static/js/gotty.licenses.txt).
|
|
109
|
+
|
|
110
|
+
static/favicon.ico, static/icon.svg and static/icon_192.png are
|
|
111
|
+
byte-for-byte identical to the icons of GoTTY
|
|
112
|
+
(https://github.com/sorenisanerd/gotty), covered by the MIT License and
|
|
113
|
+
the GoTTY copyright notices in LICENSE.
|
|
114
|
+
|
|
115
|
+
Single executables built with --build-exe / --build-for embed the Bun
|
|
116
|
+
runtime. Bun is MIT-licensed but statically links JavaScriptCore and WebKit
|
|
117
|
+
(LGPL-2) and other libraries under their own licenses; anyone distributing
|
|
118
|
+
such an executable must also follow Bun's license terms, including the LGPL
|
|
119
|
+
relinking provisions described at
|
|
120
|
+
https://github.com/oven-sh/bun/blob/main/LICENSE.md. The executables carry
|
|
121
|
+
LICENSE, NOTICE and LICENSES/ as embedded assets.
|
|
Binary file
|
|
Binary file
|
|
@@ -115,6 +115,26 @@ function assetFilePath(key) {
|
|
|
115
115
|
return assets ? assets.assetDiskPath(key) : path.join(__dirname, key);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
function windowsConptyDllPath() {
|
|
119
|
+
const dll = assetFilePath("conpty/conpty.dll");
|
|
120
|
+
if (fs.existsSync(dll)) return dll;
|
|
121
|
+
if (!assets) return null;
|
|
122
|
+
try {
|
|
123
|
+
const dllBytes = assets.readAssetBytesSync("conpty/conpty.dll");
|
|
124
|
+
const hostBytes = assets.readAssetBytesSync("conpty/OpenConsole.exe");
|
|
125
|
+
const version = crypto.createHash("sha256").update(dllBytes).digest("hex").slice(0, 16);
|
|
126
|
+
const dir = path.join(os.tmpdir(), `jsgotty-conpty-${version}`);
|
|
127
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
128
|
+
for (const [name, bytes] of [["conpty.dll", dllBytes], ["OpenConsole.exe", hostBytes]]) {
|
|
129
|
+
const dest = path.join(dir, name);
|
|
130
|
+
if (!fs.existsSync(dest)) fs.writeFileSync(dest, bytes);
|
|
131
|
+
}
|
|
132
|
+
return path.join(dir, "conpty.dll");
|
|
133
|
+
} catch (error) {
|
|
134
|
+
throw new Error(`Could not prepare bundled ConPTY: ${error.message}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
118
138
|
// URL-relative path -> asset key, or null when it escapes `static/`.
|
|
119
139
|
// Normalizing against "/" is what makes "../../etc/passwd" unreachable.
|
|
120
140
|
function staticAssetKey(relativePath) {
|
|
@@ -1624,6 +1644,10 @@ function createPtyBackend(options) {
|
|
|
1624
1644
|
if (globalThis.Bun?.semver?.satisfies?.(
|
|
1625
1645
|
globalThis.Bun?.version, ">=1.3.14"
|
|
1626
1646
|
)) {
|
|
1647
|
+
const conptyDll = windowsConptyDllPath();
|
|
1648
|
+
if (conptyDll) {
|
|
1649
|
+
return new (require("./windows-conpty.js"))(options, conptyDll);
|
|
1650
|
+
}
|
|
1627
1651
|
return new BunPtyBackend(options);
|
|
1628
1652
|
}
|
|
1629
1653
|
return new NodePtyBackend(options);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsgotty",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.14",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "jsgotty",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.14",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"node-addon-api": "^7.1.1",
|
|
12
12
|
"ws": "^8.18.3"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsgotty",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.14",
|
|
4
4
|
"description": "Share your terminal as a web application: A JavaScript rewrite of GoTTY",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -8,9 +8,13 @@
|
|
|
8
8
|
},
|
|
9
9
|
"type": "commonjs",
|
|
10
10
|
"assets": [
|
|
11
|
+
"conpty",
|
|
11
12
|
"static",
|
|
12
13
|
"README.md",
|
|
13
|
-
"README.en.md"
|
|
14
|
+
"README.en.md",
|
|
15
|
+
"LICENSE",
|
|
16
|
+
"NOTICE",
|
|
17
|
+
"LICENSES"
|
|
14
18
|
],
|
|
15
19
|
"dependencies": {
|
|
16
20
|
"node-addon-api": "^7.1.1",
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// Windows PTY adapter for the out-of-band Microsoft Console package.
|
|
2
|
+
// Keep the same interface as BunPtyBackend in gotty.js.
|
|
3
|
+
const { dlopen, ptr } = require("bun:ffi");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
const kernel = dlopen("kernel32.dll", {
|
|
7
|
+
CreatePipe: { args: ["ptr", "ptr", "ptr", "u32"], returns: "i32" },
|
|
8
|
+
InitializeProcThreadAttributeList: { args: ["ptr", "u32", "u32", "ptr"], returns: "i32" },
|
|
9
|
+
UpdateProcThreadAttribute: { args: ["ptr", "u32", "usize", "ptr", "usize", "ptr", "ptr"], returns: "i32" },
|
|
10
|
+
DeleteProcThreadAttributeList: { args: ["ptr"], returns: "void" },
|
|
11
|
+
CreateProcessW: { args: ["ptr", "ptr", "ptr", "ptr", "i32", "u32", "ptr", "ptr", "ptr", "ptr"], returns: "i32" },
|
|
12
|
+
PeekNamedPipe: { args: ["ptr", "ptr", "u32", "ptr", "ptr", "ptr"], returns: "i32" },
|
|
13
|
+
ReadFile: { args: ["ptr", "ptr", "u32", "ptr", "ptr"], returns: "i32" },
|
|
14
|
+
WriteFile: { args: ["ptr", "ptr", "u32", "ptr", "ptr"], returns: "i32" },
|
|
15
|
+
GetExitCodeProcess: { args: ["ptr", "ptr"], returns: "i32" },
|
|
16
|
+
TerminateProcess: { args: ["ptr", "u32"], returns: "i32" },
|
|
17
|
+
CloseHandle: { args: ["ptr"], returns: "i32" },
|
|
18
|
+
GetLastError: { args: [], returns: "u32" },
|
|
19
|
+
}).symbols;
|
|
20
|
+
|
|
21
|
+
const conptySymbols = {
|
|
22
|
+
ConptyCreatePseudoConsole: { args: ["u32", "ptr", "ptr", "u32", "ptr"], returns: "i32" },
|
|
23
|
+
ConptyResizePseudoConsole: { args: ["ptr", "u32"], returns: "i32" },
|
|
24
|
+
ConptyClosePseudoConsole: { args: ["ptr"], returns: "void" },
|
|
25
|
+
};
|
|
26
|
+
const wide = (value) => Buffer.from(`${value}\0`, "utf16le");
|
|
27
|
+
const handle = (buffer) => Number(buffer.readBigUInt64LE(0));
|
|
28
|
+
const size = (cols, rows) => ((Math.max(1, rows) & 0xffff) << 16) | (Math.max(1, cols) & 0xffff);
|
|
29
|
+
const winError = (operation) => new Error(`${operation} failed: ${kernel.GetLastError()}`);
|
|
30
|
+
// Windows CRT argv escaping: double backslashes before quotes and at the end.
|
|
31
|
+
function quoteArg(value) {
|
|
32
|
+
let result = '"', slashes = 0;
|
|
33
|
+
for (const char of String(value)) {
|
|
34
|
+
if (char === "\\") { slashes++; continue; }
|
|
35
|
+
if (char === '"') result += "\\".repeat(slashes * 2 + 1) + '"';
|
|
36
|
+
else result += "\\".repeat(slashes) + char;
|
|
37
|
+
slashes = 0;
|
|
38
|
+
}
|
|
39
|
+
return result + "\\".repeat(slashes * 2) + '"';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
class WindowsConptyBackend {
|
|
43
|
+
constructor(options, dllPath) {
|
|
44
|
+
this.options = options;
|
|
45
|
+
this.dataHandlers = [];
|
|
46
|
+
this.exitHandlers = [];
|
|
47
|
+
this.closed = false;
|
|
48
|
+
this.conpty = dlopen(path.resolve(dllPath), conptySymbols).symbols;
|
|
49
|
+
const inputRead = Buffer.alloc(8), inputWrite = Buffer.alloc(8);
|
|
50
|
+
const outputRead = Buffer.alloc(8), outputWrite = Buffer.alloc(8);
|
|
51
|
+
if (!kernel.CreatePipe(inputRead, inputWrite, 0, 0)) throw winError("CreatePipe input");
|
|
52
|
+
if (!kernel.CreatePipe(outputRead, outputWrite, 0, 0)) throw winError("CreatePipe output");
|
|
53
|
+
this.input = handle(inputWrite);
|
|
54
|
+
this.output = handle(outputRead);
|
|
55
|
+
const pseudo = Buffer.alloc(8);
|
|
56
|
+
const hr = this.conpty.ConptyCreatePseudoConsole(
|
|
57
|
+
size(options.width || 80, options.height || 24), handle(inputRead), handle(outputWrite), 0, pseudo);
|
|
58
|
+
kernel.CloseHandle(handle(inputRead));
|
|
59
|
+
kernel.CloseHandle(handle(outputWrite));
|
|
60
|
+
if (hr !== 0) throw new Error(`ConptyCreatePseudoConsole failed: ${hr}`);
|
|
61
|
+
this.pseudo = handle(pseudo);
|
|
62
|
+
|
|
63
|
+
const listSize = Buffer.alloc(8);
|
|
64
|
+
kernel.InitializeProcThreadAttributeList(0, 1, 0, listSize);
|
|
65
|
+
const list = Buffer.alloc(Number(listSize.readBigUInt64LE(0)));
|
|
66
|
+
if (!kernel.InitializeProcThreadAttributeList(list, 1, 0, listSize)) throw winError("InitializeProcThreadAttributeList");
|
|
67
|
+
if (!kernel.UpdateProcThreadAttribute(list, 0, 0x00020016, this.pseudo, 8, 0, 0)) throw winError("UpdateProcThreadAttribute");
|
|
68
|
+
const startup = Buffer.alloc(112);
|
|
69
|
+
startup.writeUInt32LE(112, 0);
|
|
70
|
+
startup.writeUInt32LE(0x100, 60); // STARTF_USESTDHANDLES
|
|
71
|
+
startup.writeBigUInt64LE(BigInt(ptr(list)), 104);
|
|
72
|
+
const processInfo = Buffer.alloc(24);
|
|
73
|
+
const env = { ...process.env, TERM: "xterm-256color", ...(options.headerEnv || {}) };
|
|
74
|
+
const envBlock = wide(Object.entries(env).filter(([key]) => !key.startsWith("="))
|
|
75
|
+
.map(([key, value]) => `${key}=${value}`).join("\0") + "\0");
|
|
76
|
+
const executable = Bun.which(options.command) || options.command;
|
|
77
|
+
const command = wide([executable, ...options.argv].map(quoteArg).join(" "));
|
|
78
|
+
const ok = kernel.CreateProcessW(wide(executable), command, 0, 0, 0,
|
|
79
|
+
0x00080000 | 0x00000400, envBlock, wide(process.cwd()), startup, processInfo);
|
|
80
|
+
kernel.DeleteProcThreadAttributeList(list);
|
|
81
|
+
if (!ok) throw winError("CreateProcessW");
|
|
82
|
+
this.process = handle(processInfo);
|
|
83
|
+
this.pid = processInfo.readUInt32LE(16);
|
|
84
|
+
kernel.CloseHandle(Number(processInfo.readBigUInt64LE(8)));
|
|
85
|
+
this.pollTimer = setInterval(() => this.poll(), 5);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
onData(handler) { this.dataHandlers.push(handler); }
|
|
89
|
+
onExit(handler) { this.exitHandlers.push(handler); }
|
|
90
|
+
write(buffer) { this.writeBinary(buffer); }
|
|
91
|
+
writeBinary(buffer) {
|
|
92
|
+
const data = Buffer.from(buffer);
|
|
93
|
+
const written = Buffer.alloc(4);
|
|
94
|
+
for (let offset = 0; offset < data.length;) {
|
|
95
|
+
const chunk = data.subarray(offset);
|
|
96
|
+
if (!kernel.WriteFile(this.input, chunk, chunk.length, written, 0)) throw winError("WriteFile");
|
|
97
|
+
const count = written.readUInt32LE(0);
|
|
98
|
+
if (!count) throw new Error("WriteFile wrote no data");
|
|
99
|
+
offset += count;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
resize(cols, rows) {
|
|
103
|
+
const hr = this.conpty.ConptyResizePseudoConsole(this.pseudo, size(cols, rows));
|
|
104
|
+
if (hr !== 0) throw new Error(`ConptyResizePseudoConsole failed: ${hr}`);
|
|
105
|
+
}
|
|
106
|
+
kill() { if (!this.closed) kernel.TerminateProcess(this.process, 1); }
|
|
107
|
+
close() { this.kill(); }
|
|
108
|
+
|
|
109
|
+
poll() {
|
|
110
|
+
if (this.closed) return;
|
|
111
|
+
const available = Buffer.alloc(4), readCount = Buffer.alloc(4);
|
|
112
|
+
if (kernel.PeekNamedPipe(this.output, 0, 0, 0, available, 0)) {
|
|
113
|
+
for (let bytes = available.readUInt32LE(0); bytes > 0; bytes = available.readUInt32LE(0)) {
|
|
114
|
+
const data = Buffer.alloc(Math.min(bytes, 65536));
|
|
115
|
+
if (!kernel.ReadFile(this.output, data, data.length, readCount, 0)) break;
|
|
116
|
+
const count = readCount.readUInt32LE(0);
|
|
117
|
+
if (!count) break;
|
|
118
|
+
for (const handler of this.dataHandlers) handler(data.subarray(0, count));
|
|
119
|
+
if (!kernel.PeekNamedPipe(this.output, 0, 0, 0, available, 0)) break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const exitCode = Buffer.alloc(4);
|
|
123
|
+
if (kernel.GetExitCodeProcess(this.process, exitCode) && exitCode.readUInt32LE(0) !== 259) {
|
|
124
|
+
this.closed = true;
|
|
125
|
+
clearInterval(this.pollTimer);
|
|
126
|
+
this.conpty.ConptyClosePseudoConsole(this.pseudo);
|
|
127
|
+
kernel.CloseHandle(this.input);
|
|
128
|
+
kernel.CloseHandle(this.output);
|
|
129
|
+
kernel.CloseHandle(this.process);
|
|
130
|
+
for (const handler of this.exitHandlers) handler();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = WindowsConptyBackend;
|