Repository: retep998/winapi-rs (language: rust)

Issue:
Add support for the new ConPTY API
The API allows for communicating with CLI processes without passing through cmd.

~~It's currently only available on insider builds~~ and is only documented (as far as I can tell) in [this blog post](https://blogs.msdn.microsoft.com/commandline/2018/08/02/windows-command-line-introducing-the-windows-pseudo-console-conpty/).

I'm not sure what the policies for dealing with insider APIs is, but this would be very useful for the implementation of the API in alacritty. See the [downstream issue](https://github.com/zacps/alacritty/issues/25).


Discussion / hints:
I generally prefer to wait until there is a stable Windows SDK release with the definitions.
Yeah I thought that might be the case but couldn't find any issues about it.

Mind keeping this open until it gets stabilised? 
@zacps maybe make you own binding and let @retep998 "Embrace, extend, and extinguish" your crate finally
These functions are included in the 10.0.17763.0 release of the Win 10 SDK
More concretely, this is available on 1809 under the `Semi-Annual (Targeted)` channel.

The new functions are also documented [here](https://docs.microsoft.com/en-us/windows/console/console-functions).

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 5ece74b9a..6abcb6747 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -331,6 +331,7 @@ winbase = []
 wincodec = []
 wincodecsdk = []
 wincon = []
+wincontypes = []
 wincred = []
 wincrypt = []
 windowsceip = []
diff --git a/build.rs b/build.rs
index f7e0a3a48..76a6bc931 100644
--- a/build.rs
+++ b/build.rs
@@ -102,7 +102,7 @@ const DATA: &'static [(&'static str, &'static [&'static str], &'static [&'static
     ("commctrl", &["basetsd", "commoncontrols", "guiddef", "minwinbase", "minwindef", "vcruntime", "windef", "winnt", "winuser"], &["comctl32"]),
     ("commdlg", &["basetsd", "minwindef", "prsht", "unknwnbase", "windef", "wingdi", "winnt", "winuser"], &["comdlg32"]),
     ("commoncontrols", &["commctrl", "guiddef", "minwindef", "unknwnbase", "windef", "winnt"], &["comctl32"]),
-    ("consoleapi", &["minwindef", "wincon", "winnt"], &["kernel32"]),
+    ("consoleapi", &["minwindef", "wincon", "wincontypes", "winnt"], &["kernel32"]),
     ("corsym", &["basetsd", "objidlbase", "unknwnbase", "winnt"], &[]),
     ("d2d1", &["basetsd", "d2dbasetypes", "d3dcommon", "dcommon", "dwrite", "dxgi", "guiddef", "minwindef", "unknwnbase", "wincodec", "windef", "winnt"], &["d2d1"]),
     ("d2d1_1", &["basetsd", "d2d1", "d2d1effectauthor", "d2dbasetypes", "dcommon", "documenttarget", "dwrite", "dxgi", "dxgiformat", "guiddef", "minwindef", "objidlbase", "unknwnbase", "wincodec", "winnt"], &["d2d1"]),
@@ -309,7 +309,8 @@ const DATA: &'static [(&'static str, &'static [&'static str], &'static [&'static
     ("winbase", &["basetsd", "cfgmgr32", "fileapi", "guiddef", "libloaderapi", "minwinbase", "minwindef", "processthreadsapi", "vadefs", "windef", "winnt"], &["kernel32"]),
     ("wincodec", &["basetsd", "d2d1", "d2d1_1", "dcommon", "dxgiformat", "dxgitype", "guiddef", "minwindef", "ntdef", "objidlbase", "ocidl", "propidl", "unknwnbase", "windef", "winerror", "winnt"], &["windowscodecs"]),
     ("wincodecsdk", &["guiddef", "minwindef", "oaidl", "objidl", "objidlbase", "ocidl", "propidl", "unknwnbase", "wincodec", "winnt", "wtypes"], &["ole32", "oleaut32", "windowscodecs"]),
-    ("wincon", &["minwinbase", "minwindef", "windef", "wingdi", "winnt"], &["kernel32"]),
+    ("wincon", &["minwinbase", "minwindef", "wincontypes", "windef", "wingdi", "winnt"], &["kernel32"]),
+    ("wincontypes", &["minwindef", "winnt"], &[]),
     ("wincred", &["minwindef", "sspi", "windef", "winnt"], &["advapi32", "credui"]),
     ("wincrypt", &["basetsd", "bcrypt", "guiddef", "minwinbase", "minwindef", "ncrypt", "vcruntime", "winnt"], &["advapi32", "crypt32", "cryptnet"]),
     ("windowsceip", &["minwindef"], &["kernel32"]),
diff --git a/src/um/consoleapi.rs b/src/um/consoleapi.rs
index 273cfbf91..48d1305c9 100644
--- a/src/um/consoleapi.rs
+++ b/src/um/consoleapi.rs
@@ -6,8 +6,9 @@
 // except according to those terms.
 //! ApiSet Contract for api-ms-win-core-console-l1
 use shared::minwindef::{BOOL, DWORD, LPDWORD, LPVOID, UINT};
-use um::wincon::{PCONSOLE_READCONSOLE_CONTROL, PHANDLER_ROUTINE, PINPUT_RECORD};
-use um::winnt::{HANDLE, VOID};
+use um::wincon::{PCONSOLE_READCONSOLE_CONTROL, PHANDLER_ROUTINE};
+use um::wincontypes::{COORD, HPCON, PINPUT_RECORD};
+use um::winnt::{HANDLE, HRESULT, VOID};
 extern "system" {
     pub fn AllocConsole() -> BOOL;
     pub fn GetConsoleCP() -> UINT;
@@ -74,4 +75,18 @@ extern "system" {
         lpNumberOfCharsWritten: LPDWORD,
         lpReserved: LPVOID,
     ) -> BOOL;
+    pub fn CreatePseudoConsole(
+        size: COORD,
+        hInput: HANDLE,
+        hOutput: HANDLE,
+        dwFlags: DWORD,
+        phPC: *mut HPCON
+    ) -> HRESULT;
+    pub fn ResizePseudoConsole(
+        hPC: HPCON,
+        size: COORD
+    ) -> HRESULT;
+    pub fn ClosePseudoConsole(
+        hPC: HPCON
+    );
 }
diff --git a/src/um/mod.rs b/src/um/mod.rs
index ad25bab3c..504ed8869 100644
--- a/src/um/mod.rs
+++ b/src/um/mod.rs
@@ -238,6 +238,7 @@ pub mod gl;
 #[cfg(feature = "wincodec")] pub mod wincodec;
 #[cfg(feature = "wincodecsdk")] pub mod wincodecsdk;
 #[cfg(feature = "wincon")] pub mod wincon;
+#[cfg(feature = "wincontypes")] pub mod wincontypes;
 #[cfg(feature = "wincred")] pub mod wincred;
 #[cfg(feature = "wincrypt")] pub mod wincrypt;
 #[cfg(feature = "windowsceip")] pub mod windowsceip;
diff --git a/src/um/wincon.rs b/src/um/wincon.rs
index 2e5647b86..42f91d5c9 100644
--- a/src/um/wincon.rs
+++ b/src/um/wincon.rs
@@ -11,105 +11,30 @@ use shared::minwindef::{BOOL, DWORD, LPDWORD, LPVOID, LPWORD, UINT, ULONG, WORD}
 use shared::windef::{COLORREF, HWND};
 use um::minwinbase::SECURITY_ATTRIBUTES;
 use um::wingdi::LF_FACESIZE;
-use um::winnt::{CHAR, HANDLE, LPCSTR, LPCWSTR, LPSTR, LPWSTR, SHORT, WCHAR};
-STRUCT!{struct COORD {
-    X: SHORT,
-    Y: SHORT,
-}}
-pub type PCOORD = *mut COORD;
-STRUCT!{struct SMALL_RECT {
-    Left: SHORT,
-    Top: SHORT,
-    Right: SHORT,
-    Bottom: SHORT,
-}}
-pub type PSMALL_RECT = *mut SMALL_RECT;
-UNION!{union KEY_EVENT_RECORD_uChar {
-    [u16; 1],
-    UnicodeChar UnicodeChar_mut: WCHAR,
-    AsciiChar AsciiChar_mut: CHAR,
-}}
-STRUCT!{struct KEY_EVENT_RECORD {
-    bKeyDown: BOOL,
-    wRepeatCount: WORD,
-    wVirtualKeyCode: WORD,
-    wVirtualScanCode: WORD,
-    uChar: KEY_EVENT_RECORD_uChar,
-    dwControlKeyState: DWORD,
-}}
-pub type PKEY_EVENT_RECORD = *mut KEY_EVENT_RECORD;
-pub const RIGHT_ALT_PRESSED: DWORD = 0x0001;
-pub const LEFT_ALT_PRESSED: DWORD = 0x0002;
-pub const RIGHT_CTRL_PRESSED: DWORD = 0x0004;
-pub const LEFT_CTRL_PRESSED: DWORD = 0x0008;
-pub const SHIFT_PRESSED: DWORD = 0x0010;
-pub const NUMLOCK_ON: DWORD = 0x0020;
-pub const SCROLLLOCK_ON: DWORD = 0x0040;
-pub const CAPSLOCK_ON: DWORD = 0x0080;
-pub const ENHANCED_KEY: DWORD = 0x0100;
-pub const NLS_DBCSCHAR: DWORD = 0x00010000;
-pub const NLS_ALPHANUMERIC: DWORD = 0x00000000;
-pub const NLS_KATAKANA: DWORD = 0x00020000;
-pub const NLS_HIRAGANA: DWORD = 0x00040000;
-pub const NLS_ROMAN: DWORD = 0x00400000;
-pub const NLS_IME_CONVERSION: DWORD = 0x00800000;
-pub const NLS_IME_DISABLE: DWORD = 0x20000000;
-STRUCT!{struct MOUSE_EVENT_RECORD {
-    dwMousePosition: COORD,
-    dwButtonState: DWORD,
-    dwControlKeyState: DWORD,
-    dwEventFlags: DWORD,
-}}
-pub type PMOUSE_EVENT_RECORD = *mut MOUSE_EVENT_RECORD;
-pub const FROM_LEFT_1ST_BUTTON_PRESSED: DWORD = 0x0001;
-pub const RIGHTMOST_BUTTON_PRESSED: DWORD = 0x0002;
-pub const FROM_LEFT_2ND_BUTTON_PRESSED: DWORD = 0x0004;
-pub const FROM_LEFT_3RD_BUTTON_PRESSED: DWORD = 0x0008;
-pub const FROM_LEFT_4TH_BUTTON_PRESSED: DWORD = 0x0010;
-pub const MOUSE_MOVED: DWORD = 0x0001;
-pub const DOUBLE_CLICK: DWORD = 0x0002;
-pub const MOUSE_WHEELED: DWORD = 0x0004;
-pub const MOUSE_HWHEELED: DWORD = 0x0008;
-STRUCT!{struct WINDOW_BUFFER_SIZE_RECORD {
-    dwSize: COORD,
-}}
-pub type PWINDOW_BUFFER_SIZE_RECORD = *mut WINDOW_BUFFER_SIZE_RECORD;
-STRUCT!{struct MENU_EVENT_RECORD {
-    dwCommandId: UINT,
-}}
-pub type PMENU_EVENT_RECORD = *mut MENU_EVENT_RECORD;
-STRUCT!{struct FOCUS_EVENT_RECORD {
-    bSetFocus: BOOL,
-}}
-pub type PFOCUS_EVENT_RECORD = *mut FOCUS_EVENT_RECORD;
-UNION!{union INPUT_RECORD_Event {
-    [u32; 4],
-    KeyEvent KeyEvent_mut: KEY_EVENT_RECORD,
-    MouseEvent MouseEvent_mut: MOUSE_EVENT_RECORD,
-    WindowBufferSizeEvent WindowBufferSizeEvent_mut: WINDOW_BUFFER_SIZE_RECORD,
-    MenuEvent MenuEvent_mut: MENU_EVENT_RECORD,
-    FocusEvent FocusEvent_mut: FOCUS_EVENT_RECORD,
-}}
-STRUCT!{struct INPUT_RECORD {
-    EventType: WORD,
-    Event: INPUT_RECORD_Event,
-}}
-pub type PINPUT_RECORD = *mut INPUT_RECORD;
-pub const KEY_EVENT: WORD = 0x0001;
-pub const MOUSE_EVENT: WORD = 0x0002;
-pub const WINDOW_BUFFER_SIZE_EVENT: WORD = 0x0004;
-pub const MENU_EVENT: WORD = 0x0008;
-pub const FOCUS_EVENT: WORD = 0x0010;
-UNION!{union CHAR_INFO_Char {
-    [u16; 1],
-    UnicodeChar UnicodeChar_mut: WCHAR,
-    AsciiChar AsciiChar_mut: CHAR,
-}}
-STRUCT!{struct CHAR_INFO {
-    Char: CHAR_INFO_Char,
-    Attributes: WORD,
-}}
-pub type PCHAR_INFO = *mut CHAR_INFO;
+use um::winnt::{CHAR, HANDLE, LPCSTR, LPCWSTR, LPSTR, LPWSTR, WCHAR};
+// Many definitions in wincontypes used to be defined in this file, so reexport them to avoid
+// breakage. For clarity they are imported in the order they are defined in that file rather
+// than winapi's usual alphabetical ordering, with some newlines and indentation to match their
+// grouping in the file.
+pub use um::wincontypes::{
+    COORD, PCOORD,
+    SMALL_RECT, PSMALL_RECT,
+    KEY_EVENT_RECORD_uChar, KEY_EVENT_RECORD, PKEY_EVENT_RECORD,
+    RIGHT_ALT_PRESSED, LEFT_ALT_PRESSED, RIGHT_CTRL_PRESSED, LEFT_CTRL_PRESSED, SHIFT_PRESSED,
+        NUMLOCK_ON, SCROLLLOCK_ON, CAPSLOCK_ON, ENHANCED_KEY, NLS_DBCSCHAR, NLS_ALPHANUMERIC,
+        NLS_KATAKANA, NLS_HIRAGANA, NLS_ROMAN, NLS_IME_CONVERSION, NLS_IME_DISABLE,
+    MOUSE_EVENT_RECORD, PMOUSE_EVENT_RECORD,
+    FROM_LEFT_1ST_BUTTON_PRESSED, RIGHTMOST_BUTTON_PRESSED, FROM_LEFT_2ND_BUTTON_PRESSED,
+        FROM_LEFT_3RD_BUTTON_PRESSED, FROM_LEFT_4TH_BUTTON_PRESSED, MOUSE_MOVED, DOUBLE_CLICK,
+        MOUSE_WHEELED, MOUSE_HWHEELED,
+    WINDOW_BUFFER_SIZE_RECORD, PWINDOW_BUFFER_SIZE_RECORD,
+    MENU_EVENT_RECORD, PMENU_EVENT_RECORD,
+    FOCUS_EVENT_RECORD, PFOCUS_EVENT_RECORD,
+    INPUT_RECORD_Event, INPUT_RECORD, PINPUT_RECORD,
+    KEY_EVENT, MOUSE_EVENT, WINDOW_BUFFER_SIZE_EVENT, MENU_EVENT, FOCUS_EVENT,
+    CHAR_INFO_Char, CHAR_INFO, PCHAR_INFO,
+    CONSOLE_FONT_INFO, PCONSOLE_FONT_INFO
+};
 pub const FOREGROUND_BLUE: WORD = 0x0001;
 pub const FOREGROUND_GREEN: WORD = 0x0002;
 pub const FOREGROUND_RED: WORD = 0x0004;
@@ -151,11 +76,6 @@ STRUCT!{struct CONSOLE_CURSOR_INFO {
     bVisible: BOOL,
 }}
 pub type PCONSOLE_CURSOR_INFO = *mut CONSOLE_CURSOR_INFO;
-STRUCT!{struct CONSOLE_FONT_INFO {
-    nFont: DWORD,
-    dwFontSize: COORD,
-}}
-pub type PCONSOLE_FONT_INFO = *mut CONSOLE_FONT_INFO;
 STRUCT!{struct CONSOLE_FONT_INFOEX {
     cbSize: ULONG,
     nFont: DWORD,
diff --git a/src/um/wincontypes.rs b/src/um/wincontypes.rs
new file mode 100644
index 000000000..08ae2fa92
--- /dev/null
+++ b/src/um/wincontypes.rs
@@ -0,0 +1,115 @@
+// Copyright © 2016-2017 winapi-rs developers
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// All files in the project carrying such notice may not be copied, modified, or distributed
+// except according to those terms.
+//! This module contains the public data structures, data types, and procedures exported by the NT
+//! console subsystem.
+use ctypes::c_void;
+use shared::minwindef::{BOOL, DWORD, UINT, WORD};
+use um::winnt::{CHAR, SHORT, WCHAR};
+STRUCT!{struct COORD {
+    X: SHORT,
+    Y: SHORT,
+}}
+pub type PCOORD = *mut COORD;
+STRUCT!{struct SMALL_RECT {
+    Left: SHORT,
+    Top: SHORT,
+    Right: SHORT,
+    Bottom: SHORT,
+}}
+pub type PSMALL_RECT = *mut SMALL_RECT;
+UNION!{union KEY_EVENT_RECORD_uChar {
+    [u16; 1],
+    UnicodeChar UnicodeChar_mut: WCHAR,
+    AsciiChar AsciiChar_mut: CHAR,
+}}
+STRUCT!{struct KEY_EVENT_RECORD {
+    bKeyDown: BOOL,
+    wRepeatCount: WORD,
+    wVirtualKeyCode: WORD,
+    wVirtualScanCode: WORD,
+    uChar: KEY_EVENT_RECORD_uChar,
+    dwControlKeyState: DWORD,
+}}
+pub type PKEY_EVENT_RECORD = *mut KEY_EVENT_RECORD;
+pub const RIGHT_ALT_PRESSED: DWORD = 0x0001;
+pub const LEFT_ALT_PRESSED: DWORD = 0x0002;
+pub const RIGHT_CTRL_PRESSED: DWORD = 0x0004;
+pub const LEFT_CTRL_PRESSED: DWORD = 0x0008;
+pub const SHIFT_PRESSED: DWORD = 0x0010;
+pub const NUMLOCK_ON: DWORD = 0x0020;
+pub const SCROLLLOCK_ON: DWORD = 0x0040;
+pub const CAPSLOCK_ON: DWORD = 0x0080;
+pub const ENHANCED_KEY: DWORD = 0x0100;
+pub const NLS_DBCSCHAR: DWORD = 0x00010000;
+pub const NLS_ALPHANUMERIC: DWORD = 0x00000000;
+pub const NLS_KATAKANA: DWORD = 0x00020000;
+pub const NLS_HIRAGANA: DWORD = 0x00040000;
+pub const NLS_ROMAN: DWORD = 0x00400000;
+pub const NLS_IME_CONVERSION: DWORD = 0x00800000;
+pub const NLS_IME_DISABLE: DWORD = 0x20000000;
+STRUCT!{struct MOUSE_EVENT_RECORD {
+    dwMousePosition: COORD,
+    dwButtonState: DWORD,
+    dwControlKeyState: DWORD,
+    dwEventFlags: DWORD,
+}}
+pub type PMOUSE_EVENT_RECORD = *mut MOUSE_EVENT_RECORD;
+pub const FROM_LEFT_1ST_BUTTON_PRESSED: DWORD = 0x0001;
+pub const RIGHTMOST_BUTTON_PRESSED: DWORD = 0x0002;
+pub const FROM_LEFT_2ND_BUTTON_PRESSED: DWORD = 0x0004;
+pub const FROM_LEFT_3RD_BUTTON_PRESSED: DWORD = 0x0008;
+pub const FROM_LEFT_4TH_BUTTON_PRESSED: DWORD = 0x0010;
+pub const MOUSE_MOVED: DWORD = 0x0001;
+pub const DOUBLE_CLICK: DWORD = 0x0002;
+pub const MOUSE_WHEELED: DWORD = 0x0004;
+pub const MOUSE_HWHEELED: DWORD = 0x0008;
+STRUCT!{struct WINDOW_BUFFER_SIZE_RECORD {
+    dwSize: COORD,
+}}
+pub type PWINDOW_BUFFER_SIZE_RECORD = *mut WINDOW_BUFFER_SIZE_RECORD;
+STRUCT!{struct MENU_EVENT_RECORD {
+    dwCommandId: UINT,
+}}
+pub type PMENU_EVENT_RECORD = *mut MENU_EVENT_RECORD;
+STRUCT!{struct FOCUS_EVENT_RECORD {
+    bSetFocus: BOOL,
+}}
+pub type PFOCUS_EVENT_RECORD = *mut FOCUS_EVENT_RECORD;
+UNION!{union INPUT_RECORD_Event {
+    [u32; 4],
+    KeyEvent KeyEvent_mut: KEY_EVENT_RECORD,
+    MouseEvent MouseEvent_mut: MOUSE_EVENT_RECORD,
+    WindowBufferSizeEvent WindowBufferSizeEvent_mut: WINDOW_BUFFER_SIZE_RECORD,
+    MenuEvent MenuEvent_mut: MENU_EVENT_RECORD,
+    FocusEvent FocusEvent_mut: FOCUS_EVENT_RECORD,
+}}
+STRUCT!{struct INPUT_RECORD {
+    EventType: WORD,
+    Event: INPUT_RECORD_Event,
+}}
+pub type PINPUT_RECORD = *mut INPUT_RECORD;
+pub const KEY_EVENT: WORD = 0x0001;
+pub const MOUSE_EVENT: WORD = 0x0002;
+pub const WINDOW_BUFFER_SIZE_EVENT: WORD = 0x0004;
+pub const MENU_EVENT: WORD = 0x0008;
+pub const FOCUS_EVENT: WORD = 0x0010;
+UNION!{union CHAR_INFO_Char {
+    [u16; 1],
+    UnicodeChar UnicodeChar_mut: WCHAR,
+    AsciiChar AsciiChar_mut: CHAR,
+}}
+STRUCT!{struct CHAR_INFO {
+    Char: CHAR_INFO_Char,
+    Attributes: WORD,
+}}
+pub type PCHAR_INFO = *mut CHAR_INFO;
+STRUCT!{struct CONSOLE_FONT_INFO {
+    nFont: DWORD,
+    dwFontSize: COORD,
+}}
+pub type PCONSOLE_FONT_INFO = *mut CONSOLE_FONT_INFO;
+pub type HPCON = *mut c_void;


Test patch: