static int console_get_poll_status(struct file *f) { /* Writing is always ready */ struct console_file *console_file = (struct console_file *) f; if (console->input_buffer_head != console->input_buffer_tail) return LINUX_POLLIN | LINUX_POLLOUT; console_lock(); INPUT_RECORD ir; DWORD num_read; while (PeekConsoleInputW(console->in, &ir, 1, &num_read) && num_read > 0) { /* Test if the event will be discarded */ if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown) { console_unlock(); return LINUX_POLLIN | LINUX_POLLOUT; } /* Discard the event */ ReadConsoleInputW(console->in, &ir, 1, &num_read); } /* We don't find any readable events */ console_unlock(); return LINUX_POLLOUT; }
// Helper function void PreReadConsoleInput(HANDLE hConIn, DWORD nFlags/*enum CEReadConsoleInputFlags*/, CESERVER_CONSOLE_APP_MAPPING** ppAppMap = NULL) { #if defined(_DEBUG) && defined(PRE_PEEK_CONSOLE_INPUT) INPUT_RECORD ir = {}; DWORD nRead = 0, nBuffer = 0; BOOL bNumGot = GetNumberOfConsoleInputEvents(hConIn, &nBuffer); BOOL bConInPeek = nBuffer ? PeekConsoleInputW(hConIn, &ir, 1, &nRead) : FALSE; #endif if (gbPowerShellMonitorProgress) { CheckPowershellProgressPresence(); } if (gbCurDirChanged) { gbCurDirChanged = false; if (ghConEmuWndDC) { if (gFarMode.cbSize && gFarMode.OnCurDirChanged && !IsBadCodePtr((FARPROC)gFarMode.OnCurDirChanged)) { gFarMode.OnCurDirChanged(); } else { CmdArg szDir; if (GetDirectory(szDir) > 0) { // Sends CECMD_STORECURDIR into RConServer SendCurrentDirectory(ghConWnd, szDir); } } } } if (!(nFlags & rcif_Peek)) { // On the one hand - there is a problem with unexpected Enter/Space keypress // github#19: After executing php.exe from command prompt (it runs by Enter KeyDown) // the app gets in its input queue unexpected Enter KeyUp // On the other hand - application must be able to understand if the key was released // Powershell's 'get-help Get-ChildItem -full | out-host -paging' or Issue 1927 (jilrun.exe) CESERVER_CONSOLE_APP_MAPPING* pAppMap = gpAppMap ? gpAppMap->Ptr() : NULL; if (pAppMap) { DWORD nSelfPID = GetCurrentProcessId(); if (nFlags & rcif_LLInput) pAppMap->nReadConsoleInputPID = nSelfPID; else pAppMap->nReadConsolePID = nSelfPID; pAppMap->nLastReadInputPID = nSelfPID; pAppMap->nActiveAppFlags = gnExeFlags; if (ppAppMap) *ppAppMap = pAppMap; } } }
// returns the number of keypress events in the console input queue, // or -1 if there is an error (don't forget this!!) static int pipe_read_avail_console(Q_PIPE_ID pipe) { DWORD count, i; INPUT_RECORD *rec; int n, icount, total; // how many events are there? if(!GetNumberOfConsoleInputEvents(pipe, &count)) return -1; // peek them all rec = (INPUT_RECORD *)malloc(count * sizeof(INPUT_RECORD)); BOOL ret; #if QT_VERSION >= 0x050000 ret = PeekConsoleInputW(pipe, rec, count, &i); #else QT_WA( ret = PeekConsoleInputW(pipe, rec, count, &i); ,
int getkey() { DWORD cnt; INPUT_RECORD ir; HANDLE conin = GetStdHandle(STD_INPUT_HANDLE); if(PeekConsoleInputW(conin,&ir,1,&cnt)) { do ReadConsoleInputW(conin,&ir,1,&cnt); while(ir.EventType!=KEY_EVENT); } FlushConsoleInputBuffer(conin); do ReadConsoleInputW(conin,&ir,1,&cnt); while(ir.EventType!=KEY_EVENT); FlushConsoleInputBuffer(conin); KEY_EVENT_RECORD ke = ir.Event.KeyEvent; int result = ke.uChar.UnicodeChar; if(result==0) return 1000000+ke.wVirtualKeyCode; }
BOOL WINAPI OnReadConsoleInputW(HANDLE hConsoleInput, PINPUT_RECORD lpBuffer, DWORD nLength, LPDWORD lpNumberOfEventsRead) { //typedef BOOL (WINAPI* OnReadConsoleInputW_t)(HANDLE hConsoleInput, PINPUT_RECORD lpBuffer, DWORD nLength, LPDWORD lpNumberOfEventsRead); SUPPRESSORIGINALSHOWCALL; ORIGINAL_KRNL(ReadConsoleInputW); //if (gpFarInfo && bMainThread) // TouchReadPeekConsoleInputs(0); BOOL lbRc = FALSE; // To minimize startup duration and possible problems // hook server will start on first 'user interaction' CheckHookServer(); if (ph && ph->PreCallBack) { SETARGS4(&lbRc,hConsoleInput,lpBuffer,nLength,lpNumberOfEventsRead); // Если функция возвращает FALSE - реальное чтение не будет вызвано if (!ph->PreCallBack(&args)) return lbRc; } CESERVER_CONSOLE_APP_MAPPING* pAppMap = NULL; PreReadConsoleInput(hConsoleInput, rcif_Unicode|rcif_LLInput, &pAppMap); //#ifdef USE_INPUT_SEMAPHORE //DWORD nSemaphore = ghConInSemaphore ? WaitForSingleObject(ghConInSemaphore, INSEMTIMEOUT_READ) : 1; //_ASSERTE(nSemaphore<=1); //#endif #if 0 // get-help Get-ChildItem -full | out-host -paging HANDLE hInTest; HANDLE hTestHandle = NULL; DWORD nInMode, nArgMode; BOOL bInTest = FALSE, bArgTest = FALSE; if (gbPowerShellMonitorProgress) { hInTest = GetStdHandle(STD_INPUT_HANDLE); #ifdef _DEBUG bInTest = GetConsoleMode(hInTest, &nInMode); bArgTest = GetConsoleMode(hConsoleInput, &nArgMode); hTestHandle = CreateFile(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hTestHandle != INVALID_HANDLE_VALUE) CloseHandle(hTestHandle); #endif } #endif if (gFarMode.bFarHookMode && USE_INTERNAL_QUEUE) // ecompl speed-up { #ifdef _DEBUG DWORD nDbgReadReal = countof(gir_Real), nDbgReadVirtual = countof(gir_Virtual); BOOL bReadReal = PeekConsoleInputW(hConsoleInput, gir_Real, nDbgReadReal, &nDbgReadReal); BOOL bReadVirt = gInQueue.ReadInputQueue(gir_Virtual, &nDbgReadVirtual, TRUE); #endif if ((!lbRc || !(lpNumberOfEventsRead && *lpNumberOfEventsRead)) && !gInQueue.IsInputQueueEmpty()) { DWORD n = nLength; lbRc = gInQueue.ReadInputQueue(lpBuffer, &n, FALSE); if (lpNumberOfEventsRead) *lpNumberOfEventsRead = lbRc ? n : 0; } else { lbRc = F(ReadConsoleInputW)(hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead); } } else { lbRc = F(ReadConsoleInputW)(hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead); } // cygwin/msys shells prompt if (lbRc && CEAnsi::ghAnsiLogFile && (nLength == 1) && (*lpNumberOfEventsRead == 1) && (lpBuffer->EventType == KEY_EVENT) && lpBuffer->Event.KeyEvent.bKeyDown && (lpBuffer->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) ) { CEAnsi::AnsiLogEnterPressed(); } PostReadConsoleInput(hConsoleInput, rcif_Unicode|rcif_LLInput, pAppMap); //#ifdef USE_INPUT_SEMAPHORE //if ((nSemaphore == WAIT_OBJECT_0) && ghConInSemaphore) ReleaseSemaphore(ghConInSemaphore, 1, NULL); //#endif if (ph && ph->PostCallBack) { SETARGS4(&lbRc,hConsoleInput,lpBuffer,nLength,lpNumberOfEventsRead); ph->PostCallBack(&args); } if (lbRc && lpNumberOfEventsRead && *lpNumberOfEventsRead && lpBuffer) { OnPeekReadConsoleInput('R', 'W', hConsoleInput, lpBuffer, *lpNumberOfEventsRead); } return lbRc; }