Skip to content

Instantly share code, notes, and snippets.

@Inndy
Created November 16, 2023 10:16
Show Gist options
  • Save Inndy/596be344a99e416884a0d5281a30d6c5 to your computer and use it in GitHub Desktop.
Save Inndy/596be344a99e416884a0d5281a30d6c5 to your computer and use it in GitHub Desktop.
from ctypes import wintypes
import ctypes
import threading
import time
kernel32 = ctypes.CDLL('kernel32')
ENABLE_PROCESSED_INPUT = 1
ENABLE_LINE_INPUT = 2
ENABLE_ECHO_INPUT = 4
ENABLE_WINDOW_INPUT = 8
ENABLE_MOUSE_INPUT = 0x10
ENABLE_INSERT_MODE = 0x20
ENABLE_QUICK_EDIT_MODE = 0x40
ENABLE_VIRTUAL_TERMINAL_INPUT = 0x200
kernel32.SetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.DWORD, )
kernel32.SetConsoleMode.restype = wintypes.BOOL
kernel32.GetConsoleMode.argtypes = (wintypes.HANDLE, ctypes.POINTER(wintypes.DWORD), )
kernel32.GetConsoleMode.restype = wintypes.BOOL
STD_INPUT_HANDLE = -10
kernel32.GetStdHandle.argtypes = (wintypes.DWORD, )
kernel32.GetStdHandle.restype = wintypes.HANDLE
'''
BOOL WINAPI ReadConsole(
_In_ HANDLE hConsoleInput,
_Out_ LPVOID lpBuffer,
_In_ DWORD nNumberOfCharsToRead,
_Out_ LPDWORD lpNumberOfCharsRead,
_In_opt_ LPVOID pInputControl
);
'''
kernel32.ReadConsoleW.argtypes = (wintypes.HANDLE, wintypes.LPVOID, wintypes.DWORD, wintypes.LPDWORD, wintypes.LPVOID, )
kernel32.ReadConsoleW.restype = wintypes.BOOL
def getchars():
c = (wintypes.WCHAR * 1024)()
r = wintypes.DWORD(0)
b = kernel32.ReadConsoleW(hStdin, ctypes.byref(c), len(c), ctypes.byref(r), None)
if r.value > 0:
return c.value
return -1
hStdin = kernel32.GetStdHandle(STD_INPUT_HANDLE)
if not hStdin:
raise OSError('Stdin unavailable')
v = wintypes.DWORD(0)
if not kernel32.GetConsoleMode(hStdin, ctypes.byref(v)):
raise OSError('GetConsoleMode failed')
old_mode = v.value
if not kernel32.SetConsoleMode(hStdin, old_mode & ~(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_INSERT_MODE)):
raise OSError('SetConsoleMode failed')
def restore(_=[False]):
if _[0]:
return
_[0] = True
if not kernel32.SetConsoleMode(hStdin, old_mode):
raise OSError('SetConsoleMode failed')
print('Restored')
t = threading.Thread(target=lambda: (time.sleep(2), restore()))
t.start()
for i in range(10):
print(repr(getchars()))
restore()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment