test: ntcon/server/input.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# input.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Classes

struct | _CONSOLE_KEY_INFO

## Defines

#define | CTRL_BUT_NOT_ALT(n)
#define | MAX_CHARS_FROM_1_KEYSTROKE 6
#define | CONSOLE_FREE_KEY_INFO 0
#define | CONSOLE_MAX_KEY_INFO 32

## Typedefs

typedef _CONSOLE_KEY_INFO | CONSOLE_KEY_INFO
typedef _CONSOLE_KEY_INFO * | PCONSOLE_KEY_INFO

## Functions

VOID | UserExitWorkerThread (VOID)
BOOL | InitWindowClass (VOID)
NTSTATUS | ReadBuffer (IN PINPUT_INFORMATION InputInformation, OUT PVOID Buffer, IN ULONG Length, OUT PULONG EventsRead, IN BOOL Peek, IN BOOL StreamRead, OUT PBOOL ResetWaitEvent)
NTSTATUS | CreateInputBuffer (IN ULONG NumberOfEvents OPTIONAL, IN PINPUT_INFORMATION InputBufferInformation)
NTSTATUS | ReinitializeInputBuffer (OUT PINPUT_INFORMATION InputBufferInformation)
VOID | FreeInputBuffer (IN PINPUT_INFORMATION InputBufferInformation)
NTSTATUS | WaitForMoreToRead (IN PINPUT_INFORMATION InputInformation, IN PCSR_API_MSG Message OPTIONAL, IN CSR_WAIT_ROUTINE WaitRoutine OPTIONAL, IN PVOID WaitParameter OPTIONAL, IN ULONG WaitParameterLength OPTIONAL, IN BOOLEAN WaitBlockExists OPTIONAL)
VOID | WakeUpReadersWaitingForData (IN PCONSOLE_INFORMATION Console, PINPUT_INFORMATION InputInformation)
NTSTATUS | GetNumberOfReadyEvents (IN PINPUT_INFORMATION InputInformation, OUT PULONG NumberOfEvents)
NTSTATUS | FlushAllButKeys (PINPUT_INFORMATION InputInformation)
NTSTATUS | FlushInputBuffer (PINPUT_INFORMATION InputInformation)
NTSTATUS | SetInputBufferSize (IN PINPUT_INFORMATION InputInformation, IN ULONG Size)
NTSTATUS | ReadInputBuffer (IN PINPUT_INFORMATION InputInformation, OUT PINPUT_RECORD lpBuffer, IN OUT PDWORD nLength, IN BOOL Peek, IN BOOL WaitForData, IN BOOL StreamRead, IN PCONSOLE_INFORMATION Console, IN PHANDLE_DATA HandleData OPTIONAL, IN PCSR_API_MSG Message OPTIONAL, IN CSR_WAIT_ROUTINE WaitRoutine OPTIONAL, IN PVOID WaitParameter OPTIONAL, IN ULONG WaitParameterLength OPTIONAL, IN BOOLEAN WaitBlockExists OPTIONAL)
NTSTATUS | WriteBuffer (OUT PINPUT_INFORMATION InputInformation, IN PVOID Buffer, IN ULONG Length, OUT PULONG EventsWritten, OUT PBOOL SetWaitEvent)
__inline BOOL | IsSystemKey (WORD wVirtualKeyCode)
DWORD | PreprocessInput (IN PCONSOLE_INFORMATION Console, IN PINPUT_RECORD InputEvent, IN DWORD nLength)
DWORD | PrependInputBuffer (IN PCONSOLE_INFORMATION Console, IN PINPUT_INFORMATION InputInformation, IN PINPUT_RECORD lpBuffer, IN DWORD nLength)
DWORD | WriteInputBuffer (IN PCONSOLE_INFORMATION Console, IN PINPUT_INFORMATION InputInformation, IN PINPUT_RECORD lpBuffer, IN DWORD nLength)
VOID | StoreKeyInfo (IN PMSG msg)
VOID | RetrieveKeyInfo (IN HWND hWnd, OUT PWORD pwVirtualKeyCode, OUT PWORD pwVirtualScanCode, IN BOOL FreeKeyInfo)
VOID | ClearKeyInfo (IN HWND hWnd)
VOID | ProcessCreateConsoleWindow (IN LPMSG lpMsg)
LRESULT | DialogHookProc (int nCode, WPARAM wParam, LPARAM lParam)
ULONG | InputExceptionFilter (PEXCEPTION_POINTERS pexi)
VOID | InitializeThreadMessages ()
VOID | CleanupInputThreadMessages (DWORD dwThreadId)
NTSTATUS | QueueThreadMessage (DWORD dwThreadId, UINT message, WPARAM wParam, LPARAM lParam)
BOOL | UnqueueThreadMessage (DWORD dwThreadId, UINT *pMessage, WPARAM *pwParam, LPARAM *plParam)
VOID | ConsoleInputThread (PINPUT_THREAD_INIT_INFO pInputThreadInitInfo)
ULONG | GetControlKeyState (LPARAM lParam)
ULONG | ConvertMouseButtonState (IN ULONG Flag, IN ULONG State)
VOID | TerminateRead (IN PCONSOLE_INFORMATION Console, IN PINPUT_INFORMATION InputInfo, IN DWORD Flag)
BOOL | HandleSysKeyEvent (IN PCONSOLE_INFORMATION Console, IN HWND hWnd, IN UINT Message, IN WPARAM wParam, IN LPARAM lParam)
VOID | HandleKeyEvent (IN PCONSOLE_INFORMATION Console, IN HWND hWnd, IN UINT Message, IN WPARAM wParam, IN LPARAM lParam)
BOOL | HandleMouseEvent (IN PCONSOLE_INFORMATION Console, IN PSCREEN_INFORMATION ScreenInfo, IN UINT Message, IN WPARAM wParam, IN LPARAM lParam)
VOID | HandleFocusEvent (IN PCONSOLE_INFORMATION Console, IN BOOL bSetFocus)
VOID | HandleMenuEvent (IN PCONSOLE_INFORMATION Console, IN DWORD wParam)
VOID | HandleCtrlEvent (IN PCONSOLE_INFORMATION Console, IN DWORD EventType)
VOID | KillProcess (PCONSOLE_PROCESS_TERMINATION_RECORD ProcessHandleRecord, ULONG_PTR ProcessId)
int | CreateCtrlThread (IN PCONSOLE_PROCESS_TERMINATION_RECORD ProcessHandleList, IN ULONG ProcessHandleListLength, IN PWCHAR Title, IN DWORD EventType, IN BOOL fForce)
int | ProcessCtrlEvents (IN PCONSOLE_INFORMATION Console)
VOID | UnlockConsole (IN PCONSOLE_INFORMATION Console)

## Variables

UINT | ProgmanHandleMessage
int | DialogBoxCount
LPTHREAD_START_ROUTINE | CtrlRoutine
DWORD | InputThreadTlsIndex
CONSOLE_KEY_INFO | ConsoleKeyInfo [CONSOLE_MAX_KEY_INFO]
LIST_ENTRY | gInputThreadMsg
CRITICAL_SECTION | gInputThreadMsgLock

## Define Documentation

#define CONSOLE_FREE_KEY_INFO 0

| Definition at line 71 of file ntcon/server/input.c. Referenced by ClearKeyInfo(), ConsoleInputThread(), RetrieveKeyInfo(), and StoreKeyInfo().

#define CONSOLE_MAX_KEY_INFO 32

| Definition at line 72 of file ntcon/server/input.c. Referenced by ClearKeyInfo(), ConsoleInputThread(), RetrieveKeyInfo(), and StoreKeyInfo().

#define CTRL_BUT_NOT_ALT | ( | n |  | ) |

Value:

    (((n) & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && \
            !((n) & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))

Definition at line 42 of file ntcon/server/input.c.

#define MAX_CHARS_FROM_1_KEYSTROKE 6

| Definition at line 60 of file ntcon/server/input.c. Referenced by HandleKeyEvent().

## Typedef Documentation

typedef struct _CONSOLE_KEY_INFO CONSOLE_KEY_INFO

typedef struct _CONSOLE_KEY_INFO * PCONSOLE_KEY_INFO

## Function Documentation

VOID CleanupInputThreadMessages | ( | DWORD | dwThreadId | ) |

Definition at line 1837 of file ntcon/server/input.c.

References ASSERT, UINT, and UnqueueThreadMessage().

Referenced by ConsoleInputThread().

    01839 {
    01840     UINT message;
    01841     WPARAM wParam;
    01842     LPARAM lParam;
    01843
    01844     ASSERT(dwThreadId);
    01845
    01846     while (UnqueueThreadMessage(dwThreadId, &message, &wParam, &lParam)) {
    01847         RIPMSG3(RIP_WARNING, "CleanupInputThreadMessages: %04x (%08x, %08x)", message, wParam, lParam);
    01848     }
    01849 }

VOID ClearKeyInfo | ( | IN HWND | hWnd | ) |

Definition at line 1634 of file ntcon/server/input.c.

References CONSOLE_FREE_KEY_INFO, CONSOLE_MAX_KEY_INFO, ConsoleKeyInfo, hWnd, and _CONSOLE_KEY_INFO::hWnd.

Referenced by DestroyWindowsWindow().

    01637 {
    01638     int i;
    01639
    01640     for (i=0;i<CONSOLE_MAX_KEY_INFO;i++) {
    01641         if (ConsoleKeyInfo[i].hWnd == hWnd) {
    01642             ConsoleKeyInfo[i].hWnd = CONSOLE_FREE_KEY_INFO;
    01643         }
    01644     }
    01645 }

VOID ConsoleInputThread | ( | PINPUT_THREAD_INIT_INFO | pInputThreadInitInfo | ) |

Definition at line 1946 of file ntcon/server/input.c.

References ASSERT, BOOL, CleanupInputThreadMessages(), CM_CONSOLE_INPUT_THREAD_MSG, CM_CREATE_CONSOLE_WINDOW, CONSOLE_FREE_KEY_INFO, CONSOLE_IS_IME_ENABLED, CONSOLE_MAX_KEY_INFO, ConsoleKeyInfo, _INPUT_THREAD_INFO::Desktop, _INPUT_THREAD_INIT_INFO::DesktopHandle, DialogHookProc(), DispatchMessage(), EF_DEFFACE, EnumerateFonts(), FALSE, fOneTimeInitialized, GetMessage(), _CONSOLE_KEY_INFO::hWnd, _INPUT_THREAD_INIT_INFO::InitCompleteEventHandle, InitializeCustomCP(), InitializeScreenInfo(), _INPUT_THREAD_INIT_INFO::InitStatus, InitWindowClass(), INPUT_THREAD_INFO, InputExceptionFilter, InputThreadTlsIndex, msg, NT_SUCCESS, NtSetEvent(), NTSTATUS(), NtUserConsoleControl(), NULL, ProcessCreateConsoleWindow(), ProgmanHandleMessage, RegisterWindowMessage(), RtlRaiseStatus(), Status, StoreKeyInfo(), _INPUT_THREAD_INIT_INFO::ThreadHandle, _INPUT_THREAD_INFO::ThreadHandle, _INPUT_THREAD_INFO::ThreadId, TranslateMessageEx(), TRUE, UnhookWindowsHookEx, UnqueueThreadMessage(), UserExitWorkerThread(), and _INPUT_THREAD_INFO::WindowCount.

    01948 {
    01949     MSG msg;
    01950     PTEB Teb;
    01951     PCSR_THREAD pcsrt = NULL;
    01952     INPUT_THREAD_INFO ThreadInfo;
    01953     int i;
    01954     HANDLE hThread = NULL;
    01955     HHOOK hhook = NULL;
    01956     BOOL fQuit = FALSE;
    01957     CONSOLEDESKTOPCONSOLETHREAD ConsoleDesktopInfo;
    01958     NTSTATUS Status;
    01959
    01960     //
    01961     // Initialize GDI accelerators.
    01962     //
    01963
    01964     Teb = NtCurrentTeb();
    01965
    01966     try {
    01967
    01968         /*
    01969          * Set this thread's desktop to the one we just created/opened.
    01970          * When the very first app is loaded, the desktop hasn't been
    01971          * created yet so the above call might fail.  Make sure we don't
    01972          * accidentally call SetThreadDesktop with a NULL pdesk.  The
    01973          * first app will create the desktop and open it for itself.
    01974          */
    01975         ThreadInfo.Desktop = pInputThreadInitInfo->DesktopHandle;
    01976         ThreadInfo.WindowCount = 0;
    01977         ThreadInfo.ThreadHandle = pInputThreadInitInfo->ThreadHandle;
    01978         ThreadInfo.ThreadId = HandleToUlong(Teb->ClientId.UniqueThread);
    01979 #if defined(FE_IME)
    01980         ThreadInfo.hWndConsoleIME = NULL;
    01981 #endif
    01982         TlsSetValue(InputThreadTlsIndex, &ThreadInfo);
    01983         ConsoleDesktopInfo.hdesk = pInputThreadInitInfo->DesktopHandle;
    01984         ConsoleDesktopInfo.dwThreadId = HandleToUlong(Teb->ClientId.UniqueThread);
    01985         Status = NtUserConsoleControl(ConsoleDesktopConsoleThread, &ConsoleDesktopInfo,
    01986                 sizeof(ConsoleDesktopInfo));
    01987         if (NT_SUCCESS(Status)) {
    01988
    01989             //
    01990             // This call forces the client-side desktop information
    01991             // to be updated.
    01992             //
    01993
    01994             pcsrt = CsrConnectToUser();
    01995             if (pcsrt == NULL ||
    01996                     !SetThreadDesktop(pInputThreadInitInfo->DesktopHandle)) {
    01997                 Status = STATUS_UNSUCCESSFUL;
    01998             } else {
    01999
    02000                 //
    02001                 // Save our thread handle for cleanup purposes
    02002                 //
    02003
    02004                 hThread = pcsrt->ThreadHandle;
    02005
    02006                 if (!fOneTimeInitialized) {
    02007
    02008                     InitializeCustomCP();
    02009
    02010                     //
    02011                     // Initialize default screen dimensions.  we have to initialize
    02012                     // the font info here (in the input thread) so that GDI doesn't
    02013                     // get completely confused on process termination (since a
    02014                     // process that looks like it's terminating created all the
    02015                     // server HFONTS).
    02016                     //
    02017
    02018                     EnumerateFonts(EF_DEFFACE);
    02019
    02020                     InitializeScreenInfo();
    02021
    02022                     if (!InitWindowClass())
    02023                         Status = STATUS_UNSUCCESSFUL;
    02024
    02025                     for (i=0;i<CONSOLE_MAX_KEY_INFO;i++) {
    02026                         ConsoleKeyInfo[i].hWnd = CONSOLE_FREE_KEY_INFO;
    02027                     }
    02028
    02029                     ProgmanHandleMessage = RegisterWindowMessage(TEXT(CONSOLE_PROGMAN_HANDLE_MESSAGE));
    02030                 }
    02031             }
    02032         }
    02033
    02034         //
    02035         // If we successfully initialized, the input thread is ready to run.
    02036         // Otherwise, kill the thread.
    02037         //
    02038
    02039         pInputThreadInitInfo->InitStatus = Status;
    02040         NtSetEvent(pInputThreadInitInfo->InitCompleteEventHandle, NULL);
    02041
    02042         if (!NT_SUCCESS(Status))
    02043             RtlRaiseStatus(STATUS_PORT_DISCONNECTED);
    02044
    02045         hhook = SetWindowsHookEx(WH_MSGFILTER, DialogHookProc, NULL,
    02046                                 HandleToUlong(Teb->ClientId.UniqueThread));
    02047
    02048         while (TRUE) {
    02049
    02050             //
    02051             // If a WM_QUIT has been received and all windows
    02052             // are gone, get out.
    02053             //
    02054
    02055             if (fQuit && ThreadInfo.WindowCount == 0)
    02056                 break;
    02057
    02058             //
    02059             // Make sure we don't hold any locks while we're idle.
    02060             //
    02061
    02062             ASSERT(NtCurrentTeb()->CountOfOwnedCriticalSections == 0);
    02063
    02064             GetMessage(&msg, NULL, 0, 0);
    02065
    02066             //
    02067             // Trap messages posted to the thread.
    02068             //
    02069
    02070             if (msg.message == CM_CREATE_CONSOLE_WINDOW) {
    02071                 ProcessCreateConsoleWindow(&msg);
    02072                 continue;
    02073             } else if (msg.message == WM_QUIT) {
    02074
    02075                 //
    02076                 // The message was posted from ExitWindows.  This
    02077                 // means that it's OK to terminate the thread.
    02078                 //
    02079
    02080                 fQuit = TRUE;
    02081
    02082                 //
    02083                 // Only exit the loop if there are no windows,
    02084                 //
    02085
    02086                 if (ThreadInfo.WindowCount == 0) {
    02087                     break;
    02088                 }
    02089                 KdPrint(("WM_QUIT received by console with windows\n"));
    02090                 continue;
    02091             }
    02092             else if (CONSOLE_IS_IME_ENABLED()) {
    02093                 if (msg.message == CM_CONSOLE_INPUT_THREAD_MSG) {
    02094                     MSG msg;
    02095
    02096                     if (UnqueueThreadMessage(ThreadInfo.ThreadId, &msg.message, &msg.wParam, &msg.lParam)) {
    02097                         // NOTE HIROYAMA: change this to RIP_VERBOSE
    02098                         RIPMSG3(RIP_VERBOSE, "InputThread: Unqueue: msg=%04x (%08x, %08x)",
    02099                                 msg.message, msg.wParam, msg.lParam);
    02100                         switch (msg.message) {
    02101                         case CM_CONIME_CREATE:
    02102                             ProcessCreateConsoleIME(&msg, ThreadInfo.ThreadId);
    02103                             continue;
    02104                         case CM_WAIT_CONIME_PROCESS:
    02105                             WaitConsoleIMEStuff((HDESK)msg.wParam, (HANDLE)msg.lParam);
    02106                             continue;
    02107                         case CM_SET_CONSOLEIME_WINDOW:
    02108                             ThreadInfo.hWndConsoleIME = (HWND)msg.wParam;
    02109                             continue;
    02110                         default:
    02111                             RIPMSG1(RIP_WARNING, "ConsoleInputThread: invalid thread message(%04x) !!", msg.message);
    02112                             break;
    02113                         }
    02114                     }
    02115                     else {
    02116                         RIPMSG0(RIP_WARNING, "ConsoleInputThread: bogus thread message is post. ignored");
    02117                         continue;
    02118                     }
    02119                 }
    02120             }
    02121
    02122             if (!TranslateMessageEx(&msg, TM_POSTCHARBREAKS)) {
    02123                 DispatchMessage(&msg);
    02124             } else {
    02125                 // do this so that alt-tab works while journalling
    02126                 if (msg.message == WM_SYSKEYDOWN &&
    02127                     msg.wParam == VK_TAB &&
    02128                     (msg.lParam & 0x20000000) ) {   // alt is really down
    02129                     DispatchMessage(&msg);
    02130                 } else {
    02131                     StoreKeyInfo(&msg);
    02132                 }
    02133             }
    02134         }
    02135
    02136         //
    02137         // Cleanup the input thread messages
    02138         //
    02139         CleanupInputThreadMessages(ThreadInfo.ThreadId);
    02140
    02141         RtlRaiseStatus(STATUS_PORT_DISCONNECTED);
    02142
    02143     } except (InputExceptionFilter(GetExceptionInformation())) {
    02144         BOOL fSuccess;
    02145
    02146         //
    02147         // Free all resources used by this thread
    02148         //
    02149
    02150         if (hhook != NULL)
    02151             UnhookWindowsHookEx(hhook);
    02152         ConsoleDesktopInfo.dwThreadId = 0;
    02153         NtUserConsoleControl(ConsoleDesktopConsoleThread,
    02154                 &ConsoleDesktopInfo, sizeof(ConsoleDesktopInfo));
    02155
    02156         //
    02157         // Close the desktop handle.  CSR is special cased to close
    02158         // the handle even if the thread has windows.  The desktop
    02159         // remains assigned to the thread.
    02160         //
    02161
    02162         fSuccess = CloseDesktop(ThreadInfo.Desktop);
    02163         ASSERT(fSuccess);
    02164
    02165         //
    02166         // Restore thread handle so that CSR won't get confused.
    02167         //
    02168
    02169         if (hThread != NULL)
    02170             pcsrt->ThreadHandle = hThread;
    02171     }
    02172
    02173     if (pcsrt != NULL)
    02174         CsrDereferenceThread(pcsrt);
    02175     UserExitWorkerThread();
    02176 }

ULONG ConvertMouseButtonState | ( | IN ULONG | Flag,
|  | IN ULONG | State
| ) |

Definition at line 2217 of file ntcon/server/input.c.

Referenced by HandleMouseEvent().

    02221 {
    02222     if (State & MK_LBUTTON) {
    02223         Flag |= FROM_LEFT_1ST_BUTTON_PRESSED;
    02224     }
    02225     if (State & MK_MBUTTON) {
    02226         Flag |= FROM_LEFT_2ND_BUTTON_PRESSED;
    02227     }
    02228     if (State & MK_RBUTTON) {
    02229         Flag |= RIGHTMOST_BUTTON_PRESSED;
    02230     }
    02231     return Flag;
    02232 }

int CreateCtrlThread | ( | IN PCONSOLE_PROCESS_TERMINATION_RECORD | ProcessHandleList,
|  | IN ULONG | ProcessHandleListLength,
|  | IN PWCHAR | Title,
|  | IN DWORD | EventType,
|  | IN BOOL | fForce
| ) |

Definition at line 3502 of file ntcon/server/input.c.

References Action, BHE_ACTIVATE, BHE_FORCE, BOOL, BoostHardError(), CONSOLE_SHUTDOWN_FAILED, CONSOLE_SHUTDOWN_SUCCEEDED, CONSOLE_SHUTDOWN_SYSTEM, CtrlRoutine, DebugPort, DialogBoxCount, DWORD, FALSE, gCmsHungAppTimeout, gCmsWaitToKillTimeout, gdwServicesProcessId, gdwServicesWaitToKillTimeout, InternalCreateCallbackThread(), InternalWaitCancel(), KillProcess(), NT_SUCCESS, NtQueryInformationProcess(), NTSTATUS(), NULL, Status, ThreadShutdownNotify(), TRUE, TSN_USERSAYSCANCEL, and WMCS_CONSOLE.

Referenced by NonConsoleProcessShutdown(), ProcessCtrlEvents(), and RemoveConsole().

    03513 {
    03514     HANDLE Thread;
    03515     DWORD Status;
    03516     NTSTATUS status;
    03517     DWORD ShutdownFlags;
    03518     int Success=CONSOLE_SHUTDOWN_SUCCEEDED;
    03519     ULONG i;
    03520     DWORD EventFlags;
    03521     PROCESS_BASIC_INFORMATION BasicInfo;
    03522     PCSR_PROCESS Process;
    03523     BOOL fForceProcess;
    03524     BOOL fExitProcess;
    03525     BOOL fFirstPass=TRUE;
    03526     BOOL fSecondPassNeeded=FALSE;
    03527     BOOL fHasError;
    03528     BOOL fFirstWait;
    03529     BOOL fEventProcessed;
    03530     BOOL fBreakEvent;
    03531
    03532 BigLoop:
    03533     for (i=0;i<ProcessHandleListLength;i++) {
    03534
    03535         //
    03536         // If the user has already cancelled shutdown, don't try to kill
    03537         // any more processes.
    03538         //
    03539
    03540         if (Success == CONSOLE_SHUTDOWN_FAILED) {
    03541             break;
    03542         }
    03543
    03544         //
    03545         // Get the process shutdown parameters here. First get the process
    03546         // id so we can get the csr process structure pointer.
    03547         //
    03548
    03549         status = NtQueryInformationProcess(
    03550                 ProcessHandleList[i].ProcessHandle,
    03551                 ProcessBasicInformation,
    03552                 &BasicInfo,
    03553                 sizeof(BasicInfo),
    03554                 NULL);
    03555
    03556         //
    03557         // Grab the shutdown flags from the csr process structure.  If
    03558         // the structure cannot be found, terminate the process.
    03559         //
    03560
    03561         ProcessHandleList[i].bDebugee = FALSE;
    03562         ShutdownFlags = 0;
    03563         if (NT_SUCCESS(status)) {
    03564             CsrLockProcessByClientId(
    03565                     (HANDLE)BasicInfo.UniqueProcessId, &Process);
    03566             if (Process == NULL) {
    03567                 KillProcess(&ProcessHandleList[i],
    03568                         BasicInfo.UniqueProcessId);
    03569                 continue;
    03570             }
    03571         } else {
    03572             KillProcess(&ProcessHandleList[i], 0);
    03573             continue;
    03574         }
    03575         ShutdownFlags = Process->ShutdownFlags;
    03576         ProcessHandleList[i].bDebugee = Process->DebugUserInterface.UniqueProcess!=NULL;
    03577         CsrUnlockProcess(Process);
    03578
    03579         if (!ProcessHandleList[i].bDebugee) {
    03580             HANDLE DebugPort;
    03581
    03582             // see if we're a OS/2 app that's being debugged
    03583             DebugPort = (HANDLE)NULL;
    03584             status = NtQueryInformationProcess(
    03585                         ProcessHandleList[i].ProcessHandle,
    03586                         ProcessDebugPort,
    03587                         (PVOID)&DebugPort,
    03588                         sizeof(DebugPort),
    03589                         NULL
    03590                         );
    03591             if ( NT_SUCCESS(status) && DebugPort ) {
    03592                 ProcessHandleList[i].bDebugee = TRUE;
    03593             }
    03594         }
    03595         if (EventType != CTRL_C_EVENT && EventType != CTRL_BREAK_EVENT) {
    03596             fBreakEvent = FALSE;
    03597             if (fFirstPass) {
    03598                 if (ProcessHandleList[i].bDebugee) {
    03599                     fSecondPassNeeded = TRUE;
    03600                     continue;
    03601                 }
    03602             } else {
    03603                 if (!ProcessHandleList[i].bDebugee) {
    03604                     continue;
    03605                 }
    03606             }
    03607         } else {
    03608             fBreakEvent = TRUE;
    03609             fFirstPass=FALSE;
    03610         }
    03611
    03612         //
    03613         // fForce is whether ExitWindowsEx was called with EWX_FORCE.
    03614         // ShutdownFlags are the shutdown flags for this process. If
    03615         // either are force (noretry is the same as force), then force:
    03616         // which means if the app doesn't exit, don't bring up the retry
    03617         // dialog - just force it to exit right away.
    03618         //
    03619
    03620         fForceProcess = fForce || (ShutdownFlags & SHUTDOWN_NORETRY);
    03621
    03622         //
    03623         // Only notify system security and service context processes.
    03624         // Don't bring up retry dialogs for them.
    03625         //
    03626
    03627         fExitProcess = TRUE;
    03628         EventFlags = 0;
    03629         if (ShutdownFlags & (SHUTDOWN_SYSTEMCONTEXT | SHUTDOWN_OTHERCONTEXT)) {
    03630
    03631             //
    03632             // System context - make sure we don't cause it to exit, make
    03633             // sure we don't bring up retry dialogs.
    03634             //
    03635
    03636             fExitProcess = FALSE;
    03637             fForceProcess = TRUE;
    03638
    03639             //
    03640             // This EventFlag will be passed on down to the CtrlRoutine()
    03641             // on the client side. That way that side knows not to exit
    03642             // this process.
    03643             //
    03644
    03645             EventFlags = 0x80000000;
    03646         }
    03647
    03648         //
    03649         // Is this the first time we're waiting for this process to die?
    03650         //
    03651
    03652         fFirstWait = TRUE;
    03653         fEventProcessed = FALSE;
    03654
    03655         while (!fEventProcessed) {
    03656             DWORD ThreadExitCode;
    03657             DWORD ProcessExitCode;
    03658             DWORD cMsTimeout;
    03659
    03660             Thread = InternalCreateCallbackThread(
    03661                     ProcessHandleList[i].ProcessHandle,
    03662                     (ULONG_PTR)ProcessHandleList[i].CtrlRoutine,
    03663                     EventType | EventFlags);
    03664
    03665             //
    03666             // If the thread cannot be created, terminate the process.
    03667             //
    03668
    03669             if (Thread == NULL) {
    03670                 KdPrint(("CONSRV: CreateRemoteThread failed %x\n",GetLastError()));
    03671                 break;
    03672             }
    03673
    03674             //
    03675             // Mark the event as processed.
    03676             //
    03677
    03678             fEventProcessed = TRUE;
    03679
    03680             /*
    03681              * if it's a ctrl-c or ctrl-break event, just close our
    03682              * handle to the thread.  otherwise it's a close.  wait
    03683              * for client-side thread to terminate.
    03684              */
    03685
    03686             if (EventType == CTRL_CLOSE_EVENT) {
    03687                 cMsTimeout = gCmsHungAppTimeout;
    03688             } else if (EventType == CTRL_LOGOFF_EVENT) {
    03689                 cMsTimeout = gCmsWaitToKillTimeout;
    03690             } else if (EventType == CTRL_SHUTDOWN_EVENT) {
    03691
    03692                 //
    03693                 // If we are shutting down services.exe, we need to look in the
    03694                 // registry to see how long to wait.
    03695                 //
    03696
    03697                 if (fFirstWait && BasicInfo.UniqueProcessId == gdwServicesProcessId) {
    03698                     cMsTimeout = gdwServicesWaitToKillTimeout;
    03699                 } else {
    03700                     cMsTimeout = gCmsWaitToKillTimeout;
    03701                 }
    03702             } else {
    03703                 CloseHandle(Thread);
    03704                 fExitProcess = FALSE;
    03705                 break;
    03706             }
    03707
    03708             while (TRUE) {
    03709                 fHasError = BoostHardError(BasicInfo.UniqueProcessId,
    03710                         (fForceProcess ? BHE_FORCE : BHE_ACTIVATE));
    03711
    03712                 //
    03713                 // Use a 1 second wait if there was a hard error, otherwise
    03714                 // wait cMsTimeout ms.
    03715                 //
    03716
    03717                 Status = InternalWaitCancel(Thread,
    03718                         (fHasError && fForceProcess) ? 1000 : cMsTimeout);
    03719                 if (Status == WAIT_TIMEOUT) {
    03720                     int Action;
    03721
    03722                     //
    03723                     // If there was a hard error, see if there is another one.
    03724                     //
    03725
    03726                     if (fHasError && fForceProcess) {
    03727                         continue;
    03728                     }
    03729
    03730                     if (!fForceProcess) {
    03731
    03732                         //
    03733                         // we timed out in the handler.  ask the user what
    03734                         // to do.
    03735                         //
    03736
    03737                         DialogBoxCount++;
    03738                         Action = ThreadShutdownNotify(WMCS_CONSOLE, (ULONG_PTR)Thread, (LPARAM)Title);
    03739                         DialogBoxCount--;
    03740
    03741                         //
    03742                         // If the response is Cancel or EndTask, exit the loop.
    03743                         // Otherwise retry the wait.
    03744                         //
    03745
    03746                         if (Action == TSN_USERSAYSCANCEL) {
    03747                             Success = CONSOLE_SHUTDOWN_FAILED;
    03748                         }
    03749                     }
    03750                 } else if (Status == 0) {
    03751                     ThreadExitCode = 0;
    03752                     GetExitCodeThread(Thread,&ThreadExitCode);
    03753                     GetExitCodeProcess(ProcessHandleList[i].ProcessHandle,
    03754                             &ProcessExitCode);
    03755
    03756                     //
    03757                     // if the app returned TRUE (event handled)
    03758                     // notify the user and see if the app should
    03759                     // be terminated anyway.
    03760                     //
    03761
    03762                     if (fHasError || (ThreadExitCode == EventType &&
    03763                             ProcessExitCode == STILL_ACTIVE)) {
    03764                         int Action;
    03765
    03766                         if (!fForceProcess) {
    03767
    03768                             //
    03769                             // Wait for the process to exit.  If it does exit,
    03770                             // don't bring up the end task dialog.
    03771                             //
    03772
    03773                             Status = InternalWaitCancel(ProcessHandleList[i].ProcessHandle,
    03774                                     (fHasError || fFirstWait) ? 1000 : cMsTimeout);
    03775                             if (Status == 0) {
    03776
    03777                                 //
    03778                                 // The process exited.
    03779                                 //
    03780
    03781                                 fExitProcess = FALSE;
    03782                             } else if (Status == WAIT_TIMEOUT) {
    03783                                 DialogBoxCount++;
    03784                                 Action = ThreadShutdownNotify(WMCS_CONSOLE,
    03785                                                               (ULONG_PTR)ProcessHandleList[i].ProcessHandle,
    03786                                                                (LPARAM)Title);
    03787                                 DialogBoxCount--;
    03788
    03789                                 if (Action == TSN_USERSAYSCANCEL) {
    03790                                     Success = CONSOLE_SHUTDOWN_FAILED;
    03791                                 }
    03792                             }
    03793                         }
    03794                     } else {
    03795
    03796                         //
    03797                         // The process exited.
    03798                         //
    03799
    03800                         fExitProcess = FALSE;
    03801                     }
    03802                 }
    03803
    03804                 //
    03805                 // If we get here, we know that all wait conditions have
    03806                 // been satisfied.  Time to finish with the process.
    03807                 //
    03808
    03809                 break;
    03810             }
    03811
    03812             CloseHandle(Thread);
    03813         }
    03814
    03815         //
    03816         // If the process is shutting down, mark it as terminated.
    03817         // This prevents the process from raising any hard error popups
    03818         // after we're done shutting it down.
    03819         //
    03820
    03821         if (!fBreakEvent &&
    03822                 !(ShutdownFlags & (SHUTDOWN_SYSTEMCONTEXT | SHUTDOWN_OTHERCONTEXT)) &&
    03823                 Success == CONSOLE_SHUTDOWN_SUCCEEDED) {
    03824             CsrLockProcessByClientId(
    03825                     (HANDLE)BasicInfo.UniqueProcessId, &Process);
    03826             if (Process) {
    03827                 Process->Flags |= CSR_PROCESS_TERMINATED;
    03828                 CsrUnlockProcess(Process);
    03829             }
    03830
    03831             //
    03832             // Force the termination of the process if needed.  Otherwise,
    03833             // acknowledge any remaining hard errors.
    03834             //
    03835             if (fExitProcess) {
    03836                 KillProcess(&ProcessHandleList[i],
    03837                         BasicInfo.UniqueProcessId);
    03838             } else {
    03839                 BoostHardError(BasicInfo.UniqueProcessId, BHE_FORCE);
    03840             }
    03841         }
    03842     }
    03843
    03844     //
    03845     // If this was our first time through and we skipped one of the
    03846     // processes because it was being debugged, we'll go back for a
    03847     // second pass.
    03848     //
    03849
    03850     if (fFirstPass && fSecondPassNeeded) {
    03851         fFirstPass = FALSE;
    03852         goto BigLoop;
    03853     }
    03854
    03855     // if we're shutting down a system or service security context
    03856     // thread, don't wait for the process to terminate
    03857
    03858     if (ShutdownFlags & (SHUTDOWN_SYSTEMCONTEXT | SHUTDOWN_OTHERCONTEXT)) {
    03859         return CONSOLE_SHUTDOWN_SYSTEM;
    03860     }
    03861     return Success;
    03862 }

NTSTATUS CreateInputBuffer | ( | IN ULONG NumberOfEvents | OPTIONAL,
|  | IN PINPUT_INFORMATION | InputBufferInformation
| ) |

Definition at line 103 of file ntcon/server/input.c.

References BUFFER_TAG, BufferSize, ConsoleHeapAlloc, ConsoleHeapFree, DEFAULT_NUMBER_OF_EVENTS, FALSE, MAKE_TAG, NT_SUCCESS, NtCreateEvent(), NTSTATUS(), NULL, and Status.

Referenced by AllocateConsole().

    00114                    :
    00115
    00116     This routine creates an input buffer.  It allocates the circular
    00117     buffer and initializes the information fields.
    00118
    00119 Arguments:
    00120
    00121     NumberOfEvents - Size of input buffer in events.
    00122
    00123     InputBufferInformation - Pointer to input buffer information structure.
    00124
    00125 Return Value:
    00126
    00127
    00128 --*/
    00129
    00130 {
    00131     ULONG BufferSize;
    00132     NTSTATUS Status;
    00133
    00134     if (NumberOfEvents == 0) {
    00135         NumberOfEvents = DEFAULT_NUMBER_OF_EVENTS;
    00136     }
    00137
    00138     // allocate memory for circular buffer
    00139
    00140     BufferSize =  sizeof(INPUT_RECORD) * (NumberOfEvents+1);
    00141     InputBufferInformation->InputBuffer = (PINPUT_RECORD)ConsoleHeapAlloc(MAKE_TAG( BUFFER_TAG ),BufferSize);
    00142     if (InputBufferInformation->InputBuffer == NULL) {
    00143         return STATUS_NO_MEMORY;
    00144     }
    00145     Status = NtCreateEvent(&InputBufferInformation->InputWaitEvent,
    00146                            EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE);
    00147     if (!NT_SUCCESS(Status)) {
    00148         ConsoleHeapFree(InputBufferInformation->InputBuffer);
    00149         return STATUS_NO_MEMORY;
    00150     }
    00151     InitializeListHead(&InputBufferInformation->ReadWaitQueue);
    00152
    00153     // initialize buffer header
    00154
    00155     InputBufferInformation->InputBufferSize = NumberOfEvents;
    00156     InputBufferInformation->ShareAccess.OpenCount = 0;
    00157     InputBufferInformation->ShareAccess.Readers = 0;
    00158     InputBufferInformation->ShareAccess.Writers = 0;
    00159     InputBufferInformation->ShareAccess.SharedRead = 0;
    00160     InputBufferInformation->ShareAccess.SharedWrite = 0;
    00161     InputBufferInformation->InputMode = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT;
    00162     InputBufferInformation->AllocatedBufferSize = BufferSize;
    00163     InputBufferInformation->RefCount = 0;
    00164     InputBufferInformation->First = (ULONG_PTR) InputBufferInformation->InputBuffer;
    00165     InputBufferInformation->In = (ULONG_PTR) InputBufferInformation->InputBuffer;
    00166     InputBufferInformation->Out = (ULONG_PTR) InputBufferInformation->InputBuffer;
    00167     InputBufferInformation->Last = (ULONG_PTR) InputBufferInformation->InputBuffer + BufferSize;
    00168 #if defined(FE_SB)
    00169 #if defined(FE_IME)
    00170     InputBufferInformation->ImeMode.Disable     = FALSE;
    00171     InputBufferInformation->ImeMode.Unavailable = FALSE;
    00172     InputBufferInformation->ImeMode.Open        = FALSE;
    00173     InputBufferInformation->ImeMode.ReadyConversion = FALSE;
    00174 #endif // FE_IME
    00175     InputBufferInformation->Console = Console;
    00176     RtlZeroMemory(&InputBufferInformation->ReadConInpDbcsLeadByte,sizeof(INPUT_RECORD));
    00177     RtlZeroMemory(&InputBufferInformation->WriteConInpDbcsLeadByte,sizeof(INPUT_RECORD));
    00178 #endif
    00179
    00180     return STATUS_SUCCESS;
    00181 }

LRESULT DialogHookProc | ( | int | nCode,
|  | WPARAM | wParam,
|  | LPARAM | lParam
| ) |

Definition at line 1726 of file ntcon/server/input.c.

References ASSERT, CM_CONSOLE_INPUT_THREAD_MSG, CM_CREATE_CONSOLE_WINDOW, CONSOLE_IS_IME_ENABLED, GetWindowLongPtr(), InputThreadTlsIndex, msg, ProcessCreateConsoleWindow(), StoreKeyInfo(), _INPUT_THREAD_INFO::ThreadId, TRUE, and UnqueueThreadMessage().

Referenced by ConsoleInputThread().

    01735 {
    01736     MSG *pmsg = (PMSG)lParam;
    01737
    01738     UNREFERENCED_PARAMETER(wParam);
    01739
    01740     if (pmsg->message == CM_CREATE_CONSOLE_WINDOW) {
    01741         ProcessCreateConsoleWindow(pmsg);
    01742         return TRUE;
    01743     }
    01744
    01745     if (CONSOLE_IS_IME_ENABLED()) {
    01746         if (pmsg->message == CM_CONSOLE_INPUT_THREAD_MSG) {
    01747             PINPUT_THREAD_INFO pThreadInfo = TlsGetValue(InputThreadTlsIndex);
    01748             MSG msg;
    01749
    01750             ASSERT(pThreadInfo);
    01751
    01752             if (UnqueueThreadMessage(pThreadInfo->ThreadId, &msg.message, &msg.wParam, &msg.lParam)) {
    01753                 RIPMSG3(RIP_WARNING, "DialogHookProc: %04x (%08x, %08x)", msg.message, msg.wParam, msg.lParam);
    01754                 switch (msg.message) {
    01755                 case CM_CONIME_CREATE:
    01756                     ProcessCreateConsoleIME(&msg, pThreadInfo->ThreadId);
    01757                     return TRUE;
    01758                 case CM_WAIT_CONIME_PROCESS:
    01759                     WaitConsoleIMEStuff((HDESK)msg.wParam, (HANDLE)msg.lParam);
    01760                     return TRUE;
    01761                 case CM_SET_CONSOLEIME_WINDOW:
    01762                     pThreadInfo->hWndConsoleIME = (HWND)msg.wParam;
    01763                     return TRUE;
    01764                 default:
    01765                     RIPMSG1(RIP_WARNING, "DialogHookProc: invalid thread message(%04x) !!", msg.message);
    01766                     break;
    01767                 }
    01768             }
    01769             else {
    01770                 RIPMSG0(RIP_WARNING, "DialogHookProc: bogus thread message is posted. ignored");
    01771             }
    01772         }
    01773     }
    01774
    01775     if (nCode == MSGF_DIALOGBOX) {
    01776         if (pmsg->message >= WM_KEYFIRST &&
    01777             pmsg->message <= WM_KEYLAST) {
    01778             if (pmsg->message != WM_CHAR &&
    01779                 pmsg->message != WM_DEADCHAR &&
    01780                 pmsg->message != WM_SYSCHAR &&
    01781                 pmsg->message != WM_SYSDEADCHAR) {
    01782
    01783                 // don't store key info if dialog box input
    01784                 if (GetWindowLongPtr(pmsg->hwnd, GWLP_HWNDPARENT) == 0) {
    01785                     StoreKeyInfo(pmsg);
    01786                 }
    01787             }
    01788         }
    01789     }
    01790     return 0;
    01791 }

NTSTATUS FlushAllButKeys | ( | PINPUT_INFORMATION | InputInformation | ) |

Definition at line 401 of file ntcon/server/input.c.

References BOOL, BufferSize, ConsoleHeapAlloc, ConsoleHeapFree, FALSE, _INPUT_INFORMATION::In, _INPUT_INFORMATION::InputBuffer, _INPUT_INFORMATION::InputBufferSize, _INPUT_INFORMATION::InputWaitEvent, MAKE_TAG, NT_SUCCESS, NtClearEvent(), NTSTATUS(), NULL, _INPUT_INFORMATION::Out, ReadBuffer(), Status, TMP_TAG, and TRUE.

Referenced by SetActiveScreenBuffer().

    00407                    :
    00408
    00409     This routine removes all but the key events from the buffer.
    00410
    00411 Arguments:
    00412
    00413     InputInformation - Pointer to input buffer information structure.
    00414
    00415 Return Value:
    00416
    00417 Note:
    00418
    00419     The console lock must be held when calling this routine.
    00420
    00421 --*/
    00422
    00423 {
    00424     ULONG NumberOfEventsRead,i;
    00425     NTSTATUS Status;
    00426     PINPUT_RECORD TmpInputBuffer,InPtr,TmpInputBufferPtr;
    00427     ULONG BufferSize;
    00428     BOOL Dummy;
    00429
    00430     if (InputInformation->In != InputInformation->Out)  {
    00431
    00432         //
    00433         // allocate memory for temp buffer
    00434         //
    00435
    00436         BufferSize =  sizeof(INPUT_RECORD) * (InputInformation->InputBufferSize+1);
    00437         TmpInputBuffer = (PINPUT_RECORD)ConsoleHeapAlloc(MAKE_TAG( TMP_TAG ),BufferSize);
    00438         if (TmpInputBuffer == NULL) {
    00439             return STATUS_NO_MEMORY;
    00440         }
    00441         TmpInputBufferPtr = TmpInputBuffer;
    00442
    00443         //
    00444         // copy input buffer.
    00445         // let ReadBuffer do any compaction work.
    00446         //
    00447
    00448         Status = ReadBuffer(InputInformation,
    00449                             TmpInputBuffer,
    00450                             InputInformation->InputBufferSize,
    00451                             &NumberOfEventsRead,
    00452                             TRUE,
    00453                             FALSE,
    00454                             &Dummy
    00455 #if defined(FE_SB)
    00456                             ,
    00457                             TRUE
    00458 #endif
    00459                            );
    00460
    00461         if (!NT_SUCCESS(Status)) {
    00462             ConsoleHeapFree(TmpInputBuffer);
    00463             return Status;
    00464         }
    00465
    00466         InputInformation->Out = (ULONG_PTR) InputInformation->InputBuffer;
    00467         InPtr = InputInformation->InputBuffer;
    00468         for (i=0;i<NumberOfEventsRead;i++) {
    00469             if (TmpInputBuffer->EventType == KEY_EVENT) {
    00470                 *InPtr = *TmpInputBuffer;
    00471                 InPtr++;
    00472             }
    00473             TmpInputBuffer++;
    00474         }
    00475         InputInformation->In = (ULONG_PTR) InPtr;
    00476         if (InputInformation->In == InputInformation->Out) {
    00477             NtClearEvent(InputInformation->InputWaitEvent);
    00478         }
    00479         ConsoleHeapFree(TmpInputBufferPtr);
    00480     }
    00481     return STATUS_SUCCESS;
    00482 }

NTSTATUS FlushInputBuffer | ( | PINPUT_INFORMATION | InputInformation | ) |

Definition at line 485 of file ntcon/server/input.c.

References _INPUT_INFORMATION::In, _INPUT_INFORMATION::InputBuffer, _INPUT_INFORMATION::InputWaitEvent, NtClearEvent(), and _INPUT_INFORMATION::Out.

Referenced by HandleKeyEvent(), and SrvFlushConsoleInputBuffer().

    00491                    :
    00492
    00493     This routine empties the input buffer
    00494
    00495 Arguments:
    00496
    00497     InputInformation - Pointer to input buffer information structure.
    00498
    00499 Return Value:
    00500
    00501 Note:
    00502
    00503     The console lock must be held when calling this routine.
    00504
    00505 --*/
    00506
    00507 {
    00508     InputInformation->In = (ULONG_PTR) InputInformation->InputBuffer;
    00509     InputInformation->Out = (ULONG_PTR) InputInformation->InputBuffer;
    00510     NtClearEvent(InputInformation->InputWaitEvent);
    00511     return STATUS_SUCCESS;
    00512 }

VOID FreeInputBuffer | ( | IN PINPUT_INFORMATION | InputBufferInformation | ) |

Definition at line 221 of file ntcon/server/input.c.

References ASSERT, and ConsoleHeapFree.

Referenced by AbortCreateConsole(), AllocateConsole(), and DestroyWindowsWindow().

    00227                    :
    00228
    00229     This routine frees the resources associated with an input buffer.
    00230
    00231 Arguments:
    00232
    00233     InputBufferInformation - Pointer to input buffer information structure.
    00234
    00235 Return Value:
    00236
    00237
    00238 --*/
    00239
    00240 {
    00241     ASSERT(InputBufferInformation->RefCount == 0);
    00242     CloseHandle(InputBufferInformation->InputWaitEvent);
    00243     ConsoleHeapFree(InputBufferInformation->InputBuffer);
    00244 }

ULONG GetControlKeyState | ( | LPARAM | lParam | ) |

Definition at line 2179 of file ntcon/server/input.c.

References GetKeyState(), KEY_ENHANCED, KEY_PRESSED, KEY_TOGGLED, and VK_OEM_SCROLL.

Referenced by HandleKeyEvent(), and HandleMouseEvent().

    02182 {
    02183     ULONG ControlKeyState=0;
    02184
    02185     if (GetKeyState(VK_LMENU) & KEY_PRESSED) {
    02186         ControlKeyState |= LEFT_ALT_PRESSED;
    02187     }
    02188     if (GetKeyState(VK_RMENU) & KEY_PRESSED) {
    02189         ControlKeyState |= RIGHT_ALT_PRESSED;
    02190     }
    02191     if (GetKeyState(VK_LCONTROL) & KEY_PRESSED) {
    02192         ControlKeyState |= LEFT_CTRL_PRESSED;
    02193     }
    02194     if (GetKeyState(VK_RCONTROL) & KEY_PRESSED) {
    02195         ControlKeyState |= RIGHT_CTRL_PRESSED;
    02196     }
    02197     if (GetKeyState(VK_SHIFT) & KEY_PRESSED) {
    02198         ControlKeyState |= SHIFT_PRESSED;
    02199     }
    02200     if (GetKeyState(VK_NUMLOCK) & KEY_TOGGLED) {
    02201         ControlKeyState |= NUMLOCK_ON;
    02202     }
    02203     if (GetKeyState(VK_OEM_SCROLL) & KEY_TOGGLED) {
    02204         ControlKeyState |= SCROLLLOCK_ON;
    02205     }
    02206     if (GetKeyState(VK_CAPITAL) & KEY_TOGGLED) {
    02207         ControlKeyState |= CAPSLOCK_ON;
    02208     }
    02209     if (lParam & KEY_ENHANCED) {
    02210         ControlKeyState |= ENHANCED_KEY;
    02211     }
    02212     ControlKeyState |= (lParam & ALTNUMPAD_BIT);
    02213     return ControlKeyState;
    02214 }

NTSTATUS GetNumberOfReadyEvents | ( | IN PINPUT_INFORMATION | InputInformation,
|  | OUT PULONG | NumberOfEvents
| ) |

Definition at line 362 of file ntcon/server/input.c.

Referenced by PrependInputBuffer(), and SrvGetConsoleNumberOfInputEvents().

    00369                    :
    00370
    00371     This routine returns the number of events in the input buffer.
    00372
    00373 Arguments:
    00374
    00375     InputInformation - Pointer to input buffer information structure.
    00376
    00377     NumberOfEvents - On output contains the number of events.
    00378
    00379 Return Value:
    00380
    00381 Note:
    00382
    00383     The console lock must be held when calling this routine.
    00384
    00385 --*/
    00386
    00387 {
    00388     if (InputInformation->In < InputInformation->Out) {
    00389         *NumberOfEvents = (ULONG)(InputInformation->Last - InputInformation->Out);
    00390         *NumberOfEvents += (ULONG)(InputInformation->In - InputInformation->First);
    00391     }
    00392     else {
    00393         *NumberOfEvents = (ULONG)(InputInformation->In - InputInformation->Out);
    00394     }
    00395     *NumberOfEvents /= sizeof(INPUT_RECORD);
    00396
    00397     return STATUS_SUCCESS;
    00398 }

VOID HandleCtrlEvent | ( | IN PCONSOLE_INFORMATION | Console,
|  | IN DWORD | EventType
| ) |

Definition at line 3430 of file ntcon/server/input.c.

References ASSERT, CONSOLE_CTRL_BREAK_FLAG, CONSOLE_CTRL_C_FLAG, CONSOLE_CTRL_CLOSE_FLAG, and FALSE.

Referenced by ConsoleWindowProc(), HandleKeyEvent(), and SrvGenerateConsoleCtrlEvent().

    03434 {
    03435     switch (EventType) {
    03436         case CTRL_C_EVENT:
    03437             Console->CtrlFlags |= CONSOLE_CTRL_C_FLAG;
    03438             break;
    03439         case CTRL_BREAK_EVENT:
    03440             Console->CtrlFlags |= CONSOLE_CTRL_BREAK_FLAG;
    03441             break;
    03442         case CTRL_CLOSE_EVENT:
    03443             Console->CtrlFlags |= CONSOLE_CTRL_CLOSE_FLAG;
    03444             break;
    03445         default:
    03446             ASSERT (FALSE);
    03447     }
    03448 }

VOID HandleFocusEvent | ( | IN PCONSOLE_INFORMATION | Console,
|  | IN BOOL | bSetFocus
| ) |

Definition at line 3369 of file ntcon/server/input.c.

References CONSOLE_CONNECTED_TO_EMULATOR, CONSOLE_VDM_REGISTERED, NtUserSetInformationThread(), TIF_DOSEMULATOR, TIF_VDMAPP, and WriteInputBuffer().

Referenced by ConsoleWindowProc(), and DisplayModeTransition().

    03373 {
    03374     INPUT_RECORD InputEvent;
    03375     ULONG EventsWritten;
    03376     USERTHREAD_FLAGS Flags;
    03377
    03378     InputEvent.EventType = FOCUS_EVENT;
    03379     InputEvent.Event.FocusEvent.bSetFocus = bSetFocus;
    03380
    03381     Flags.dwFlags = 0;
    03382     if (bSetFocus) {
    03383         if (Console->Flags & CONSOLE_VDM_REGISTERED) {
    03384             Flags.dwFlags |= TIF_VDMAPP;
    03385         }
    03386         if (Console->Flags & CONSOLE_CONNECTED_TO_EMULATOR) {
    03387             Flags.dwFlags |= TIF_DOSEMULATOR;
    03388         }
    03389     }
    03390
    03391     Flags.dwMask = (TIF_VDMAPP | TIF_DOSEMULATOR);
    03392     NtUserSetInformationThread(Console->InputThreadInfo->ThreadHandle,
    03393             UserThreadFlags, &Flags, sizeof(Flags));
    03394     EventsWritten = WriteInputBuffer( Console,
    03395                                       &Console->InputBuffer,
    03396                                       &InputEvent,
    03397                                       1
    03398                                      );
    03399 #if DBG
    03400     if (EventsWritten != 1) {
    03401         OutputDebugStringA("PutInputInBuffer: EventsWritten != 1, 1 expected\n");
    03402     }
    03403 #endif
    03404 }

VOID HandleKeyEvent | ( | IN PCONSOLE_INFORMATION | Console,
|  | IN HWND | hWnd,
|  | IN UINT | Message,
|  | IN WPARAM | wParam,
|  | IN LPARAM | lParam
| ) |

Definition at line 2397 of file ntcon/server/input.c.

References ASSERT, BOOL, _SCREEN_INFORMATION::BufferInfo, BYTE, _ROW::CharRow, ClearScroll(), ClearSelection(), CodePageToCharSet(), CONIME_HOTKEY, CONIME_KEYDATA, CONIME_NOTIFY_VK_KANA, CONSOLE_CTRL_BREAK_SEEN, CONSOLE_CTRL_C_SEEN, CONSOLE_IGNORE_NEXT_KEYUP, CONSOLE_IS_IME_ENABLED, CONSOLE_MOUSE_DOWN, CONSOLE_MOUSE_SELECTION, CONSOLE_SCROLLBAR_TRACKING, CONSOLE_SCROLLING, CONSOLE_SELECTING, CONSOLE_SELECTION_NOT_EMPTY, CONSOLE_SUSPENDED, CONSOLE_TEXTMODE_BUFFER, CONSOLE_VDM_REGISTERED, CONSOLE_WINDOW_SIZE_Y, ConsoleHideCursor(), ConsoleShowCursor(), CTRL_BUT_NOT_ALT, DialogBoxCount, DoCopy(), DWORD, ExtendSelection(), FALSE, FlushInputBuffer(), GetControlKeyState(), GetKeyboardState, GetKeyState(), HandleCtrlEvent(), HorizontalScroll(), hWnd, ImmConversionToConsole(), IsSystemKey(), KEY_PRESSED, KEY_TRANSITION_UP, MakeCursorVisible(), MAX_CHARS_FROM_1_KEYSTROKE, MyInvert(), NT_SUCCESS, NtUserCheckImeHotKey(), NtUserGetImeHotKey(), NULL, PostMessage(), RetrieveKeyInfo(), _SCREEN_INFORMATION::ScreenBufferSize, SHORT, StoreSelection(), TerminateRead(), ToUnicodeEx(), TRUE, UINT, VerticalScroll(), and WriteInputBuffer().

Referenced by ConsoleWindowProc(), and HandleSysKeyEvent().

    02404 {
    02405     INPUT_RECORD InputEvent;
    02406     BOOLEAN ContinueProcessing;
    02407     ULONG EventsWritten;
    02408     WORD VirtualKeyCode;
    02409     ULONG ControlKeyState;
    02410     BOOL bKeyDown;
    02411     BOOL bGenerateBreak=FALSE;
    02412 #ifdef FE_SB
    02413     BOOL KeyMessageFromConsoleIME;
    02414 #endif
    02415
    02416 #ifdef FE_SB
    02417     // v-HirShi Sep.21.1995 For Console IME
    02418     if ((WM_KEYFIRST+CONIME_KEYDATA) <= Message && Message <= (WM_KEYLAST+CONIME_KEYDATA)) {
    02419         Message -= CONIME_KEYDATA ;
    02420         KeyMessageFromConsoleIME = TRUE ;
    02421     }
    02422     else {
    02423         KeyMessageFromConsoleIME = FALSE ;
    02424     }
    02425 #endif
    02426     /*
    02427      * BOGUS for WM_CHAR/WM_DEADCHAR, in which LOWORD(lParam) is a character
    02428      */
    02429     VirtualKeyCode = LOWORD(wParam);
    02430     ControlKeyState = GetControlKeyState(lParam);
    02431     bKeyDown = !(lParam & KEY_TRANSITION_UP);
    02432
    02433     //
    02434     // Make sure we retrieve the key info first, or we could chew up
    02435     // unneeded space in the key info table if we bail out early.
    02436     //
    02437
    02438     InputEvent.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
    02439     InputEvent.Event.KeyEvent.wVirtualScanCode = (BYTE)(HIWORD(lParam));
    02440     if (Message == WM_CHAR || Message == WM_SYSCHAR ||
    02441         Message == WM_DEADCHAR || Message == WM_SYSDEADCHAR) {
    02442         RetrieveKeyInfo(hWnd,
    02443                         &InputEvent.Event.KeyEvent.wVirtualKeyCode,
    02444                         &InputEvent.Event.KeyEvent.wVirtualScanCode,
    02445                         !(Console->InputBuffer.ImeMode.Open ^ KeyMessageFromConsoleIME));
    02446         VirtualKeyCode = InputEvent.Event.KeyEvent.wVirtualKeyCode;
    02447     }
    02448
    02449     //
    02450     // If this is a key up message, should we ignore it? We do this
    02451     // so that if a process reads a line from the input buffer, the
    02452     // key up event won't get put in the buffer after the read
    02453     // completes.
    02454     //
    02455
    02456     if (Console->Flags & CONSOLE_IGNORE_NEXT_KEYUP) {
    02457         Console->Flags &= ~CONSOLE_IGNORE_NEXT_KEYUP;
    02458         if (!bKeyDown)
    02459             return;
    02460     }
    02461
    02462 #ifdef FE_SB
    02463     // v-HirShi Sep.21.1995 For Console IME
    02464     if (KeyMessageFromConsoleIME) {
    02465         goto FromConsoleIME ;
    02466     }
    02467 #endif
    02468
    02469     if (Console->Flags & CONSOLE_SELECTING) {
    02470
    02471         if (!bKeyDown) {
    02472             return;
    02473         }
    02474
    02475         //
    02476         // if escape or ctrl-c, cancel selection
    02477         //
    02478
    02479         if (!(Console->SelectionFlags & CONSOLE_MOUSE_DOWN) ) {
    02480             if (VirtualKeyCode == VK_ESCAPE ||
    02481                 (VirtualKeyCode == 'C' &&
    02482                  (GetKeyState(VK_CONTROL) & KEY_PRESSED) )) {
    02483                 ClearSelection(Console);
    02484                 return;
    02485             } else if (VirtualKeyCode == VK_RETURN) {
    02486
    02487                 // if return, copy selection
    02488
    02489                 DoCopy(Console);
    02490                 return;
    02491             }
    02492         }
    02493         if (!(Console->SelectionFlags & CONSOLE_MOUSE_SELECTION)) {
    02494             if ((Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) &&
    02495                 (VirtualKeyCode == VK_RIGHT ||
    02496                  VirtualKeyCode == VK_LEFT ||
    02497                  VirtualKeyCode == VK_UP ||
    02498                  VirtualKeyCode == VK_DOWN ||
    02499                  VirtualKeyCode == VK_NEXT ||
    02500                  VirtualKeyCode == VK_PRIOR ||
    02501                  VirtualKeyCode == VK_END ||
    02502                  VirtualKeyCode == VK_HOME
    02503                 ) ) {
    02504                 PSCREEN_INFORMATION ScreenInfo;
    02505 #ifdef FE_SB
    02506                 SHORT RowIndex;
    02507                 PROW Row;
    02508                 BYTE KAttrs;
    02509                 SHORT NextRightX;
    02510                 SHORT NextLeftX;
    02511 #endif
    02512
    02513                 ScreenInfo = Console->CurrentScreenBuffer;
    02514
    02515                 //
    02516                 // see if shift is down.  if so, we're extending
    02517                 // the selection.  otherwise, we're resetting the
    02518                 // anchor
    02519                 //
    02520
    02521                 ConsoleHideCursor(ScreenInfo);
    02522 #ifdef FE_SB
    02523                 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y) % ScreenInfo->ScreenBufferSize.Y;
    02524                 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
    02525
    02526                if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
    02527                {
    02528                     KAttrs = Row->CharRow.KAttrs[ScreenInfo->BufferInfo.TextInfo.CursorPosition.X];
    02529                     if (KAttrs & ATTR_LEADING_BYTE)
    02530                         NextRightX = 2;
    02531                     else
    02532                         NextRightX = 1;
    02533                 }
    02534                 else
    02535                 {
    02536                     NextRightX = 1;
    02537                 }
    02538                 if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.X > 0) {
    02539                     if (CONSOLE_IS_DBCS_OUTPUTCP(Console)) {
    02540                         KAttrs = Row->CharRow.KAttrs[ScreenInfo->BufferInfo.TextInfo.CursorPosition.X-1];
    02541                         if (KAttrs & ATTR_TRAILING_BYTE)
    02542                             NextLeftX = 2;
    02543                         else if (KAttrs & ATTR_LEADING_BYTE) {
    02544                             if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.X-1 > 0) {
    02545                                 KAttrs = Row->CharRow.KAttrs[ScreenInfo->BufferInfo.TextInfo.CursorPosition.X-2];
    02546                                 if (KAttrs & ATTR_TRAILING_BYTE)
    02547                                     NextLeftX = 3;
    02548                                 else
    02549                                     NextLeftX = 2;
    02550                             }
    02551                             else
    02552                                 NextLeftX = 1;
    02553                         }
    02554                         else
    02555                             NextLeftX = 1;
    02556                     }
    02557                     else
    02558                         NextLeftX = 1;
    02559                 }
    02560
    02561                 switch (VirtualKeyCode) {
    02562                     case VK_RIGHT:
    02563                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.X+NextRightX < ScreenInfo->ScreenBufferSize.X) {
    02564                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.X+=NextRightX;
    02565                         }
    02566                         break;
    02567                     case VK_LEFT:
    02568                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.X > 0) {
    02569                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.X-=NextLeftX;
    02570                         }
    02571                         break;
    02572                     case VK_UP:
    02573                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y > 0) {
    02574                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y-=1;
    02575                         }
    02576                         break;
    02577                     case VK_DOWN:
    02578                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y+1 < ScreenInfo->ScreenBufferSize.Y) {
    02579                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y+=1;
    02580                         }
    02581                         break;
    02582                     case VK_NEXT:
    02583                         ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y += CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-1;
    02584                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y >= ScreenInfo->ScreenBufferSize.Y) {
    02585                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y = ScreenInfo->ScreenBufferSize.Y-1;
    02586                         }
    02587                         break;
    02588                     case VK_PRIOR:
    02589                         ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y -= CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-1;
    02590                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y < 0) {
    02591                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y = 0;
    02592                         }
    02593                         break;
    02594                     case VK_END:
    02595                         ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y = ScreenInfo->ScreenBufferSize.Y-CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
    02596                         break;
    02597                     case VK_HOME:
    02598                         ScreenInfo->BufferInfo.TextInfo.CursorPosition.X = 0;
    02599                         ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y = 0;
    02600                         break;
    02601                     default:
    02602                         ASSERT(FALSE);
    02603                 }
    02604 #else   // FE_SB
    02605                 switch (VirtualKeyCode) {
    02606                     case VK_RIGHT:
    02607                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.X+1 < ScreenInfo->ScreenBufferSize.X) {
    02608                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.X+=1;
    02609                         }
    02610                         break;
    02611                     case VK_LEFT:
    02612                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.X > 0) {
    02613                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.X-=1;
    02614                         }
    02615                         break;
    02616                     case VK_UP:
    02617                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y > 0) {
    02618                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y-=1;
    02619                         }
    02620                         break;
    02621                     case VK_DOWN:
    02622                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y+1 < ScreenInfo->ScreenBufferSize.Y) {
    02623                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y+=1;
    02624                         }
    02625                         break;
    02626                     case VK_NEXT:
    02627                         ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y += CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-1;
    02628                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y >= ScreenInfo->ScreenBufferSize.Y) {
    02629                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y = ScreenInfo->ScreenBufferSize.Y-1;
    02630                         }
    02631                         break;
    02632                     case VK_PRIOR:
    02633                         ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y -= CONSOLE_WINDOW_SIZE_Y(ScreenInfo)-1;
    02634                         if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y < 0) {
    02635                             ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y = 0;
    02636                         }
    02637                         break;
    02638                     case VK_END:
    02639                         ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y = ScreenInfo->ScreenBufferSize.Y-CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
    02640                         break;
    02641                     case VK_HOME:
    02642                         ScreenInfo->BufferInfo.TextInfo.CursorPosition.X = 0;
    02643                         ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y = 0;
    02644                         break;
    02645                     default:
    02646                         ASSERT(FALSE);
    02647                 }
    02648 #endif  // FE_SB
    02649                 ConsoleShowCursor(ScreenInfo);
    02650                 if (GetKeyState(VK_SHIFT) & KEY_PRESSED) {
    02651                     {
    02652                         ExtendSelection(Console,ScreenInfo->BufferInfo.TextInfo.CursorPosition);
    02653                     }
    02654                 } else {
    02655                     if (Console->SelectionFlags & CONSOLE_SELECTION_NOT_EMPTY) {
    02656                         MyInvert(Console,&Console->SelectionRect);
    02657                         Console->SelectionFlags &= ~CONSOLE_SELECTION_NOT_EMPTY;
    02658                         ConsoleShowCursor(ScreenInfo);
    02659                     }
    02660                     Console->SelectionAnchor = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
    02661                     MakeCursorVisible(ScreenInfo,Console->SelectionAnchor);
    02662                     Console->SelectionRect.Left = Console->SelectionRect.Right = Console->SelectionAnchor.X;
    02663                     Console->SelectionRect.Top = Console->SelectionRect.Bottom = Console->SelectionAnchor.Y;
    02664                 }
    02665                 return;
    02666             }
    02667         } else if (!(Console->SelectionFlags & CONSOLE_MOUSE_DOWN)) {
    02668
    02669             //
    02670             // if in mouse selection mode and user hits a key, cancel selection
    02671             //
    02672
    02673             if (!IsSystemKey(VirtualKeyCode)) {
    02674                 ClearSelection(Console);
    02675             }
    02676         }
    02677     } else if (Console->Flags & CONSOLE_SCROLLING) {
    02678
    02679         if (!bKeyDown) {
    02680             return;
    02681         }
    02682
    02683         //
    02684         // if escape, enter or ctrl-c, cancel scroll
    02685         //
    02686
    02687         if (VirtualKeyCode == VK_ESCAPE ||
    02688             VirtualKeyCode == VK_RETURN ||
    02689             (VirtualKeyCode == 'C' &&
    02690              (GetKeyState(VK_CONTROL) & KEY_PRESSED) )) {
    02691             ClearScroll(Console);
    02692         } else {
    02693             WORD ScrollCommand;
    02694             BOOL Horizontal=FALSE;
    02695             switch (VirtualKeyCode) {
    02696                 case VK_UP:
    02697                     ScrollCommand = SB_LINEUP;
    02698                     break;
    02699                 case VK_DOWN:
    02700                     ScrollCommand = SB_LINEDOWN;
    02701                     break;
    02702                 case VK_LEFT:
    02703                     ScrollCommand = SB_LINEUP;
    02704                     Horizontal=TRUE;
    02705                     break;
    02706                 case VK_RIGHT:
    02707                     ScrollCommand = SB_LINEDOWN;
    02708                     Horizontal=TRUE;
    02709                     break;
    02710                 case VK_NEXT:
    02711                     ScrollCommand = SB_PAGEDOWN;
    02712                     break;
    02713                 case VK_PRIOR:
    02714                     ScrollCommand = SB_PAGEUP;
    02715                     break;
    02716                 case VK_END:
    02717                     ScrollCommand = SB_PAGEDOWN;
    02718                     Horizontal=TRUE;
    02719                     break;
    02720                 case VK_HOME:
    02721                     ScrollCommand = SB_PAGEUP;
    02722                     Horizontal=TRUE;
    02723                     break;
    02724                 case VK_SHIFT:
    02725                 case VK_CONTROL:
    02726                 case VK_MENU:
    02727                     return;
    02728                 default:
    02729                     Beep(800, 200);
    02730                     return;
    02731             }
    02732             if (Horizontal)
    02733                 HorizontalScroll(Console->CurrentScreenBuffer, ScrollCommand, 0);
    02734             else
    02735                 VerticalScroll(Console, Console->CurrentScreenBuffer,ScrollCommand,0);
    02736         }
    02737         return;
    02738     }
    02739
    02740     //
    02741     // if the user is inputting chars at an inappropriate time, beep.
    02742     //
    02743
    02744     if ((Console->Flags & (CONSOLE_SELECTING | CONSOLE_SCROLLING | CONSOLE_SCROLLBAR_TRACKING)) &&
    02745         bKeyDown &&
    02746         !IsSystemKey(VirtualKeyCode)) {
    02747         Beep(800, 200);
    02748         return;
    02749     }
    02750
    02751     //
    02752     // if in fullscreen mode, process PrintScreen
    02753     //
    02754
    02755 #ifdef LATER
    02756 //
    02757 // Changed this code to get commas to work (build 485).
    02758 //
    02759 // Therese, the problem is that WM_CHAR/WM_SYSCHAR messages come through
    02760 // here - in this case, LOWORD(wParam) is a character value and not a virtual
    02761 // key. It happens that VK_SNAPSHOT == 0x2c, and the character value for a
    02762 // comma is also == 0x2c, so execution enters this conditional when a comma
    02763 // is hit. Commas aren't coming out because of the newly entered return
    02764 // statement.
    02765 //
    02766 // HandleKeyEvent() is making many virtual key comparisons - need to make
    02767 // sure that for each one, there is either no corresponding character value,
    02768 // or that you check before you compare so that you are comparing two values
    02769 // that have the same data type.
    02770 //
    02771 // I added the message comparison so that we know we're checking virtual
    02772 // keys against virtual keys and not characters.
    02773 //
    02774 // - scottlu
    02775 //
    02776
    02777 #endif
    02778
    02779     if (Message != WM_CHAR && Message != WM_SYSCHAR &&
    02780         VirtualKeyCode == VK_SNAPSHOT &&
    02781         !(Console->ReserveKeys & (CONSOLE_ALTPRTSC | CONSOLE_PRTSC )) ) {
    02782         if (Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
    02783             Console->SelectionFlags |= CONSOLE_SELECTION_NOT_EMPTY;
    02784             Console->SelectionRect = Console->CurrentScreenBuffer->Window;
    02785             StoreSelection(Console);
    02786             Console->SelectionFlags &= ~CONSOLE_SELECTION_NOT_EMPTY;
    02787         }
    02788         return;
    02789     }
    02790
    02791     //
    02792     // IME stuff
    02793     //
    02794     if (!(Console->Flags & CONSOLE_VDM_REGISTERED)) {
    02795         LPARAM lParamForHotKey ;
    02796         DWORD HotkeyID ;
    02797         lParamForHotKey = lParam ;
    02798
    02799         HotkeyID = NtUserCheckImeHotKey( (VirtualKeyCode & 0x00ff),lParamForHotKey) ;
    02800         //
    02801         // If it's direct KL switching hokey, handle it here
    02802         // regardless the system is IME enabled or not.
    02803         //
    02804         if (HotkeyID >= IME_HOTKEY_DSWITCH_FIRST && HotkeyID <= IME_HOTKEY_DSWITCH_LAST) {
    02805             UINT uModifier, uVkey;
    02806             HKL hkl;
    02807
    02808             RIPMSG1(RIP_VERBOSE, "HandleKeyEvent: handling IME HOTKEY id=%x", HotkeyID);
    02809             if (NtUserGetImeHotKey(HotkeyID, &uModifier, &uVkey, &hkl) && hkl != NULL) {
    02810                 BYTE bCharSetSys = CodePageToCharSet(GetACP());
    02811                 WPARAM wpSysChar = 0;
    02812                 CHARSETINFO cs;
    02813
    02814                 if (TranslateCharsetInfo((LPDWORD)LOWORD(hkl), &cs, TCI_SRCLOCALE)) {
    02815                     if (bCharSetSys == cs.ciCharset) {
    02816                         wpSysChar = INPUTLANGCHANGE_SYSCHARSET;
    02817                     }
    02818                 }
    02819                 PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, wpSysChar, (LPARAM)hkl);
    02820             }
    02821             return;
    02822         }
    02823
    02824         if (!(Console->InputBuffer.ImeMode.Disable) && CONSOLE_IS_IME_ENABLED()) {
    02825
    02826             if (HotkeyID != IME_INVALID_HOTKEY) {
    02827                 switch(HotkeyID) {
    02828                 case IME_JHOTKEY_CLOSE_OPEN:
    02829                     {
    02830                         BOOL fOpen = Console->InputBuffer.ImeMode.Open;
    02831                         if (!bKeyDown)
    02832                             break ;
    02833
    02834                         Console->InputBuffer.ImeMode.Open = !fOpen ;
    02835                         if (!NT_SUCCESS(ConsoleImeMessagePump(Console,
    02836                                               CONIME_HOTKEY,
    02837                                               (WPARAM)Console->ConsoleHandle,
    02838                                               HotkeyID))) {
    02839                             break;
    02840                         }
    02841
    02842                         // Update in the system conversion mode buffer.
    02843                         GetImeKeyState(Console, NULL);
    02844
    02845                         break ;
    02846                     }
    02847                 case IME_CHOTKEY_IME_NONIME_TOGGLE:
    02848                 case IME_THOTKEY_IME_NONIME_TOGGLE:
    02849                 case IME_CHOTKEY_SHAPE_TOGGLE:
    02850                 case IME_THOTKEY_SHAPE_TOGGLE:
    02851                 case IME_CHOTKEY_SYMBOL_TOGGLE:
    02852                 case IME_THOTKEY_SYMBOL_TOGGLE:
    02853                 case IME_KHOTKEY_SHAPE_TOGGLE:
    02854                 case IME_KHOTKEY_HANJACONVERT:
    02855                 case IME_KHOTKEY_ENGLISH:
    02856                 case IME_ITHOTKEY_RESEND_RESULTSTR:
    02857                 case IME_ITHOTKEY_PREVIOUS_COMPOSITION:
    02858                 case IME_ITHOTKEY_UISTYLE_TOGGLE:
    02859                 default:
    02860                     {
    02861                         if (!NT_SUCCESS(ConsoleImeMessagePump(Console,
    02862                                               CONIME_HOTKEY,
    02863                                               (WPARAM)Console->ConsoleHandle,
    02864                                               HotkeyID))) {
    02865                             break;
    02866                         }
    02867
    02868                         // Update in the system conversion mode buffer.
    02869                         GetImeKeyState(Console, NULL);
    02870
    02871                         break ;
    02872                     }
    02873                 }
    02874                 return ;
    02875             }
    02876
    02877             if ( CTRL_BUT_NOT_ALT(ControlKeyState) &&
    02878                     (bKeyDown) ) {
    02879                 if (VirtualKeyCode == 'C' &&
    02880                         Console->InputBuffer.InputMode & ENABLE_PROCESSED_INPUT) {
    02881                     goto FromConsoleIME ;
    02882                 }
    02883                 else if (VirtualKeyCode == VK_CANCEL) {
    02884                     goto FromConsoleIME ;
    02885                 }
    02886                 else if (VirtualKeyCode == 'S'){
    02887                     goto FromConsoleIME ;
    02888                 }
    02889             }
    02890             else if (VirtualKeyCode == VK_PAUSE ){
    02891                 goto FromConsoleIME ;
    02892             }
    02893             else if ( ((VirtualKeyCode == VK_SHIFT)   ||
    02894                        (VirtualKeyCode == VK_CONTROL) ||
    02895                        (VirtualKeyCode == VK_CAPITAL) ||
    02896                        (VirtualKeyCode == VK_KANA)    ||    // VK_KANA == VK_HANGUL
    02897                        (VirtualKeyCode == VK_JUNJA)   ||
    02898                        (VirtualKeyCode == VK_HANJA)   ||
    02899                        (VirtualKeyCode == VK_NUMLOCK) ||
    02900                        (VirtualKeyCode == VK_SCROLL)     )
    02901                       &&
    02902                       !(Console->InputBuffer.ImeMode.Unavailable) &&
    02903                       !(Console->InputBuffer.ImeMode.Open)
    02904                     )
    02905             {
    02906                 if (!NT_SUCCESS(ConsoleImeMessagePump(Console,
    02907                                       Message+CONIME_KEYDATA,
    02908                                       (WPARAM)LOWORD(wParam)<<16|LOWORD(VirtualKeyCode),
    02909                                       lParam
    02910                                      ))) {
    02911                     return;
    02912                 }
    02913                 goto FromConsoleIME ;
    02914             }
    02915
    02916             if (!Console->InputBuffer.ImeMode.Unavailable && Console->InputBuffer.ImeMode.Open) {
    02917                 if (! (HIWORD(lParam) & KF_REPEAT))
    02918                 {
    02919                     if (PRIMARYLANGID(LOWORD(Console->hklActive)) == LANG_JAPANESE &&
    02920                             (BYTE)wParam == VK_KANA) {
    02921                         if (!NT_SUCCESS(ConsoleImeMessagePump(Console,
    02922                                               CONIME_NOTIFY_VK_KANA,
    02923                                               0,
    02924                                               0
    02925                                              ))) {
    02926                             return;
    02927                         }
    02928                     }
    02929                 }
    02930
    02931                 ConsoleImeMessagePump(Console,
    02932                                       Message+CONIME_KEYDATA,
    02933                                       LOWORD(wParam)<<16|LOWORD(VirtualKeyCode),
    02934                                       lParam
    02935                                      );
    02936                 return ;
    02937             }
    02938         }
    02939     }
    02940 FromConsoleIME:
    02941
    02942     //
    02943     // ignore key strokes that will generate CHAR messages.  this is only
    02944     // necessary while a dialog box is up.
    02945     //
    02946
    02947     if (DialogBoxCount > 0) {
    02948         if (Message != WM_CHAR && Message != WM_SYSCHAR && Message != WM_DEADCHAR && Message != WM_SYSDEADCHAR) {
    02949             WCHAR awch[MAX_CHARS_FROM_1_KEYSTROKE];
    02950             int cwch;
    02951             BYTE KeyState[256];
    02952
    02953             GetKeyboardState(KeyState);
    02954             cwch = ToUnicodeEx((UINT)wParam,HIWORD(lParam),KeyState,awch,
    02955                                MAX_CHARS_FROM_1_KEYSTROKE,
    02956                                //TM_POSTCHARBREAKS | (KeyState(VK_MENU) & 1));
    02957                                TM_POSTCHARBREAKS,
    02958                                (HKL)NULL);
    02959             if (cwch != 0) {
    02960                 return;
    02961             }
    02962         } else {
    02963             // remember to generate break
    02964             if (Message == WM_CHAR) {
    02965                 bGenerateBreak=TRUE;
    02966             }
    02967         }
    02968     }
    02969
    02970 #ifdef FE_IME
    02971     // ignore key stroke while IME property is up.
    02972     if (Console->InputBuffer.hWndConsoleIME)
    02973         return;
    02974 #endif
    02975
    02976     InputEvent.EventType = KEY_EVENT;
    02977     InputEvent.Event.KeyEvent.bKeyDown = bKeyDown;
    02978     InputEvent.Event.KeyEvent.wRepeatCount = LOWORD(lParam);
    02979
    02980     if (Message == WM_CHAR || Message == WM_SYSCHAR || Message == WM_DEADCHAR || Message == WM_SYSDEADCHAR) {
    02981         // If this is a fake character, zero the scancode.
    02982         if (lParam & 0x02000000) {
    02983             InputEvent.Event.KeyEvent.wVirtualScanCode = 0;
    02984         }
    02985         InputEvent.Event.KeyEvent.dwControlKeyState = GetControlKeyState(lParam);
    02986         if (Message == WM_CHAR || Message == WM_SYSCHAR) {
    02987             InputEvent.Event.KeyEvent.uChar.UnicodeChar = (WCHAR)wParam;
    02988         } else {
    02989             InputEvent.Event.KeyEvent.uChar.UnicodeChar = (WCHAR)0;
    02990         }
    02991     } else {
    02992         // if alt-gr, ignore
    02993         if (lParam & 0x02000000) {
    02994             return;
    02995         }
    02996         InputEvent.Event.KeyEvent.dwControlKeyState = ControlKeyState;
    02997         InputEvent.Event.KeyEvent.uChar.UnicodeChar = 0;
    02998     }
    02999
    03000 #ifdef FE_IME
    03001     if (CONSOLE_IS_IME_ENABLED()) {
    03002         // MSKK August.22.1993 KazuM
    03003         DWORD dwConversion;
    03004
    03005         if (!NT_SUCCESS(GetImeKeyState(Console, &dwConversion))) {
    03006             return;
    03007         }
    03008
    03009         InputEvent.Event.KeyEvent.dwControlKeyState |= ImmConversionToConsole(dwConversion);
    03010     }
    03011 #endif
    03012
    03013     ContinueProcessing=TRUE;
    03014
    03015     if (CTRL_BUT_NOT_ALT(InputEvent.Event.KeyEvent.dwControlKeyState) &&
    03016         InputEvent.Event.KeyEvent.bKeyDown) {
    03017
    03018         //
    03019         // check for ctrl-c, if in line input mode.
    03020         //
    03021
    03022         if (InputEvent.Event.KeyEvent.wVirtualKeyCode == 'C' &&
    03023             Console->InputBuffer.InputMode & ENABLE_PROCESSED_INPUT) {
    03024             HandleCtrlEvent(Console,CTRL_C_EVENT);
    03025             if (!Console->PopupCount)
    03026                 TerminateRead(Console,&Console->InputBuffer,CONSOLE_CTRL_C_SEEN);
    03027             if (!(Console->Flags & CONSOLE_SUSPENDED)) {
    03028                 ContinueProcessing=FALSE;
    03029             }
    03030         }
    03031
    03032         //
    03033         // check for ctrl-break.
    03034         //
    03035
    03036         else if (InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_CANCEL) {
    03037             FlushInputBuffer(&Console->InputBuffer);
    03038             HandleCtrlEvent(Console,CTRL_BREAK_EVENT);
    03039             if (!Console->PopupCount)
    03040                 TerminateRead(Console,&Console->InputBuffer,CONSOLE_CTRL_BREAK_SEEN);
    03041             if (!(Console->Flags & CONSOLE_SUSPENDED)) {
    03042                 ContinueProcessing=FALSE;
    03043             }
    03044         }
    03045
    03046         //
    03047         // don't write ctrl-esc to the input buffer
    03048         //
    03049
    03050         else if (InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE &&
    03051                  !(Console->ReserveKeys & CONSOLE_CTRLESC)) {
    03052             ContinueProcessing=FALSE;
    03053         }
    03054     } else if (InputEvent.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED) &&
    03055                InputEvent.Event.KeyEvent.bKeyDown &&
    03056                InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE &&
    03057                !(Console->ReserveKeys & CONSOLE_ALTESC)) {
    03058         ContinueProcessing=FALSE;
    03059     }
    03060
    03061     if (ContinueProcessing) {
    03062         EventsWritten = WriteInputBuffer( Console,
    03063                                           &Console->InputBuffer,
    03064                                           &InputEvent,
    03065                                           1
    03066                                          );
    03067         if (EventsWritten && bGenerateBreak) {
    03068             InputEvent.Event.KeyEvent.bKeyDown = FALSE;
    03069             WriteInputBuffer( Console,
    03070                               &Console->InputBuffer,
    03071                               &InputEvent,
    03072                               1
    03073                              );
    03074         }
    03075     }
    03076     return;
    03077 }

VOID HandleMenuEvent | ( | IN PCONSOLE_INFORMATION | Console,
|  | IN DWORD | wParam
| ) |

Definition at line 3407 of file ntcon/server/input.c.

References WriteInputBuffer().

Referenced by ConsoleWindowProc().

    03411 {
    03412     INPUT_RECORD InputEvent;
    03413     ULONG EventsWritten;
    03414
    03415     InputEvent.EventType = MENU_EVENT;
    03416     InputEvent.Event.MenuEvent.dwCommandId = wParam;
    03417     EventsWritten = WriteInputBuffer( Console,
    03418                                       &Console->InputBuffer,
    03419                                       &InputEvent,
    03420                                       1
    03421                                      );
    03422 #if DBG
    03423     if (EventsWritten != 1) {
    03424         OutputDebugStringA("PutInputInBuffer: EventsWritten != 1, 1 expected\n");
    03425     }
    03426 #endif
    03427 }

BOOL HandleMouseEvent | ( | IN PCONSOLE_INFORMATION | Console,
|  | IN PSCREEN_INFORMATION | ScreenInfo,
|  | IN UINT | Message,
|  | IN WPARAM | wParam,
|  | IN LPARAM | lParam
| ) |

Definition at line 3080 of file ntcon/server/input.c.

References ASSERT, _ROW::CharRow, _CHAR_ROW::Chars, CONSOLE_HAS_FOCUS, CONSOLE_IGNORE_NEXT_MOUSE_INPUT, CONSOLE_MOUSE_DOWN, CONSOLE_MOUSE_SELECTION, CONSOLE_QUICK_EDIT_MODE, CONSOLE_SELECTING, CONSOLE_SELECTION_NOT_EMPTY, CONSOLE_TEXTMODE_BUFFER, ConvertMouseButtonState(), ConvertToMouseSelect(), DoCopy(), DoPaste(), ExtendSelection(), FALSE, GetControlKeyState(), GetKeyState(), gfTrimLeadingZeros, IS_WORD_DELIM, KEY_PRESSED, L, msgSelectMode, MyInvert(), ReleaseCapture(), SCR_FONTSIZE(), SetCapture, SetWinText(), SHORT, TRUE, UINT, UpdateMousePosition(), and WriteInputBuffer().

Referenced by ConsoleWindowProc().

    03093 {
    03094     ULONG ButtonFlags,EventFlags;
    03095     INPUT_RECORD InputEvent;
    03096     ULONG EventsWritten;
    03097     COORD MousePosition;
    03098     SHORT RowIndex;
    03099     PROW Row;
    03100
    03101     if (!(Console->Flags & CONSOLE_HAS_FOCUS) &&
    03102         !(Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) &&
    03103         !(Console->SelectionFlags & CONSOLE_MOUSE_DOWN)) {
    03104         return TRUE;
    03105     }
    03106
    03107     if (Console->Flags & CONSOLE_IGNORE_NEXT_MOUSE_INPUT) {
    03108         // only reset on up transition
    03109         if (Message != WM_LBUTTONDOWN &&
    03110             Message != WM_MBUTTONDOWN &&
    03111             Message != WM_RBUTTONDOWN) {
    03112             Console->Flags &= ~CONSOLE_IGNORE_NEXT_MOUSE_INPUT;
    03113             return FALSE;
    03114         }
    03115         return TRUE;
    03116     }
    03117
    03118     //
    03119     // translate mouse position into characters, if necessary.
    03120     //
    03121
    03122     MousePosition.X = LOWORD(lParam);
    03123     MousePosition.Y = HIWORD(lParam);
    03124     if (ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) {
    03125         MousePosition.X /= SCR_FONTSIZE(ScreenInfo).X;
    03126         MousePosition.Y /= SCR_FONTSIZE(ScreenInfo).Y;
    03127     }
    03128     MousePosition.X += ScreenInfo->Window.Left;
    03129     MousePosition.Y += ScreenInfo->Window.Top;
    03130
    03131     //
    03132     // make sure mouse position is clipped to screen buffer
    03133     //
    03134
    03135     if (MousePosition.X < 0) {
    03136         MousePosition.X = 0;
    03137     } else if (MousePosition.X >= ScreenInfo->ScreenBufferSize.X) {
    03138         MousePosition.X = ScreenInfo->ScreenBufferSize.X-1;
    03139     }
    03140     if (MousePosition.Y < 0) {
    03141         MousePosition.Y = 0;
    03142     } else if (MousePosition.Y >= ScreenInfo->ScreenBufferSize.Y) {
    03143         MousePosition.Y = ScreenInfo->ScreenBufferSize.Y-1;
    03144     }
    03145
    03146     if (Console->Flags & CONSOLE_SELECTING ||
    03147         ((Console->Flags & CONSOLE_QUICK_EDIT_MODE) &&
    03148          (Console->FullScreenFlags == 0)) ) {
    03149         if (Message == WM_LBUTTONDOWN) {
    03150
    03151             //
    03152             // make sure message matches button state
    03153             //
    03154
    03155             if (!(GetKeyState(VK_LBUTTON) & KEY_PRESSED)) {
    03156                 return FALSE;
    03157             }
    03158
    03159             if (Console->Flags & CONSOLE_QUICK_EDIT_MODE &&
    03160                 !(Console->Flags & CONSOLE_SELECTING)) {
    03161                 Console->Flags |= CONSOLE_SELECTING;
    03162                 Console->SelectionFlags = CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN | CONSOLE_SELECTION_NOT_EMPTY;
    03163
    03164                 //
    03165                 // invert selection
    03166                 //
    03167
    03168                 Console->SelectionAnchor = MousePosition;
    03169                 Console->SelectionRect.Left =Console->SelectionRect.Right = Console->SelectionAnchor.X;
    03170                 Console->SelectionRect.Top = Console->SelectionRect.Bottom = Console->SelectionAnchor.Y;
    03171                 MyInvert(Console,&Console->SelectionRect);
    03172                 SetWinText(Console,msgSelectMode,TRUE);
    03173                 SetCapture(Console->hWnd);
    03174             } else {
    03175
    03176             //
    03177             // We now capture the mouse to our Window. We do this so that the user can
    03178             //  "scroll" the selection endpoint to an off screen position by moving the
    03179             //  mouse off the client area.
    03180             //
    03181
    03182             if (Console->SelectionFlags & CONSOLE_MOUSE_SELECTION) {
    03183
    03184                 //
    03185                 // Check for SHIFT-Mouse Down "continue previous selection" command
    03186                 //
    03187
    03188                 if (GetKeyState(VK_SHIFT) & KEY_PRESSED) {
    03189                     Console->SelectionFlags |= CONSOLE_MOUSE_DOWN; // BUGBUG necessary flag?
    03190                     SetCapture(Console->hWnd);
    03191                     ExtendSelection(Console,
    03192                                     MousePosition
    03193                                    );
    03194                 } else {
    03195
    03196                     //
    03197                     // invert old selection, reset anchor, and invert
    03198                     // new selection.
    03199                     //
    03200
    03201                     MyInvert(Console,&Console->SelectionRect);
    03202                     Console->SelectionFlags |= CONSOLE_MOUSE_DOWN; // BUGBUG necessary flag?
    03203                     SetCapture(Console->hWnd);
    03204                     Console->SelectionAnchor = MousePosition;
    03205                     Console->SelectionRect.Left =Console->SelectionRect.Right = Console->SelectionAnchor.X;
    03206                     Console->SelectionRect.Top = Console->SelectionRect.Bottom = Console->SelectionAnchor.Y;
    03207                     MyInvert(Console,&Console->SelectionRect);
    03208                 }
    03209             } else {
    03210                 ConvertToMouseSelect(Console,
    03211                                      MousePosition
    03212                                     );
    03213             }
    03214             }
    03215         } else if (Message == WM_LBUTTONUP) {
    03216             if (Console->SelectionFlags & CONSOLE_MOUSE_SELECTION) {
    03217                 Console->SelectionFlags &= ~CONSOLE_MOUSE_DOWN;
    03218                 ReleaseCapture();
    03219             }
    03220         } else if (Message == WM_LBUTTONDBLCLK) {
    03221             if ((MousePosition.X == Console->SelectionAnchor.X) &&
    03222                 (MousePosition.Y == Console->SelectionAnchor.Y)) {
    03223                 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+MousePosition.Y) % ScreenInfo->ScreenBufferSize.Y;
    03224                 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
    03225                 while (Console->SelectionAnchor.X > 0) {
    03226                     if (IS_WORD_DELIM(Row->CharRow.Chars[Console->SelectionAnchor.X - 1]))
    03227                         break;
    03228                     Console->SelectionAnchor.X--;
    03229                 }
    03230                 while (MousePosition.X < ScreenInfo->ScreenBufferSize.X) {
    03231                     if (IS_WORD_DELIM(Row->CharRow.Chars[MousePosition.X]))
    03232                         break;
    03233                     MousePosition.X++;
    03234                 }
    03235                 if (gfTrimLeadingZeros) {
    03236                     //
    03237                     // Trim the leading zeros: 000fe12 -> fe12
    03238                     // Usefull for debugging
    03239                     //
    03240                     if (MousePosition.X > Console->SelectionAnchor.X + 2 &&
    03241                             Row->CharRow.Chars[Console->SelectionAnchor.X + 1] != L'x' &&
    03242                             Row->CharRow.Chars[Console->SelectionAnchor.X + 1] != L'X') {
    03243                         // Don't touch the selection begins with 0x
    03244                         while (Row->CharRow.Chars[Console->SelectionAnchor.X] == L'0' && Console->SelectionAnchor.X < MousePosition.X - 1) {
    03245                             Console->SelectionAnchor.X++;
    03246                         }
    03247                     }
    03248                 }
    03249                 ExtendSelection(Console, MousePosition);
    03250             }
    03251         } else if ((Message == WM_RBUTTONDOWN) || (Message == WM_RBUTTONDBLCLK)) {
    03252             if (!(Console->SelectionFlags & CONSOLE_MOUSE_DOWN)) {
    03253                 if (Console->Flags & CONSOLE_SELECTING) {
    03254                     DoCopy(Console);
    03255                 } else if (Console->Flags & CONSOLE_QUICK_EDIT_MODE) {
    03256                     DoPaste(Console);
    03257                 }
    03258                 Console->Flags |= CONSOLE_IGNORE_NEXT_MOUSE_INPUT;
    03259             }
    03260         } else if (Message == WM_MOUSEMOVE) {
    03261             if (Console->SelectionFlags & CONSOLE_MOUSE_DOWN) {
    03262                 ExtendSelection(Console,
    03263                                 MousePosition
    03264                                );
    03265             }
    03266         } else if (Message == WM_MOUSEWHEEL) {
    03267             return TRUE;
    03268         }
    03269         return FALSE;
    03270     }
    03271
    03272     if (!(Console->InputBuffer.InputMode & ENABLE_MOUSE_INPUT)) {
    03273         ReleaseCapture();
    03274         if (Console->FullScreenFlags == 0) {
    03275             return TRUE;
    03276         }
    03277         return FALSE;
    03278     }
    03279
    03280     // BUGBUG alt is not set correctly
    03281     InputEvent.Event.MouseEvent.dwControlKeyState = GetControlKeyState(0);
    03282
    03283     if (Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
    03284         if (MousePosition.X > ScreenInfo->Window.Right) {
    03285             MousePosition.X = ScreenInfo->Window.Right;
    03286         }
    03287         if (MousePosition.Y > ScreenInfo->Window.Bottom) {
    03288             MousePosition.Y = ScreenInfo->Window.Bottom;
    03289         }
    03290     }
    03291     switch (Message) {
    03292         case WM_LBUTTONDOWN:
    03293             SetCapture(Console->hWnd);
    03294             ButtonFlags = FROM_LEFT_1ST_BUTTON_PRESSED;
    03295             EventFlags = 0;
    03296             break;
    03297         case WM_LBUTTONUP:
    03298             ReleaseCapture();
    03299             ButtonFlags = 0;
    03300             EventFlags = 0;
    03301             break;
    03302         case WM_RBUTTONDOWN:
    03303             SetCapture(Console->hWnd);
    03304             ButtonFlags = RIGHTMOST_BUTTON_PRESSED;
    03305             EventFlags = 0;
    03306             break;
    03307         case WM_RBUTTONUP:
    03308             ReleaseCapture();
    03309             ButtonFlags = 0;
    03310             EventFlags = 0;
    03311             break;
    03312         case WM_MBUTTONDOWN:
    03313             SetCapture(Console->hWnd);
    03314             ButtonFlags = FROM_LEFT_2ND_BUTTON_PRESSED;
    03315             EventFlags = 0;
    03316             break;
    03317         case WM_MBUTTONUP:
    03318             ReleaseCapture();
    03319             ButtonFlags = 0;
    03320             EventFlags = 0;
    03321             break;
    03322         case WM_MOUSEMOVE:
    03323             ButtonFlags = 0;
    03324             EventFlags = MOUSE_MOVED;
    03325             break;
    03326         case WM_LBUTTONDBLCLK:
    03327             ButtonFlags = FROM_LEFT_1ST_BUTTON_PRESSED;
    03328             EventFlags = DOUBLE_CLICK;
    03329             break;
    03330         case WM_RBUTTONDBLCLK:
    03331             ButtonFlags = RIGHTMOST_BUTTON_PRESSED;
    03332             EventFlags = DOUBLE_CLICK;
    03333             break;
    03334         case WM_MBUTTONDBLCLK:
    03335             ButtonFlags = FROM_LEFT_2ND_BUTTON_PRESSED;
    03336             EventFlags = DOUBLE_CLICK;
    03337             break;
    03338         case WM_MOUSEWHEEL:
    03339             ButtonFlags = ((UINT)wParam & 0xFFFF0000);
    03340             EventFlags = MOUSE_WHEELED;
    03341             break;
    03342         default:
    03343             ASSERT(FALSE);
    03344     }
    03345     InputEvent.EventType = MOUSE_EVENT;
    03346     InputEvent.Event.MouseEvent.dwMousePosition = MousePosition;
    03347     InputEvent.Event.MouseEvent.dwEventFlags = EventFlags;
    03348     InputEvent.Event.MouseEvent.dwButtonState =
    03349         ConvertMouseButtonState(ButtonFlags,(UINT)wParam);
    03350     EventsWritten = WriteInputBuffer( Console,
    03351                                       &Console->InputBuffer,
    03352                                       &InputEvent,
    03353                                       1
    03354                                      );
    03355 #if DBG
    03356     if (EventsWritten != 1) {
    03357         OutputDebugStringA("PutInputInBuffer: EventsWritten != 1, 1 expected\n");
    03358     }
    03359 #endif
    03360 #ifdef i386
    03361     if (Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE) {
    03362         UpdateMousePosition(ScreenInfo,InputEvent.Event.MouseEvent.dwMousePosition);
    03363     }
    03364 #endif
    03365     return FALSE;
    03366 }

BOOL HandleSysKeyEvent | ( | IN PCONSOLE_INFORMATION | Console,
|  | IN HWND | hWnd,
|  | IN UINT | Message,
|  | IN WPARAM | wParam,
|  | IN LPARAM | lParam
| ) |

Definition at line 2272 of file ntcon/server/input.c.

References BOOL, ChangeDispSettings(), CONIME_KEYDATA, ConvertToFullScreen(), ConvertToWindowed(), FALSE, FullScreenInitialized, GetKeyState(), ghInstance, HandleKeyEvent(), hWnd, KEY_PRESSED, KEY_UP_TRANSITION, L, LOBYTE, MapVirtualKey(), msgNoFullScreen, ShowWindow, and TRUE.

Referenced by ConsoleWindowProc().

    02286 {
    02287     WORD VirtualKeyCode;
    02288     BOOL bCtrlDown;
    02289
    02290 #if defined (FE_IME)
    02291 // Sep.16.1995 Support Console IME by v-HirShi(Hirotoshi Shimizu)
    02292     if (Message == WM_SYSCHAR || Message == WM_SYSDEADCHAR ||
    02293         Message == WM_SYSCHAR+CONIME_KEYDATA || Message == WM_SYSDEADCHAR+CONIME_KEYDATA)
    02294 #else
    02295     if (Message == WM_SYSCHAR || Message == WM_SYSDEADCHAR)
    02296 #endif
    02297     {
    02298         VirtualKeyCode = (WORD)MapVirtualKey(LOBYTE(HIWORD(lParam)), 1);
    02299     } else {
    02300         VirtualKeyCode = LOWORD(wParam);
    02301     }
    02302
    02303     //
    02304     // check for ctrl-esc
    02305     //
    02306     bCtrlDown = GetKeyState(VK_CONTROL) & KEY_PRESSED;
    02307
    02308     if (VirtualKeyCode == VK_ESCAPE &&
    02309         bCtrlDown &&
    02310         !(GetKeyState(VK_MENU) & KEY_PRESSED) &&
    02311         !(GetKeyState(VK_SHIFT) & KEY_PRESSED) &&
    02312         !(Console->ReserveKeys & CONSOLE_CTRLESC) ) {
    02313         return TRUE;    // call DefWindowProc
    02314     }
    02315
    02316     if ((lParam & 0x20000000) == 0) {   // we're iconic
    02317
    02318
    02319         //
    02320         // Check for ENTER while ICONic (Restore accelerator)
    02321         //
    02322
    02323         if (VirtualKeyCode == VK_RETURN && !(Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE)) {
    02324
    02325             return TRUE;    // call DefWindowProc
    02326         } else {
    02327             HandleKeyEvent(Console,
    02328                            hWnd,
    02329                            Message,
    02330                            wParam,
    02331                            lParam
    02332                           );
    02333             return FALSE;
    02334         }
    02335     }
    02336
    02337     if (VirtualKeyCode == VK_RETURN && !bCtrlDown &&
    02338             !(Console->ReserveKeys & CONSOLE_ALTENTER)) {
    02339 #ifdef i386
    02340         if (!(Message & KEY_UP_TRANSITION)) {
    02341             if (FullScreenInitialized) {
    02342                 if (Console->FullScreenFlags == 0) {
    02343                     ConvertToFullScreen(Console);
    02344                     Console->FullScreenFlags = CONSOLE_FULLSCREEN;
    02345
    02346                     ChangeDispSettings(Console, Console->hWnd,CDS_FULLSCREEN);
    02347                 } else {
    02348                     ConvertToWindowed(Console);
    02349                     Console->FullScreenFlags &= ~CONSOLE_FULLSCREEN;
    02350
    02351                     ChangeDispSettings(Console, Console->hWnd,0);
    02352
    02353                     ShowWindow(Console->hWnd, SW_RESTORE);
    02354                 }
    02355             } else {
    02356                 WCHAR ItemString[70];
    02357                 LoadString(ghInstance,msgNoFullScreen,ItemString,70);
    02358                 MessageBoxEx(Console->hWnd,
    02359                             ItemString,
    02360                             Console->Title,
    02361                             MB_SYSTEMMODAL | MB_OK,
    02362                             0L
    02363                            );
    02364             }
    02365         }
    02366 #endif
    02367         return FALSE;
    02368     }
    02369
    02370     //
    02371     // make sure alt-space gets translated so that the system
    02372     // menu is displayed.
    02373     //
    02374
    02375     if (!(GetKeyState(VK_CONTROL) & KEY_PRESSED)) {
    02376         if (VirtualKeyCode == VK_SPACE && !(Console->ReserveKeys & CONSOLE_ALTSPACE)) {
    02377             return TRUE; // call DefWindowProc
    02378         }
    02379
    02380         if (VirtualKeyCode == VK_ESCAPE && !(Console->ReserveKeys & CONSOLE_ALTESC)) {
    02381             return TRUE;  // call DefWindowProc
    02382         }
    02383         if (VirtualKeyCode == VK_TAB && !(Console->ReserveKeys & CONSOLE_ALTTAB)) {
    02384             return TRUE;  // call DefWindowProc
    02385         }
    02386     }
    02387     HandleKeyEvent(Console,
    02388                    hWnd,
    02389                    Message,
    02390                    wParam,
    02391                    lParam
    02392                   );
    02393     return FALSE;
    02394 }

VOID InitializeThreadMessages | ( |  | ) |

Definition at line 1829 of file ntcon/server/input.c.

References gInputThreadMsg, and gInputThreadMsgLock.

Referenced by ConServerDllInitialization().

    01830 {
    01831     RtlEnterCriticalSection(&gInputThreadMsgLock);
    01832     InitializeListHead(&gInputThreadMsg);
    01833     RtlLeaveCriticalSection(&gInputThreadMsgLock);
    01834 }

BOOL InitWindowClass | ( | VOID |  | ) |

Definition at line 590 of file srvinit.c.

References ASSERT, BOOL, _CONSOLE_REGISTRY_INFO::ColorTable, CONSOLE_WINDOW_CLASS, ConsoleWindowProc(), DefaultRegInfo, GetSystemMetrics(), ghDefaultIcon, ghDefaultSmIcon, ghInstance, ghModuleWin, ghNormalCursor, IDI_CONSOLE, LOBYTE, NtUserConsoleControl(), NULL, RegisterClassEx, and _CONSOLE_REGISTRY_INFO::ScreenFill.

Referenced by ConsoleInputThread().

    00591 {
    00592     WNDCLASSEX wc;
    00593     BOOL retval;
    00594     ATOM atomConsoleClass;
    00595
    00596     ghNormalCursor = LoadCursor(NULL, IDC_ARROW);
    00597     ASSERT(ghModuleWin != NULL);
    00598     ghDefaultIcon       = LoadIcon(ghModuleWin, MAKEINTRESOURCE(IDI_CONSOLE));
    00599     ghDefaultSmIcon     = LoadImage(ghModuleWin, MAKEINTRESOURCE(IDI_CONSOLE), IMAGE_ICON,
    00600                                     GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
    00601                                     LR_SHARED);
    00602     wc.hIcon            = ghDefaultIcon;
    00603     wc.cbSize           = sizeof(WNDCLASSEX);
    00604     wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
    00605     wc.lpfnWndProc      = ConsoleWindowProc;
    00606     wc.cbClsExtra       = 0;
    00607     wc.cbWndExtra       = GWL_CONSOLE_WNDALLOC;
    00608     wc.hInstance        = ghInstance;
    00609     wc.hCursor          = ghNormalCursor;
    00610     wc.hbrBackground    = CreateSolidBrush(DefaultRegInfo.ColorTable[LOBYTE(DefaultRegInfo.ScreenFill.Attributes >> 4) & 0xF]);
    00611     wc.lpszMenuName     = NULL;
    00612     wc.lpszClassName    = CONSOLE_WINDOW_CLASS;
    00613     wc.hIconSm          = ghDefaultSmIcon;
    00614
    00615     atomConsoleClass = RegisterClassEx(&wc);
    00616     retval = (atomConsoleClass != 0);
    00617
    00618     if (retval)
    00619         NtUserConsoleControl(ConsoleClassAtom, &atomConsoleClass, sizeof(ATOM));
    00620
    00621     return retval;
    00622 }

ULONG InputExceptionFilter | ( | PEXCEPTION_POINTERS | pexi | ) |

Definition at line 1795 of file ntcon/server/input.c.

References DbgPrint, EXCEPTION_EXECUTE_HANDLER, NT_SUCCESS, NtQuerySystemInformation(), NTSTATUS(), NULL, and Status.

    01797 {
    01798     NTSTATUS Status;
    01799     SYSTEM_KERNEL_DEBUGGER_INFORMATION KernelDebuggerInfo;
    01800
    01801     if (pexi->ExceptionRecord->ExceptionCode != STATUS_PORT_DISCONNECTED) {
    01802         Status = NtQuerySystemInformation( SystemKernelDebuggerInformation,
    01803                                            &KernelDebuggerInfo,
    01804                                            sizeof(KernelDebuggerInfo),
    01805                                            NULL
    01806                                          );
    01807
    01808         if (NT_SUCCESS(Status) && KernelDebuggerInfo.KernelDebuggerEnabled) {
    01809             DbgPrint("Unhandled Exception hit in csrss.exe InputExceptionFilter\n");
    01810             DbgPrint("first, enter !exr %p for the exception record\n", pexi->ExceptionRecord);
    01811             DbgPrint("next, enter !cxr %p for the context\n", pexi->ContextRecord);
    01812             DbgPrint("then !kb to get the faulting stack\n");
    01813             DbgBreakPoint();
    01814         }
    01815     }
    01816
    01817     return EXCEPTION_EXECUTE_HANDLER;
    01818 }

__inline BOOL IsSystemKey | ( | WORD | wVirtualKeyCode | ) |

Definition at line 1320 of file ntcon/server/input.c.

References FALSE, and TRUE.

Referenced by HandleKeyEvent(), and PreprocessInput().

    01323 {
    01324     switch (wVirtualKeyCode) {
    01325     case VK_SHIFT:
    01326     case VK_CONTROL:
    01327     case VK_MENU:
    01328     case VK_PAUSE:
    01329     case VK_CAPITAL:
    01330     case VK_LWIN:
    01331     case VK_RWIN:
    01332     case VK_NUMLOCK:
    01333     case VK_SCROLL:
    01334         return TRUE;
    01335     }
    01336     return FALSE;
    01337 }

VOID KillProcess | ( | PCONSOLE_PROCESS_TERMINATION_RECORD | ProcessHandleRecord,
|  | ULONG_PTR | ProcessId
| ) |

Definition at line 3451 of file ntcon/server/input.c.

References _CONSOLE_PROCESS_TERMINATION_RECORD::bDebugee, BHE_FORCE, BoostHardError(), CMSHUNGAPPTIMEOUT, DbgPrint, FALSE, NT_SUCCESS, NTSTATUS(), NtTerminateProcess(), NtWaitForSingleObject(), and _CONSOLE_PROCESS_TERMINATION_RECORD::ProcessHandle.

Referenced by CreateCtrlThread().

    03455 {
    03456     NTSTATUS status;
    03457
    03458     //
    03459     // Just terminate the process outright.
    03460     //
    03461
    03462     status = NtTerminateProcess(ProcessHandleRecord->ProcessHandle,
    03463                 ProcessHandleRecord->bDebugee ? DBG_TERMINATE_PROCESS : CONTROL_C_EXIT);
    03464
    03465 #if DBG
    03466     if (status != STATUS_SUCCESS &&
    03467             status != STATUS_PROCESS_IS_TERMINATING &&
    03468             status != STATUS_THREAD_WAS_SUSPENDED &&
    03469             !(status == STATUS_ACCESS_DENIED && ProcessHandleRecord->bDebugee)) {
    03470         DbgPrint("NtTerminateProcess failed - status = %x\n", status);
    03471         DbgBreakPoint();
    03472     }
    03473 #endif
    03474
    03475     //
    03476     // Clear any remaining hard errors for the process.
    03477     //
    03478
    03479     if (ProcessId)
    03480         BoostHardError(ProcessId, BHE_FORCE);
    03481
    03482     //
    03483     // Give the process 5 seconds to exit.
    03484     //
    03485
    03486     if (NT_SUCCESS(status)) {
    03487         LARGE_INTEGER li;
    03488
    03489         li.QuadPart = (LONGLONG)-10000 * CMSHUNGAPPTIMEOUT;
    03490         status = NtWaitForSingleObject(ProcessHandleRecord->ProcessHandle,
    03491                                        FALSE,
    03492                                        &li);
    03493         if (status != STATUS_WAIT_0) {
    03494             RIPMSG2(RIP_WARNING,
    03495                     "KillProcess: wait for process %x failed with status %x",
    03496                     ProcessId, status);
    03497         }
    03498     }
    03499 }

DWORD PrependInputBuffer | ( | IN PCONSOLE_INFORMATION | Console,
|  | IN PINPUT_INFORMATION | InputInformation,
|  | IN PINPUT_RECORD | lpBuffer,
|  | IN DWORD | nLength
| ) |

Definition at line 1410 of file ntcon/server/input.c.

References BOOL, BUFFER_TAG, ConsoleHeapAlloc, ConsoleHeapFree, DWORD, FALSE, GetNumberOfReadyEvents(), MAKE_TAG, NT_SUCCESS, NtSetEvent(), NTSTATUS(), NULL, PreprocessInput(), ReadBuffer(), Status, TRUE, WakeUpReadersWaitingForData(), and WriteBuffer().

Referenced by SrvWriteConsoleInput().

    01419                    :
    01420
    01421     This routine writes to the beginning of the input buffer.
    01422
    01423 Arguments:
    01424
    01425     InputInformation - Pointer to input buffer information structure.
    01426
    01427     lpBuffer - Buffer to write from.
    01428
    01429     nLength - On input, number of events to write.  On output, number of
    01430     events written.
    01431
    01432 Return Value:
    01433
    01434 Note:
    01435
    01436     The console lock must be held when calling this routine.
    01437
    01438 --*/
    01439
    01440 {
    01441     NTSTATUS Status;
    01442     ULONG EventsWritten,EventsRead;
    01443     BOOL SetWaitEvent;
    01444     ULONG NumExistingEvents;
    01445     PINPUT_RECORD pExistingEvents;
    01446     BOOL Dummy;
    01447
    01448     nLength = PreprocessInput(Console, lpBuffer, nLength);
    01449     if (nLength == 0) {
    01450         return 0;
    01451     }
    01452
    01453     Status = GetNumberOfReadyEvents(InputInformation,
    01454                                     &NumExistingEvents
    01455                                    );
    01456
    01457     if (NumExistingEvents) {
    01458
    01459         pExistingEvents = ConsoleHeapAlloc(MAKE_TAG( BUFFER_TAG ),NumExistingEvents * sizeof(INPUT_RECORD));
    01460         if (pExistingEvents == NULL)
    01461             return (DWORD)STATUS_NO_MEMORY;
    01462         Status = ReadBuffer(InputInformation,
    01463                             pExistingEvents,
    01464                             NumExistingEvents,
    01465                             &EventsRead,
    01466                             FALSE,
    01467                             FALSE,
    01468                             &Dummy
    01469 #if defined(FE_SB)
    01470                             ,
    01471                             TRUE
    01472 #endif
    01473                            );
    01474
    01475         if (!NT_SUCCESS(Status)) {
    01476             ConsoleHeapFree(pExistingEvents);
    01477             return Status;
    01478         }
    01479     } else {
    01480         pExistingEvents = NULL;
    01481     }
    01482
    01483     //
    01484     // write new info to buffer
    01485     //
    01486
    01487     Status = WriteBuffer(InputInformation,
    01488                          lpBuffer,
    01489                          nLength,
    01490                          &EventsWritten,
    01491                          &SetWaitEvent
    01492                         );
    01493
    01494     //
    01495     // write existing info to buffer
    01496     //
    01497
    01498     if (pExistingEvents) {
    01499         Status = WriteBuffer(InputInformation,
    01500                              pExistingEvents,
    01501                              EventsRead,
    01502                              &EventsWritten,
    01503                              &Dummy
    01504                             );
    01505         ConsoleHeapFree(pExistingEvents);
    01506     }
    01507
    01508     if (SetWaitEvent) {
    01509         NtSetEvent(InputInformation->InputWaitEvent,NULL);
    01510     }
    01511
    01512     //
    01513     // alert any writers waiting for space
    01514     //
    01515
    01516     WakeUpReadersWaitingForData(Console,InputInformation);
    01517
    01518     return nLength;
    01519 }

DWORD PreprocessInput | ( | IN PCONSOLE_INFORMATION | Console,
|  | IN PINPUT_RECORD | InputEvent,
|  | IN DWORD | nLength
| ) |

Definition at line 1340 of file ntcon/server/input.c.

References CONSOLE_OUTPUT_SUSPENDED, CONSOLE_SUSPENDED, IsPauseKey(), IsSystemKey(), and UnblockWriteConsole().

Referenced by PrependInputBuffer(), and WriteInputBuffer().

    01348                    :
    01349
    01350     This routine processes special characters in the input stream.
    01351
    01352 Arguments:
    01353
    01354     Console - Pointer to console structure.
    01355
    01356     InputEvent - Buffer to write from.
    01357
    01358     nLength - Number of events to write.
    01359
    01360 Return Value:
    01361
    01362     Number of events to write after special characters have been stripped.
    01363
    01364 Note:
    01365
    01366     The console lock must be held when calling this routine.
    01367
    01368 --*/
    01369
    01370 {
    01371     ULONG NumEvents;
    01372
    01373
    01374     for (NumEvents = nLength; NumEvents != 0; NumEvents--) {
    01375         if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown) {
    01376             //
    01377             // if output is suspended, any keyboard input releases it.
    01378             //
    01379
    01380             if ((Console->Flags & CONSOLE_SUSPENDED) &&
    01381                 !IsSystemKey(InputEvent->Event.KeyEvent.wVirtualKeyCode)) {
    01382
    01383                 UnblockWriteConsole(Console, CONSOLE_OUTPUT_SUSPENDED);
    01384                 RtlMoveMemory(InputEvent, InputEvent + 1, (NumEvents - 1) * sizeof(INPUT_RECORD));
    01385                 nLength--;
    01386                 continue;
    01387             }
    01388
    01389             //
    01390             // intercept control-s
    01391             //
    01392
    01393             if ((Console->InputBuffer.InputMode & ENABLE_LINE_INPUT) &&
    01394                     (InputEvent->Event.KeyEvent.wVirtualKeyCode == VK_PAUSE ||
    01395                      IsPauseKey(&InputEvent->Event.KeyEvent))) {
    01396
    01397                 Console->Flags |= CONSOLE_OUTPUT_SUSPENDED;
    01398                 RtlMoveMemory(InputEvent, InputEvent + 1, (NumEvents - 1) * sizeof(INPUT_RECORD));
    01399                 nLength--;
    01400                 continue;
    01401             }
    01402         }
    01403         InputEvent++;
    01404     }
    01405     return nLength;
    01406 }

VOID ProcessCreateConsoleWindow | ( | IN LPMSG | lpMsg | ) |

Definition at line 1657 of file ntcon/server/input.c.

References ASSERT, CONSOLE_DEFAULT_BUFFER_SIZE, CreateWindowsWindow(), DBGPRINT, DialogBoxCount, FALSE, _CONSOLE_INFORMATION::Flags, ghInstance, hWnd, _CONSOLE_INFORMATION::hWnd, _CONSOLE_INFORMATION::InputThreadInfo, InputThreadTlsIndex, min, msgBufferTooBig, NELEM, NT_SUCCESS, NTSTATUS(), RevalidateConsole(), Status, _CONSOLE_INFORMATION::Title, _CONSOLE_INFORMATION::TitleLength, UnlockConsole(), and _INPUT_THREAD_INFO::WindowCount.

Referenced by ConsoleInputThread(), and DialogHookProc().

    01660 {
    01661     NTSTATUS Status;
    01662     // make sure this is a valid message
    01663     PCONSOLE_INFORMATION pConsole;
    01664
    01665     if (NT_SUCCESS(RevalidateConsole((HANDLE)lpMsg->wParam, &pConsole))) {
    01666
    01667         //
    01668         // Make sure the console doesn't already have a window.
    01669         //
    01670
    01671         if (pConsole->hWnd) {
    01672             RIPMSG1(RIP_WARNING, "Console %#p already has a window", pConsole);
    01673             UnlockConsole(pConsole);
    01674             return;
    01675         }
    01676
    01677         pConsole->InputThreadInfo = TlsGetValue(InputThreadTlsIndex);
    01678         DBGPRINT(("Before CreateWindowsWindow cWindows = %d\n",
    01679                   pConsole->InputThreadInfo->WindowCount));
    01680
    01681         Status = CreateWindowsWindow(pConsole);
    01682         DBGPRINT(("After  CreateWindowsWindow cWindows = %d\n",
    01683                   pConsole->InputThreadInfo->WindowCount));
    01684         switch (Status) {
    01685         case STATUS_SUCCESS:
    01686
    01687             //
    01688             // If we changed the screen buffer size, let the user know about it
    01689             // with a message box. Make sure we don't recurse too deeply in
    01690             // this code by limiting the number of message boxes on the screen
    01691             // at once. If there are already a bunch up there, the user should
    01692             // have the idea by now anyway.
    01693             //
    01694
    01695             if ((pConsole->Flags & CONSOLE_DEFAULT_BUFFER_SIZE) && (DialogBoxCount < 8)) {
    01696                 WCHAR ItemString[120];
    01697                 WCHAR Title[120];
    01698                 HWND hWnd = pConsole->hWnd;
    01699                 ULONG TitleLength = min(sizeof(Title)-sizeof(WCHAR), pConsole->TitleLength);
    01700                 RtlCopyMemory(Title, pConsole->Title, TitleLength);
    01701                 Title[TitleLength/sizeof(WCHAR)] = 0;
    01702                 UnlockConsole(pConsole);
    01703                 LoadString(ghInstance,msgBufferTooBig,ItemString,NELEM(ItemString));
    01704                 DialogBoxCount++;
    01705                 MessageBox(hWnd, ItemString, Title, MB_OK);
    01706                 DialogBoxCount--;
    01707                 break;
    01708             }
    01709             // FALL THRU
    01710         case STATUS_NO_MEMORY:
    01711             UnlockConsole(pConsole);
    01712             break;
    01713         case STATUS_INVALID_HANDLE:
    01714             // Console is gone, don't do anything.
    01715             break;
    01716         default:
    01717             KdPrint(("CONSRV: CreateWindowsWindow returned %x\n", Status));
    01718             ASSERT(FALSE);
    01719             break;
    01720         }
    01721     }
    01722 }

int ProcessCtrlEvents | ( | IN PCONSOLE_INFORMATION | Console | ) |

Definition at line 3865 of file ntcon/server/input.c.

References ASSERT, BOOL, CONSOLE_CTRL_BREAK_FLAG, CONSOLE_CTRL_C_FLAG, CONSOLE_CTRL_CLOSE_FLAG, CONSOLE_CTRL_LOGOFF_FLAG, CONSOLE_CTRL_SHUTDOWN_FLAG, CONSOLE_FORCE_SHUTDOWN_FLAG, CONSOLE_IN_DESTRUCTION, CONSOLE_PROCESS_TERMINATION_RECORD, CONSOLE_SHUTDOWN_FAILED, CONSOLE_TERMINATING, ConsoleHeapAlloc, ConsoleHeapFree, CreateCtrlThread(), CtrlRoutine, _CONSOLE_PROCESS_TERMINATION_RECORD::CtrlRoutine, _CONSOLE_PROCESS_HANDLE::CtrlRoutine, DestroyConsole(), DWORD, FALSE, L, MAKE_TAG, NELEM, NT_SUCCESS, NtClose(), NTSTATUS(), NULL, _CONSOLE_PROCESS_HANDLE::Process, _CONSOLE_PROCESS_HANDLE::ProcessHandle, Status, _CONSOLE_PROCESS_TERMINATION_RECORD::TerminateCount, _CONSOLE_PROCESS_HANDLE::TerminateCount, TITLE_TAG, TMP_TAG, and TRUE.

Referenced by UnlockConsole().

    03869 {
    03870     PWCHAR Title;
    03871     CONSOLE_PROCESS_TERMINATION_RECORD ProcessHandles[2];
    03872     PCONSOLE_PROCESS_TERMINATION_RECORD ProcessHandleList;
    03873     ULONG ProcessHandleListLength,i;
    03874     ULONG CtrlFlags;
    03875     PLIST_ENTRY ListHead, ListNext;
    03876     BOOL FreeTitle;
    03877     int Success;
    03878     PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
    03879     DWORD EventType;
    03880     DWORD LimitingProcessId;
    03881     NTSTATUS Status;
    03882
    03883     //
    03884     // If the console was marked for destruction, do it now.
    03885     //
    03886
    03887     if (Console->Flags & CONSOLE_IN_DESTRUCTION) {
    03888         DestroyConsole(Console);
    03889         return CONSOLE_SHUTDOWN_FAILED;
    03890     }
    03891
    03892     //
    03893     // make sure we don't try to process control events if this
    03894     // console is already going away
    03895     //
    03896
    03897     if (Console->Flags & CONSOLE_TERMINATING) {
    03898         Console->CtrlFlags = 0;
    03899     }
    03900
    03901     if (Console->CtrlFlags == 0) {
    03902         RtlLeaveCriticalSection(&Console->ConsoleLock);
    03903         return CONSOLE_SHUTDOWN_FAILED;
    03904     }
    03905
    03906     //
    03907     // make our own copy of the console process handle list
    03908     //
    03909
    03910     LimitingProcessId = Console->LimitingProcessId;
    03911     Console->LimitingProcessId = 0;
    03912
    03913     ListHead = &Console->ProcessHandleList;
    03914     ListNext = ListHead->Flink;
    03915     ProcessHandleListLength = 0;
    03916     while (ListNext != ListHead) {
    03917         ProcessHandleRecord = CONTAINING_RECORD( ListNext, CONSOLE_PROCESS_HANDLE, ListLink );
    03918         ListNext = ListNext->Flink;
    03919         if ( LimitingProcessId ) {
    03920             if ( ProcessHandleRecord->Process->ProcessGroupId == LimitingProcessId ) {
    03921                 ProcessHandleListLength += 1;
    03922             }
    03923         } else {
    03924             ProcessHandleListLength += 1;
    03925         }
    03926     }
    03927
    03928     //
    03929     // Use the stack buffer to hold the process handles if there are only a
    03930     // few, otherwise allocate a buffer from the heap.
    03931     //
    03932
    03933     if (ProcessHandleListLength <= NELEM(ProcessHandles)) {
    03934         ProcessHandleList = ProcessHandles;
    03935     } else {
    03936         ProcessHandleList = (PCONSOLE_PROCESS_TERMINATION_RECORD)ConsoleHeapAlloc(MAKE_TAG( TMP_TAG ),ProcessHandleListLength * sizeof(CONSOLE_PROCESS_TERMINATION_RECORD));
    03937         if (ProcessHandleList == NULL) {
    03938             RtlLeaveCriticalSection(&Console->ConsoleLock);
    03939             return CONSOLE_SHUTDOWN_FAILED;
    03940         }
    03941     }
    03942
    03943     ListNext = ListHead->Flink;
    03944     i=0;
    03945     while (ListNext != ListHead) {
    03946         BOOLEAN ProcessIsIn;
    03947
    03948         ASSERT(i<=ProcessHandleListLength);
    03949         ProcessHandleRecord = CONTAINING_RECORD( ListNext, CONSOLE_PROCESS_HANDLE, ListLink );
    03950         ListNext = ListNext->Flink;
    03951
    03952         if ( LimitingProcessId ) {
    03953             if ( ProcessHandleRecord->Process->ProcessGroupId == LimitingProcessId ) {
    03954                 ProcessIsIn = TRUE;
    03955             } else {
    03956                 ProcessIsIn = FALSE;
    03957             }
    03958         } else {
    03959             ProcessIsIn = TRUE;
    03960         }
    03961
    03962         if ( ProcessIsIn ) {
    03963             Success = (int)DuplicateHandle(NtCurrentProcess(),
    03964                            ProcessHandleRecord->ProcessHandle,
    03965                            NtCurrentProcess(),
    03966                            &ProcessHandleList[i].ProcessHandle,
    03967                            0,
    03968                            FALSE,
    03969                            DUPLICATE_SAME_ACCESS);
    03970
    03971             //
    03972             // If the duplicate failed, the best we can do is to skip
    03973             // including the process in the list and hope it goes
    03974             // away.
    03975             //
    03976             if (!Success) {
    03977                 KdPrint(("CONSRV: dup handle failed for %d of %d in %lx\n",
    03978                          i, ProcessHandleListLength, Console));
    03979                 continue;
    03980             }
    03981
    03982             if (Console->CtrlFlags & CONSOLE_CTRL_CLOSE_FLAG) {
    03983                 ProcessHandleRecord->TerminateCount++;
    03984             } else {
    03985                 ProcessHandleRecord->TerminateCount = 0;
    03986             }
    03987             ProcessHandleList[i].TerminateCount = ProcessHandleRecord->TerminateCount;
    03988
    03989             if (ProcessHandleRecord->CtrlRoutine) {
    03990                 ProcessHandleList[i].CtrlRoutine = ProcessHandleRecord->CtrlRoutine;
    03991             } else {
    03992                 ProcessHandleList[i].CtrlRoutine = CtrlRoutine;
    03993             }
    03994
    03995             //
    03996             // If this is the VDM process and we're closing the
    03997             // console window, move it to the front of the list
    03998             //
    03999
    04000             if (i > 0 && Console->VDMProcessId && Console->VDMProcessId ==
    04001                     ProcessHandleRecord->Process->ClientId.UniqueProcess &&
    04002                     ProcessHandleRecord->TerminateCount > 0) {
    04003                 CONSOLE_PROCESS_TERMINATION_RECORD ProcessHandle;
    04004                 ProcessHandle = ProcessHandleList[0];
    04005                 ProcessHandleList[0] = ProcessHandleList[i];
    04006                 ProcessHandleList[i] = ProcessHandle;
    04007             }
    04008
    04009             i++;
    04010         }
    04011     }
    04012     ProcessHandleListLength = i;
    04013     ASSERT(ProcessHandleListLength > 0);
    04014
    04015     // copy title.  titlelength does not include terminating null.
    04016
    04017     Title = (PWCHAR)ConsoleHeapAlloc(MAKE_TAG( TITLE_TAG ),Console->TitleLength+sizeof(WCHAR));
    04018     if (Title) {
    04019         FreeTitle = TRUE;
    04020         RtlCopyMemory(Title,Console->Title,Console->TitleLength+sizeof(WCHAR));
    04021     } else {
    04022         FreeTitle = FALSE;
    04023         Title = L"Command Window";
    04024     }
    04025
    04026     // copy ctrl flags
    04027
    04028     CtrlFlags = Console->CtrlFlags;
    04029     ASSERT( !((CtrlFlags & (CONSOLE_CTRL_CLOSE_FLAG | CONSOLE_CTRL_BREAK_FLAG | CONSOLE_CTRL_C_FLAG)) &&
    04030               (CtrlFlags & (CONSOLE_CTRL_LOGOFF_FLAG | CONSOLE_CTRL_SHUTDOWN_FLAG)) ));
    04031
    04032     Console->CtrlFlags = 0;
    04033
    04034     RtlLeaveCriticalSection(&Console->ConsoleLock);
    04035
    04036     //
    04037     // the ctrl flags could be a combination of the following
    04038     // values:
    04039     //
    04040     //        CONSOLE_CTRL_C_FLAG
    04041     //        CONSOLE_CTRL_BREAK_FLAG
    04042     //        CONSOLE_CTRL_CLOSE_FLAG
    04043     //        CONSOLE_CTRL_LOGOFF_FLAG
    04044     //        CONSOLE_CTRL_SHUTDOWN_FLAG
    04045     //
    04046
    04047     Success = CONSOLE_SHUTDOWN_FAILED;
    04048
    04049     EventType = (DWORD)-1;
    04050     switch (CtrlFlags & (CONSOLE_CTRL_CLOSE_FLAG | CONSOLE_CTRL_BREAK_FLAG |
    04051             CONSOLE_CTRL_C_FLAG | CONSOLE_CTRL_LOGOFF_FLAG |
    04052             CONSOLE_CTRL_SHUTDOWN_FLAG)) {
    04053
    04054     case CONSOLE_CTRL_CLOSE_FLAG:
    04055         EventType = CTRL_CLOSE_EVENT;
    04056         break;
    04057
    04058     case CONSOLE_CTRL_BREAK_FLAG:
    04059         EventType = CTRL_BREAK_EVENT;
    04060         break;
    04061
    04062     case CONSOLE_CTRL_C_FLAG:
    04063         EventType = CTRL_C_EVENT;
    04064         break;
    04065
    04066     case CONSOLE_CTRL_LOGOFF_FLAG:
    04067         EventType = CTRL_LOGOFF_EVENT;
    04068         break;
    04069
    04070     case CONSOLE_CTRL_SHUTDOWN_FLAG:
    04071         EventType = CTRL_SHUTDOWN_EVENT;
    04072         break;
    04073     }
    04074
    04075     if (EventType != (DWORD)-1) {
    04076
    04077         Success = CreateCtrlThread(ProcessHandleList,
    04078                 ProcessHandleListLength,
    04079                 Title,
    04080                 EventType,
    04081                 (CtrlFlags & CONSOLE_FORCE_SHUTDOWN_FLAG) != 0
    04082                 );
    04083     }
    04084
    04085     if (FreeTitle) {
    04086         ConsoleHeapFree(Title);
    04087     }
    04088
    04089     for (i=0;i<ProcessHandleListLength;i++) {
    04090         Status = NtClose(ProcessHandleList[i].ProcessHandle);
    04091         ASSERT(NT_SUCCESS(Status));
    04092     }
    04093
    04094     if (ProcessHandleList != ProcessHandles) {
    04095         ConsoleHeapFree(ProcessHandleList);
    04096     }
    04097
    04098     return Success;
    04099 }

NTSTATUS QueueThreadMessage | ( | DWORD | dwThreadId,
|  | UINT | message,
|  | WPARAM | wParam,
|  | LPARAM | lParam
| ) |

Definition at line 1860 of file ntcon/server/input.c.

References CM_CONSOLE_INPUT_THREAD_MSG, ConsoleHeapAlloc, ConsoleHeapFree, gInputThreadMsg, gInputThreadMsgLock, MAKE_TAG, NULL, PCONSOLE_THREAD_MSG, PostThreadMessage(), and TMP_TAG.

    01865 {
    01866     PCONSOLE_THREAD_MSG pConMsg;
    01867
    01868     // NOTE HIROYAMA: change this to RIP_VERBOSE
    01869     RIPMSG4(RIP_VERBOSE, "QueueThreadMessage: TID=%08x msg:%04x (%08x, %08x)",
    01870             dwThreadId, message, wParam, lParam);
    01871
    01872     pConMsg = ConsoleHeapAlloc(MAKE_TAG(TMP_TAG), sizeof *pConMsg);
    01873     if (pConMsg == NULL) {
    01874         RIPMSG0(RIP_WARNING, "QueueThreadMessage: failed to allocate pConMsg");
    01875         return STATUS_NO_MEMORY;
    01876     }
    01877
    01878     pConMsg->dwThreadId = dwThreadId;
    01879     pConMsg->Message = message;
    01880     pConMsg->wParam = wParam;
    01881     pConMsg->lParam = lParam;
    01882
    01883     RtlEnterCriticalSection(&gInputThreadMsgLock);
    01884     InsertHeadList(&gInputThreadMsg, &pConMsg->ListLink);
    01885     RtlLeaveCriticalSection(&gInputThreadMsgLock);
    01886
    01887     if (!PostThreadMessage(dwThreadId, CM_CONSOLE_INPUT_THREAD_MSG, 0, 0)) {
    01888         RIPMSG1(RIP_WARNING, "QueueThreadMessage: failed to post thread msg(%04x)", message);
    01889         RtlEnterCriticalSection(&gInputThreadMsgLock);
    01890         RemoveEntryList(&pConMsg->ListLink);
    01891         RtlLeaveCriticalSection(&gInputThreadMsgLock);
    01892         ConsoleHeapFree(pConMsg);
    01893         return STATUS_UNSUCCESSFUL;
    01894     }
    01895
    01896     return STATUS_SUCCESS;
    01897 }

NTSTATUS ReadBuffer | ( | IN PINPUT_INFORMATION | InputInformation,
|  | OUT PVOID | Buffer,
|  | IN ULONG | Length,
|  | OUT PULONG | EventsRead,
|  | IN BOOL | Peek,
|  | IN BOOL | StreamRead,
|  | OUT PBOOL | ResetWaitEvent
| ) |

Definition at line 616 of file ntcon/server/input.c.

References ASSERT, Buffer, _CONSOLE_INFORMATION::CP, FALSE, _CONSOLE_INFORMATION::hDC, PBYTE, TRUE, and Unicode.

Referenced by FlushAllButKeys(), PrependInputBuffer(), ReadInputBuffer(), and SetInputBufferSize().

    00630                    :
    00631
    00632     This routine reads from a buffer.  It does the actual circular buffer
    00633     manipulation.
    00634
    00635 Arguments:
    00636
    00637     InputInformation - buffer to read from
    00638
    00639     Buffer - buffer to read into
    00640
    00641     Length - length of buffer in events
    00642
    00643     EventsRead - where to store number of events read
    00644
    00645     Peek - if TRUE, don't remove data from buffer, just copy it.
    00646
    00647     StreamRead - if TRUE, events with repeat counts > 1 are returned
    00648     as multiple events.  also, EventsRead == 1.
    00649
    00650     ResetWaitEvent - on exit, TRUE if buffer became empty.
    00651
    00652 Return Value:
    00653
    00654     ??
    00655
    00656 Note:
    00657
    00658     The console lock must be held when calling this routine.
    00659
    00660 --*/
    00661
    00662 {
    00663     ULONG TransferLength,OldTransferLength;
    00664     ULONG BufferLengthInBytes;
    00665 #ifdef FE_SB
    00666     PCONSOLE_INFORMATION Console;
    00667     ULONG Length2;
    00668     PINPUT_RECORD BufferRecords;
    00669     PINPUT_RECORD QueueRecords;
    00670     WCHAR UniChar;
    00671     WORD EventType;
    00672 #endif
    00673
    00674 #ifdef FE_SB
    00675     Console = InputInformation->Console;
    00676 #endif
    00677     *ResetWaitEvent = FALSE;
    00678
    00679     //
    00680     // if StreamRead, just return one record.  if repeat count is greater
    00681     // than one, just decrement it.  the repeat count is > 1 if more than
    00682     // one event of the same type was merged.  we need to expand them back
    00683     // to individual events here.
    00684     //
    00685
    00686     if (StreamRead &&
    00687         ((PINPUT_RECORD)(InputInformation->Out))->EventType == KEY_EVENT) {
    00688
    00689         ASSERT(Length == 1);
    00690         ASSERT(InputInformation->In != InputInformation->Out);
    00691         RtlMoveMemory((PBYTE)Buffer,
    00692                       (PBYTE)InputInformation->Out,
    00693                       sizeof(INPUT_RECORD)
    00694                      );
    00695         InputInformation->Out += sizeof(INPUT_RECORD);
    00696         if (InputInformation->Last == InputInformation->Out) {
    00697             InputInformation->Out = InputInformation->First;
    00698         }
    00699         if (InputInformation->Out == InputInformation->In) {
    00700             *ResetWaitEvent = TRUE;
    00701         }
    00702         *EventsRead = 1;
    00703         return STATUS_SUCCESS;
    00704     }
    00705
    00706     BufferLengthInBytes = Length * sizeof(INPUT_RECORD);
    00707
    00708     //
    00709     // if in > out, buffer looks like this:
    00710     //
    00711     //         out     in
    00712     //    ______ _____________
    00713     //   |      |      |      |
    00714     //   | free | data | free |
    00715     //   |______|______|______|
    00716     //
    00717     // we transfer the requested number of events or the amount in the buffer
    00718     //
    00719
    00720     if (InputInformation->In > InputInformation->Out) {
    00721         if  ((InputInformation->In - InputInformation->Out) > BufferLengthInBytes) {
    00722             TransferLength = BufferLengthInBytes;
    00723         }
    00724         else {
    00725             TransferLength = (ULONG)(InputInformation->In - InputInformation->Out);
    00726         }
    00727 #ifdef FE_SB
    00728         if (!Unicode) {
    00729             BufferLengthInBytes = 0;
    00730             OldTransferLength = TransferLength / sizeof(INPUT_RECORD);
    00731             BufferRecords = (PINPUT_RECORD)Buffer;
    00732             QueueRecords = (PINPUT_RECORD)InputInformation->Out;
    00733
    00734             while (BufferLengthInBytes < Length &&
    00735                    OldTransferLength) {
    00736                 UniChar = QueueRecords->Event.KeyEvent.uChar.UnicodeChar;
    00737                 EventType = QueueRecords->EventType;
    00738                 *BufferRecords++ = *QueueRecords++;
    00739                 if (EventType == KEY_EVENT) {
    00740                     if (IsConsoleFullWidth(Console->hDC,
    00741                                            Console->CP,
    00742                                            UniChar)) {
    00743                         BufferLengthInBytes += 2;
    00744                     }
    00745                     else {
    00746                         BufferLengthInBytes++;
    00747                     }
    00748                 }
    00749                 else {
    00750                     BufferLengthInBytes++;
    00751                 }
    00752                 OldTransferLength--;
    00753             }
    00754             ASSERT(TransferLength >= OldTransferLength * sizeof(INPUT_RECORD));
    00755             TransferLength -= OldTransferLength * sizeof(INPUT_RECORD);
    00756         }
    00757         else
    00758 #endif
    00759         {
    00760             RtlMoveMemory((PBYTE)Buffer,
    00761                           (PBYTE)InputInformation->Out,
    00762                           TransferLength
    00763                          );
    00764         }
    00765         *EventsRead = TransferLength / sizeof(INPUT_RECORD);
    00766 #ifdef FE_SB
    00767         ASSERT(*EventsRead <= Length);
    00768 #endif
    00769         if (!Peek) {
    00770             InputInformation->Out += TransferLength;
    00771 #ifdef FE_SB
    00772             ASSERT(InputInformation->Out <= InputInformation->Last);
    00773 #endif
    00774         }
    00775         if (InputInformation->Out == InputInformation->In) {
    00776             *ResetWaitEvent = TRUE;
    00777         }
    00778         return STATUS_SUCCESS;
    00779     }
    00780
    00781     //
    00782     // if out > in, buffer looks like this:
    00783     //
    00784     //         in     out
    00785     //    ______ _____________
    00786     //   |      |      |      |
    00787     //   | data | free | data |
    00788     //   |______|______|______|
    00789     //
    00790     // we read from the out pointer to the end of the buffer then from the
    00791     // beginning of the buffer, until we hit the in pointer or enough bytes
    00792     // are read.
    00793     //
    00794
    00795     else {
    00796
    00797         if  ((InputInformation->Last - InputInformation->Out) > BufferLengthInBytes) {
    00798             TransferLength = BufferLengthInBytes;
    00799         }
    00800         else {
    00801             TransferLength = (ULONG)(InputInformation->Last - InputInformation->Out);
    00802         }
    00803 #ifdef FE_SB
    00804         if (!Unicode) {
    00805             BufferLengthInBytes = 0;
    00806             OldTransferLength = TransferLength / sizeof(INPUT_RECORD);
    00807             BufferRecords = (PINPUT_RECORD)Buffer;
    00808             QueueRecords = (PINPUT_RECORD)InputInformation->Out;
    00809
    00810             while (BufferLengthInBytes < Length &&
    00811                    OldTransferLength) {
    00812                 UniChar = QueueRecords->Event.KeyEvent.uChar.UnicodeChar;
    00813                 EventType = QueueRecords->EventType;
    00814                 *BufferRecords++ = *QueueRecords++;
    00815                 if (EventType == KEY_EVENT) {
    00816                     if (IsConsoleFullWidth(Console->hDC,
    00817                                            Console->CP,
    00818                                     UniChar)) {
    00819                         BufferLengthInBytes += 2;
    00820                     }
    00821                     else {
    00822                         BufferLengthInBytes++;
    00823                     }
    00824                 }
    00825                 else {
    00826                     BufferLengthInBytes++;
    00827                 }
    00828                 OldTransferLength--;
    00829             }
    00830             ASSERT(TransferLength >= OldTransferLength * sizeof(INPUT_RECORD));
    00831             TransferLength -= OldTransferLength * sizeof(INPUT_RECORD);
    00832         }
    00833         else
    00834 #endif
    00835         {
    00836             RtlMoveMemory((PBYTE)Buffer,
    00837                           (PBYTE)InputInformation->Out,
    00838                           TransferLength
    00839                          );
    00840         }
    00841         *EventsRead = TransferLength / sizeof(INPUT_RECORD);
    00842 #ifdef FE_SB
    00843         ASSERT(*EventsRead <= Length);
    00844 #endif
    00845
    00846         if (!Peek) {
    00847             InputInformation->Out += TransferLength;
    00848 #ifdef FE_SB
    00849             ASSERT(InputInformation->Out <= InputInformation->Last);
    00850 #endif
    00851             if (InputInformation->Out == InputInformation->Last) {
    00852                 InputInformation->Out = InputInformation->First;
    00853             }
    00854         }
    00855 #ifdef FE_SB
    00856         if (!Unicode) {
    00857             if (BufferLengthInBytes >= Length) {
    00858                 if (InputInformation->Out == InputInformation->In) {
    00859                     *ResetWaitEvent = TRUE;
    00860                 }
    00861                 return STATUS_SUCCESS;
    00862             }
    00863         }
    00864         else
    00865 #endif
    00866         if (*EventsRead == Length) {
    00867             if (InputInformation->Out == InputInformation->In) {
    00868                 *ResetWaitEvent = TRUE;
    00869             }
    00870             return STATUS_SUCCESS;
    00871         }
    00872
    00873         //
    00874         // hit end of buffer, read from beginning
    00875         //
    00876
    00877         OldTransferLength = TransferLength;
    00878 #ifdef FE_SB
    00879         Length2 = Length;
    00880         if (!Unicode) {
    00881             ASSERT(Length > BufferLengthInBytes);
    00882             Length -= BufferLengthInBytes;
    00883             if (Length == 0) {
    00884                 if (InputInformation->Out == InputInformation->In) {
    00885                     *ResetWaitEvent = TRUE;
    00886                 }
    00887             return STATUS_SUCCESS;
    00888             }
    00889             BufferLengthInBytes = Length * sizeof(INPUT_RECORD);
    00890
    00891             if ((InputInformation->In - InputInformation->First) > BufferLengthInBytes) {
    00892                 TransferLength = BufferLengthInBytes;
    00893             }
    00894             else {
    00895                 TransferLength = (ULONG)(InputInformation->In - InputInformation->First);
    00896             }
    00897         }
    00898         else
    00899 #endif
    00900         if  ((InputInformation->In - InputInformation->First) > (BufferLengthInBytes - OldTransferLength)) {
    00901             TransferLength = BufferLengthInBytes - OldTransferLength;
    00902         }
    00903         else {
    00904             TransferLength = (ULONG)(InputInformation->In - InputInformation->First);
    00905         }
    00906 #ifdef FE_SB
    00907         if (!Unicode) {
    00908             BufferLengthInBytes = 0;
    00909             OldTransferLength = TransferLength / sizeof(INPUT_RECORD);
    00910             QueueRecords = (PINPUT_RECORD)InputInformation->First;
    00911
    00912             while (BufferLengthInBytes < Length &&
    00913                    OldTransferLength) {
    00914                 UniChar = QueueRecords->Event.KeyEvent.uChar.UnicodeChar;
    00915                 EventType = QueueRecords->EventType;
    00916                 *BufferRecords++ = *QueueRecords++;
    00917                 if (EventType == KEY_EVENT) {
    00918                     if (IsConsoleFullWidth(Console->hDC,
    00919                                            Console->CP,
    00920                                     UniChar)) {
    00921                         BufferLengthInBytes += 2;
    00922                     }
    00923                     else {
    00924                         BufferLengthInBytes++;
    00925                     }
    00926                 }
    00927                 else {
    00928                     BufferLengthInBytes++;
    00929                 }
    00930                 OldTransferLength--;
    00931             }
    00932             ASSERT(TransferLength >= OldTransferLength * sizeof(INPUT_RECORD));
    00933             TransferLength -= OldTransferLength * sizeof(INPUT_RECORD);
    00934         }
    00935         else
    00936 #endif
    00937         {
    00938             RtlMoveMemory((PBYTE)Buffer+OldTransferLength,
    00939                           (PBYTE)InputInformation->First,
    00940                           TransferLength
    00941                          );
    00942         }
    00943         *EventsRead += TransferLength / sizeof(INPUT_RECORD);
    00944 #ifdef FE_SB
    00945         ASSERT(*EventsRead <= Length2);
    00946 #endif
    00947         if (!Peek) {
    00948             InputInformation->Out = InputInformation->First + TransferLength;
    00949         }
    00950         if (InputInformation->Out == InputInformation->In) {
    00951             *ResetWaitEvent = TRUE;
    00952         }
    00953         return STATUS_SUCCESS;
    00954     }
    00955 }

NTSTATUS ReadInputBuffer | ( | IN PINPUT_INFORMATION | InputInformation,
|  | OUT PINPUT_RECORD | lpBuffer,
|  | IN OUT PDWORD | nLength,
|  | IN BOOL | Peek,
|  | IN BOOL | WaitForData,
|  | IN BOOL | StreamRead,
|  | IN PCONSOLE_INFORMATION | Console,
|  | IN PHANDLE_DATA HandleData | OPTIONAL,
|  | IN PCSR_API_MSG Message | OPTIONAL,
|  | IN CSR_WAIT_ROUTINE WaitRoutine | OPTIONAL,
|  | IN PVOID WaitParameter | OPTIONAL,
|  | IN ULONG WaitParameterLength | OPTIONAL,
|  | IN BOOLEAN WaitBlockExists | OPTIONAL
| ) |

Definition at line 959 of file ntcon/server/input.c.

References ASSERT, BOOL, CONSOLE_STATUS_WAIT, FALSE, LockConsole, LockReadCount, NT_SUCCESS, NtClearEvent(), NTSTATUS(), ReadBuffer(), Status, Unicode, UnlockReadCount, and WaitForMoreToRead().

Referenced by DirectReadWaitRoutine(), GetChar(), and SrvGetConsoleInput().

    00981                    :
    00982
    00983     This routine reads from the input buffer.
    00984
    00985 Arguments:
    00986
    00987     InputInformation - Pointer to input buffer information structure.
    00988
    00989     lpBuffer - Buffer to read into.
    00990
    00991     nLength - On input, number of events to read.  On output, number of
    00992     events read.
    00993
    00994     Peek - If TRUE, copy events to lpBuffer but don't remove them from
    00995     the input buffer.
    00996
    00997     WaitForData - if TRUE, wait until an event is input.  if FALSE, return
    00998         immediately
    00999
    01000     StreamRead - if TRUE, events with repeat counts > 1 are returned
    01001     as multiple events.  also, EventsRead == 1.
    01002
    01003     Console - Pointer to console buffer information.
    01004
    01005     HandleData - Pointer to handle data structure.  This parameter is
    01006     optional if WaitForData is false.
    01007
    01008     Message - if called from dll (not InputThread), points to api
    01009     message.  this parameter is used for wait block processing.
    01010
    01011     WaitRoutine - Routine to call when wait is woken up.
    01012
    01013     WaitParameter - Parameter to pass to wait routine.
    01014
    01015     WaitParameterLength - Length of wait parameter.
    01016
    01017     WaitBlockExists - TRUE if wait block has already been created.
    01018
    01019 Return Value:
    01020
    01021 Note:
    01022
    01023     The console lock must be held when calling this routine.
    01024
    01025 --*/
    01026
    01027 {
    01028     ULONG EventsRead;
    01029     NTSTATUS Status;
    01030     BOOL ResetWaitEvent;
    01031
    01032     if (InputInformation->In == InputInformation->Out)  {
    01033         if (!WaitForData) {
    01034             *nLength = 0;
    01035             return STATUS_SUCCESS;
    01036         }
    01037         LockReadCount(HandleData);
    01038         HandleData->InputReadData->ReadCount += 1;
    01039         UnlockReadCount(HandleData);
    01040         Status = WaitForMoreToRead(InputInformation,
    01041                                    Message,
    01042                                    WaitRoutine,
    01043                                    WaitParameter,
    01044                                    WaitParameterLength,
    01045                                    WaitBlockExists
    01046                                   );
    01047
    01048         if (!NT_SUCCESS(Status)) {
    01049             if (Status != CONSOLE_STATUS_WAIT) {
    01050                 /*
    01051                  * WaitForMoreToRead failed, restore ReadCount and bale out
    01052                  */
    01053                 LockReadCount(HandleData);
    01054                 HandleData->InputReadData->ReadCount -= 1;
    01055                 UnlockReadCount(HandleData);
    01056             }
    01057             *nLength = 0;
    01058             return Status;
    01059         }
    01060
    01061         //
    01062         // we will only get to this point if we were called by GetInput.
    01063         //
    01064         ASSERT(FALSE); // I say we never get here !  IANJA
    01065
    01066         LockConsole(Console);
    01067     }
    01068
    01069     //
    01070     // read from buffer
    01071     //
    01072
    01073     Status = ReadBuffer(InputInformation,
    01074                         lpBuffer,
    01075                         *nLength,
    01076                         &EventsRead,
    01077                         Peek,
    01078                         StreamRead,
    01079                         &ResetWaitEvent
    01080 #if defined(FE_SB)
    01081                         ,
    01082                         Unicode
    01083 #endif
    01084                        );
    01085     if (ResetWaitEvent) {
    01086         NtClearEvent(InputInformation->InputWaitEvent);
    01087     }
    01088
    01089     *nLength = EventsRead;
    01090     return Status;
    01091 }

NTSTATUS ReinitializeInputBuffer | ( | OUT PINPUT_INFORMATION | InputBufferInformation | ) |

Definition at line 184 of file ntcon/server/input.c.

References NtClearEvent().

Referenced by CloseInputHandle().

    00190                    :
    00191
    00192     This routine resets the input buffer information fields to their
    00193     initial values.
    00194
    00195 Arguments:
    00196
    00197     InputBufferInformation - Pointer to input buffer information structure.
    00198
    00199 Return Value:
    00200
    00201 Note:
    00202
    00203     The console lock must be held when calling this routine.
    00204
    00205 --*/
    00206
    00207 {
    00208     NtClearEvent(InputBufferInformation->InputWaitEvent);
    00209     InputBufferInformation->ShareAccess.OpenCount = 0;
    00210     InputBufferInformation->ShareAccess.Readers = 0;
    00211     InputBufferInformation->ShareAccess.Writers = 0;
    00212     InputBufferInformation->ShareAccess.SharedRead = 0;
    00213     InputBufferInformation->ShareAccess.SharedWrite = 0;
    00214     InputBufferInformation->InputMode = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT  | ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT;
    00215     InputBufferInformation->In = (ULONG_PTR) InputBufferInformation->InputBuffer;
    00216     InputBufferInformation->Out = (ULONG_PTR) InputBufferInformation->InputBuffer;
    00217     return STATUS_SUCCESS;
    00218 }

VOID RetrieveKeyInfo | ( | IN HWND | hWnd,
|  | OUT PWORD | pwVirtualKeyCode,
|  | OUT PWORD | pwVirtualScanCode,
|  | IN BOOL | FreeKeyInfo
| ) |

Definition at line 1609 of file ntcon/server/input.c.

References CONSOLE_FREE_KEY_INFO, CONSOLE_MAX_KEY_INFO, ConsoleKeyInfo, hWnd, _CONSOLE_KEY_INFO::hWnd, MapVirtualKey(), _CONSOLE_KEY_INFO::wVirtualKeyCode, and _CONSOLE_KEY_INFO::wVirtualScanCode.

Referenced by HandleKeyEvent().

    01615 {
    01616     int i;
    01617
    01618     for (i=0;i<CONSOLE_MAX_KEY_INFO;i++) {
    01619         if (ConsoleKeyInfo[i].hWnd == hWnd) {
    01620             break;
    01621         }
    01622     }
    01623     if (i!=CONSOLE_MAX_KEY_INFO) {
    01624         *pwVirtualKeyCode = ConsoleKeyInfo[i].wVirtualKeyCode;
    01625         *pwVirtualScanCode = ConsoleKeyInfo[i].wVirtualScanCode;
    01626         if (FreeKeyInfo)
    01627             ConsoleKeyInfo[i].hWnd = CONSOLE_FREE_KEY_INFO;
    01628     } else {
    01629         *pwVirtualKeyCode = (WORD)MapVirtualKey(*pwVirtualScanCode, 3);
    01630     }
    01631 }

NTSTATUS SetInputBufferSize | ( | IN PINPUT_INFORMATION | InputInformation,
|  | IN ULONG | Size
| ) |

Definition at line 516 of file ntcon/server/input.c.

References ASSERT, BOOL, BUFFER_TAG, BufferSize, ConsoleHeapAlloc, ConsoleHeapFree, FALSE, MAKE_TAG, NT_SUCCESS, NTSTATUS(), NULL, ReadBuffer(), Size, Status, and TRUE.

Referenced by WriteBuffer().

    00523                    :
    00524
    00525     This routine resizes the input buffer.
    00526
    00527 Arguments:
    00528
    00529     InputInformation - Pointer to input buffer information structure.
    00530
    00531     Size - New size in number of events.
    00532
    00533 Return Value:
    00534
    00535 Note:
    00536
    00537     The console lock must be held when calling this routine.
    00538
    00539 --*/
    00540
    00541 {
    00542     ULONG NumberOfEventsRead;
    00543     NTSTATUS Status;
    00544     PINPUT_RECORD InputBuffer;
    00545     ULONG BufferSize;
    00546     BOOL Dummy;
    00547
    00548 #if DBG
    00549     ULONG_PTR NumberOfEvents;
    00550     if (InputInformation->In < InputInformation->Out) {
    00551         NumberOfEvents = InputInformation->Last - InputInformation->Out;
    00552         NumberOfEvents += InputInformation->In - InputInformation->First;
    00553     }
    00554     else {
    00555         NumberOfEvents = InputInformation->In - InputInformation->Out;
    00556     }
    00557     NumberOfEvents /= sizeof(INPUT_RECORD);
    00558 #endif
    00559     ASSERT( Size > InputInformation->InputBufferSize );
    00560
    00561     //
    00562     // allocate memory for new input buffer
    00563     //
    00564
    00565     BufferSize =  sizeof(INPUT_RECORD) * (Size+1);
    00566     InputBuffer = (PINPUT_RECORD)ConsoleHeapAlloc(MAKE_TAG( BUFFER_TAG ),BufferSize);
    00567     if (InputBuffer == NULL) {
    00568         return STATUS_NO_MEMORY;
    00569     }
    00570
    00571     //
    00572     // copy old input buffer.
    00573     // let the ReadBuffer do any compaction work.
    00574     //
    00575
    00576     Status = ReadBuffer(InputInformation,
    00577                         InputBuffer,
    00578                         Size,
    00579                         &NumberOfEventsRead,
    00580                         TRUE,
    00581                         FALSE,
    00582                         &Dummy
    00583 #if defined(FE_SB)
    00584                         ,
    00585                         TRUE
    00586 #endif
    00587                        );
    00588
    00589     if (!NT_SUCCESS(Status)) {
    00590         ConsoleHeapFree(InputBuffer);
    00591         return Status;
    00592     }
    00593     InputInformation->Out = (ULONG_PTR)InputBuffer;
    00594     InputInformation->In = (ULONG_PTR)InputBuffer + sizeof(INPUT_RECORD) * NumberOfEventsRead;
    00595
    00596     //
    00597     // adjust pointers
    00598     //
    00599
    00600     InputInformation->First = (ULONG_PTR) InputBuffer;
    00601     InputInformation->Last = (ULONG_PTR) InputBuffer + BufferSize;
    00602
    00603     //
    00604     // free old input buffer
    00605     //
    00606
    00607     ConsoleHeapFree(InputInformation->InputBuffer);
    00608     InputInformation->InputBufferSize = Size;
    00609     InputInformation->AllocatedBufferSize = BufferSize;
    00610     InputInformation->InputBuffer = InputBuffer;
    00611     return Status;
    00612 }

VOID StoreKeyInfo | ( | IN PMSG | msg | ) |

Definition at line 1587 of file ntcon/server/input.c.

References BYTE, CONSOLE_FREE_KEY_INFO, CONSOLE_MAX_KEY_INFO, ConsoleKeyInfo, _CONSOLE_KEY_INFO::hWnd, msg, _CONSOLE_KEY_INFO::wVirtualKeyCode, and _CONSOLE_KEY_INFO::wVirtualScanCode.

Referenced by ConsoleInputThread(), and DialogHookProc().

    01590 {
    01591     int i;
    01592
    01593     for (i=0;i<CONSOLE_MAX_KEY_INFO;i++) {
    01594         if (ConsoleKeyInfo[i].hWnd == CONSOLE_FREE_KEY_INFO ||
    01595             ConsoleKeyInfo[i].hWnd == msg->hwnd) {
    01596             break;
    01597         }
    01598     }
    01599     if (i!=CONSOLE_MAX_KEY_INFO) {
    01600         ConsoleKeyInfo[i].hWnd = msg->hwnd;
    01601         ConsoleKeyInfo[i].wVirtualKeyCode = LOWORD(msg->wParam);
    01602         ConsoleKeyInfo[i].wVirtualScanCode = (BYTE)(HIWORD(msg->lParam));
    01603     } else {
    01604         KdPrint(("CONSRV: ConsoleKeyInfo buffer is full\n"));
    01605     }
    01606 }

VOID TerminateRead | ( | IN PCONSOLE_INFORMATION | Console,
|  | IN PINPUT_INFORMATION | InputInfo,
|  | IN DWORD | Flag
| ) |

Definition at line 2235 of file ntcon/server/input.c.

References ASSERT, NULL, and TRUE.

Referenced by HandleKeyEvent().

    02243                    :
    02244
    02245     This routine wakes up any readers waiting for data when a ctrl-c
    02246     or ctrl-break is input.
    02247
    02248 Arguments:
    02249
    02250     InputInfo - pointer to input buffer
    02251
    02252     Flag - flag indicating whether ctrl-break or ctrl-c was input
    02253
    02254 --*/
    02255
    02256 {
    02257     BOOLEAN WaitSatisfied;
    02258     WaitSatisfied = CsrNotifyWait(&InputInfo->ReadWaitQueue,
    02259                   TRUE,
    02260                   NULL,
    02261                   (PVOID)Flag
    02262                  );
    02263     if (WaitSatisfied) {
    02264         // #334370 under stress, WaitQueue may already hold the satisfied waits
    02265         ASSERT ((Console->WaitQueue == NULL) ||
    02266                 (Console->WaitQueue == &InputInfo->ReadWaitQueue));
    02267         Console->WaitQueue = &InputInfo->ReadWaitQueue;
    02268     }
    02269 }

VOID UnlockConsole | ( | IN PCONSOLE_INFORMATION | Console | ) |

Definition at line 4103 of file ntcon/server/input.c.

References ASSERT, CONSOLE_CLIENTPROCESSID, CONSOLE_CTRL_LOGOFF_FLAG, CONSOLE_CTRL_SHUTDOWN_FLAG, CONSOLE_FORCE_SHUTDOWN_FLAG, CONSOLE_SHUTDOWN_SUCCEEDED, CONSOLE_SHUTDOWN_SYSTEM, CONSOLE_SHUTTING_DOWN, ConsoleVDMCriticalSection, ConsoleVDMOnSwitching, _CONSOLE_INFORMATION::CtrlFlags, dwFlags, DWORD, _CONSOLE_INFORMATION::Flags, _CONSOLE_INFORMATION::LimitingProcessId, NT_SUCCESS, NtFreeVirtualMemory(), NtQueryVirtualMemory(), NTSTATUS(), NtTerminateThread(), NULL, ProcessCtrlEvents(), RevalidateConsole(), RtlRaiseStatus(), SHUTDOWN_CANCEL, SHUTDOWN_KNOWN_PROCESS, ShutdownConsole(), Status, UserExitWorkerThread(), ValidateConsole(), _CONSOLE_INFORMATION::VDMProcessId, VOID(), and Zero.

Referenced by ApiPreamble(), ConsoleAddProcessRoutine(), ConsoleClientConnectRoutine(), ConsoleClientShutdown(), ConsoleSetActiveWindow(), ConsoleWindowProc(), FreeCon(), GetThreadConsoleDesktop(), ProcessCreateConsoleWindow(), PropertiesDlgShow(), RemoveConsole(), RevalidateConsole(), SrvAddConsoleAlias(), SrvAllocConsole(), SrvCloseHandle(), SrvConsoleMenuControl(), SrvConsoleNotifyLastClose(), SrvCreateConsoleScreenBuffer(), SrvDuplicateHandle(), SrvExpungeConsoleCommandHistory(), SrvFillConsoleOutput(), SrvFlushConsoleInputBuffer(), SrvGenerateConsoleCtrlEvent(), SrvGetConsoleAlias(), SrvGetConsoleAliases(), SrvGetConsoleAliasesLength(), SrvGetConsoleAliasExes(), SrvGetConsoleAliasExesLength(), SrvGetConsoleCommandHistory(), SrvGetConsoleCommandHistoryLength(), SrvGetConsoleCP(), SrvGetConsoleCurrentFont(), SrvGetConsoleCursorInfo(), SrvGetConsoleDisplayMode(), SrvGetConsoleFontInfo(), SrvGetConsoleFontSize(), SrvGetConsoleHardwareState(), SrvGetConsoleInput(), SrvGetConsoleKeyboardLayoutName(), SrvGetConsoleLangId(), SrvGetConsoleMode(), SrvGetConsoleMouseInfo(), SrvGetConsoleNumberOfFonts(), SrvGetConsoleNumberOfInputEvents(), SrvGetConsoleScreenBufferInfo(), SrvGetConsoleTitle(), SrvGetConsoleWindow(), SrvGetHandleInformation(), SrvGetLargestConsoleWindowSize(), SrvInvalidateBitMapRect(), SrvOpenConsole(), SrvReadConsole(), SrvReadConsoleOutput(), SrvReadConsoleOutputString(), SrvRegisterConsoleVDM(), SrvScrollConsoleScreenBuffer(), SrvSetConsoleActiveScreenBuffer(), SrvSetConsoleCommandHistoryMode(), SrvSetConsoleCP(), SrvSetConsoleCursor(), SrvSetConsoleCursorInfo(), SrvSetConsoleCursorPosition(), SrvSetConsoleDisplayMode(), SrvSetConsoleFont(), SrvSetConsoleHardwareState(), SrvSetConsoleIcon(), SrvSetConsoleKeyShortcuts(), SrvSetConsoleMenuClose(), SrvSetConsoleMode(), SrvSetConsoleNumberOfCommands(), SrvSetConsolePalette(), SrvSetConsoleScreenBufferSize(), SrvSetConsoleTextAttribute(), SrvSetConsoleTitle(), SrvSetConsoleWindowInfo(), SrvSetHandleInformation(), SrvShowConsoleCursor(), SrvVDMConsoleOperation(), SrvVerifyConsoleIoHandle(), SrvWriteConsole(), SrvWriteConsoleInput(), SrvWriteConsoleOutput(), and SrvWriteConsoleOutputString().

    04106 {
    04107     LIST_ENTRY WaitQueue;
    04108
    04109     //
    04110     // Make sure the console pointer is still valid
    04111     //
    04112     ASSERT(NT_SUCCESS(ValidateConsole(Console)));
    04113
    04114 #ifdef i386
    04115     //
    04116     // do nothing if we are in screen switching(handshaking with ntvdm)
    04117     // we don't check anything else because we are in a safe state here.
    04118     //
    04119     if (ConsoleVDMOnSwitching == Console &&
    04120         ConsoleVDMOnSwitching->VDMProcessId == CONSOLE_CLIENTPROCESSID()) {
    04121         KdPrint(("    UnlockConsole - Thread %lx is leaving VDM CritSec\n", GetCurrentThreadId()));
    04122         RtlLeaveCriticalSection(&ConsoleVDMCriticalSection);
    04123         return;
    04124     }
    04125 #endif
    04126
    04127     //
    04128     // if we're about to release the console lock, see if there
    04129     // are any satisfied wait blocks that need to be dereferenced.
    04130     // this code avoids a deadlock between grabbing the console
    04131     // lock and then grabbing the process structure lock.
    04132     //
    04133 #if defined(_X86_)
    04134     if (Console->ConsoleLock.RecursionCount == 1) {
    04135 #endif
    04136 #if defined(_MIPS_) || defined(_ALPHA_) || defined(_PPC_) || defined(_IA64_)
    04137     if (Console->ConsoleLock.RecursionCount == 0) {
    04138 #endif
    04139         InitializeListHead(&WaitQueue);
    04140         if (Console->WaitQueue) {
    04141             CsrMoveSatisfiedWait(&WaitQueue, Console->WaitQueue);
    04142             Console->WaitQueue = NULL;
    04143         }
    04144         ProcessCtrlEvents(Console);
    04145
    04146         /*
    04147          * Can't call CsrDereferenceWait with the console locked or we could deadlock.
    04148          */
    04149         if (!IsListEmpty(&WaitQueue)) {
    04150             CsrDereferenceWait(&WaitQueue);
    04151         }
    04152     } else {

BOOL UnqueueThreadMessage | ( | DWORD | dwThreadId,
|  | UINT * | pMessage,
|  | WPARAM * | pwParam,
|  | LPARAM * | plParam
| ) |

Definition at line 1906 of file ntcon/server/input.c.

References ASSERT, BOOL, CONSOLE_THREAD_MSG, ConsoleHeapFree, _CONSOLE_THREAD_MSG::dwThreadId, FALSE, gInputThreadMsg, gInputThreadMsgLock, and TRUE.

Referenced by CleanupInputThreadMessages(), ConsoleInputThread(), and DialogHookProc().

    01911 {
    01912     BOOL fResult = FALSE;       // if message is found, set this to TRUE
    01913     PLIST_ENTRY pEntry;
    01914
    01915     ASSERT(dwThreadId);
    01916
    01917     RtlEnterCriticalSection(&gInputThreadMsgLock);
    01918
    01919     //
    01920     // Search for dwThreadId message from the tail of the queue.
    01921     //
    01922     pEntry = gInputThreadMsg.Blink;
    01923
    01924     while (pEntry != &gInputThreadMsg) {
    01925         PCONSOLE_THREAD_MSG pConMsg = CONTAINING_RECORD(pEntry, CONSOLE_THREAD_MSG, ListLink);
    01926
    01927         if (pConMsg->dwThreadId == dwThreadId) {
    01928             *pMessage = pConMsg->Message;
    01929             *pwParam = pConMsg->wParam;
    01930             *plParam = pConMsg->lParam;
    01931
    01932             RemoveEntryList(pEntry);
    01933             ConsoleHeapFree(pConMsg);
    01934             fResult = TRUE;
    01935             break;
    01936         }
    01937         pEntry = pEntry->Blink;
    01938     }
    01939
    01940     RtlLeaveCriticalSection(&gInputThreadMsgLock);
    01941
    01942     return fResult;
    01943 }

VOID UserExitWorkerThread | ( | VOID |  | ) |

NTSTATUS WaitForMoreToRead | ( | IN PINPUT_INFORMATION | InputInformation,
|  | IN PCSR_API_MSG Message | OPTIONAL,
|  | IN CSR_WAIT_ROUTINE WaitRoutine | OPTIONAL,
|  | IN PVOID WaitParameter | OPTIONAL,
|  | IN ULONG WaitParameterLength | OPTIONAL,
|  | IN BOOLEAN WaitBlockExists | OPTIONAL
| ) |

Definition at line 248 of file ntcon/server/input.c.

References CONSOLE_STATUS_WAIT, ConsoleHeapAlloc, ConsoleHeapFree, MAKE_TAG, NULL, and WAIT_TAG.

Referenced by CookedRead(), and ReadInputBuffer().

    00259                    :
    00260
    00261     This routine waits for a writer to add data to the buffer.
    00262
    00263 Arguments:
    00264
    00265     InputInformation - buffer to wait for
    00266
    00267     Console - Pointer to console buffer information.
    00268
    00269     Message - if called from dll (not InputThread), points to api
    00270     message.  this parameter is used for wait block processing.
    00271
    00272     WaitRoutine - Routine to call when wait is woken up.
    00273
    00274     WaitParameter - Parameter to pass to wait routine.
    00275
    00276     WaitParameterLength - Length of wait parameter.
    00277
    00278     WaitBlockExists - TRUE if wait block has already been created.
    00279
    00280 Return Value:
    00281
    00282     STATUS_WAIT - call was from client and wait block has been created.
    00283
    00284     STATUS_SUCCESS - call was from server and wait has been satisfied.
    00285
    00286 --*/
    00287
    00288 {
    00289     PVOID WaitParameterBuffer;
    00290
    00291     if (!WaitBlockExists) {
    00292         WaitParameterBuffer = (PVOID)ConsoleHeapAlloc(MAKE_TAG( WAIT_TAG ),WaitParameterLength);
    00293         if (WaitParameterBuffer == NULL) {
    00294             return STATUS_NO_MEMORY;
    00295         }
    00296         RtlCopyMemory(WaitParameterBuffer,WaitParameter,WaitParameterLength);
    00297 #if defined(FE_SB)
    00298         if (WaitParameterLength == sizeof(COOKED_READ_DATA) &&
    00299             InputInformation->Console->lpCookedReadData == WaitParameter) {
    00300             InputInformation->Console->lpCookedReadData = WaitParameterBuffer;
    00301         }
    00302 #endif
    00303         if (!CsrCreateWait(&InputInformation->ReadWaitQueue,
    00304                           WaitRoutine,
    00305                           CSR_SERVER_QUERYCLIENTTHREAD(),
    00306                           Message,
    00307                           WaitParameterBuffer,
    00308                           NULL
    00309                          )) {
    00310             ConsoleHeapFree(WaitParameterBuffer);
    00311 #if defined(FE_SB)
    00312             InputInformation->Console->lpCookedReadData = NULL;
    00313 #endif
    00314             return STATUS_NO_MEMORY;
    00315         }
    00316     }
    00317     return CONSOLE_STATUS_WAIT;
    00318 }

VOID WakeUpReadersWaitingForData | ( | IN PCONSOLE_INFORMATION | Console,
|  | PINPUT_INFORMATION | InputInformation
| ) |

Definition at line 322 of file ntcon/server/input.c.

References ASSERT, FALSE, NULL, and _INPUT_INFORMATION::ReadWaitQueue.

Referenced by PrependInputBuffer(), and WriteInputBuffer().

    00329                    :
    00330
    00331     This routine wakes up readers waiting for data to read.
    00332
    00333 Arguments:
    00334
    00335     InputInformation - buffer to alert readers for
    00336
    00337 Return Value:
    00338
    00339     TRUE - The operation was successful
    00340
    00341     FALSE/NULL - The operation failed.
    00342
    00343 --*/
    00344
    00345 {
    00346     BOOLEAN WaitSatisfied;
    00347     WaitSatisfied = CsrNotifyWait(&InputInformation->ReadWaitQueue,
    00348                   FALSE,
    00349                   NULL,
    00350                   NULL
    00351                  );
    00352     if (WaitSatisfied) {
    00353         // #334370 under stress, WaitQueue may already hold the satisfied waits
    00354         ASSERT ((Console->WaitQueue == NULL) ||
    00355                 (Console->WaitQueue == &InputInformation->ReadWaitQueue));
    00356         Console->WaitQueue = &InputInformation->ReadWaitQueue;
    00357     }
    00358 }

NTSTATUS WriteBuffer | ( | OUT PINPUT_INFORMATION | InputInformation,
|  | IN PVOID | Buffer,
|  | IN ULONG | Length,
|  | OUT PULONG | EventsWritten,
|  | OUT PBOOL | SetWaitEvent
| ) |

Definition at line 1095 of file ntcon/server/input.c.

References ASSERT, Buffer, _CONSOLE_INFORMATION::CP, FALSE, _CONSOLE_INFORMATION::hDC, INPUT_BUFFER_SIZE_INCREMENT, NT_SUCCESS, NTSTATUS(), PBYTE, SetInputBufferSize(), Status, and TRUE.

Referenced by PrependInputBuffer(), and WriteInputBuffer().

    01105                    :
    01106
    01107     This routine writes to a buffer.  It does the actual circular buffer
    01108     manipulation.
    01109
    01110 Arguments:
    01111
    01112     InputInformation - buffer to write to
    01113
    01114     Buffer - buffer to write from
    01115
    01116     Length - length of buffer in events
    01117
    01118     BytesRead - where to store number of bytes written.
    01119
    01120     SetWaitEvent - on exit, TRUE if buffer became non-empty.
    01121
    01122 Return Value:
    01123
    01124     ERROR_BROKEN_PIPE - no more readers.
    01125
    01126 Note:
    01127
    01128     The console lock must be held when calling this routine.
    01129
    01130 --*/
    01131
    01132 {
    01133     NTSTATUS Status;
    01134     ULONG TransferLength;
    01135     ULONG BufferLengthInBytes;
    01136 #if defined(FE_SB)
    01137     PCONSOLE_INFORMATION Console = InputInformation->Console;
    01138 #endif
    01139
    01140     *SetWaitEvent = FALSE;
    01141
    01142     //
    01143     // windows sends a mouse_move message each time a window is updated.
    01144     // coalesce these.
    01145     //
    01146
    01147     if (Length == 1 && InputInformation->Out != InputInformation->In) {
    01148         PINPUT_RECORD InputEvent=Buffer;
    01149
    01150         if (InputEvent->EventType == MOUSE_EVENT &&
    01151             InputEvent->Event.MouseEvent.dwEventFlags == MOUSE_MOVED) {
    01152             PINPUT_RECORD LastInputEvent;
    01153
    01154             if (InputInformation->In == InputInformation->First) {
    01155                 LastInputEvent = (PINPUT_RECORD) (InputInformation->Last - sizeof(INPUT_RECORD));
    01156             }
    01157             else {
    01158                 LastInputEvent = (PINPUT_RECORD) (InputInformation->In - sizeof(INPUT_RECORD));
    01159             }
    01160             if (LastInputEvent->EventType == MOUSE_EVENT &&
    01161                 LastInputEvent->Event.MouseEvent.dwEventFlags == MOUSE_MOVED) {
    01162                 LastInputEvent->Event.MouseEvent.dwMousePosition.X =
    01163                     InputEvent->Event.MouseEvent.dwMousePosition.X;
    01164                 LastInputEvent->Event.MouseEvent.dwMousePosition.Y =
    01165                     InputEvent->Event.MouseEvent.dwMousePosition.Y;
    01166                 *EventsWritten = 1;
    01167                 return STATUS_SUCCESS;
    01168             }
    01169         }
    01170         else if (InputEvent->EventType == KEY_EVENT &&
    01171                  InputEvent->Event.KeyEvent.bKeyDown) {
    01172             PINPUT_RECORD LastInputEvent;
    01173             if (InputInformation->In == InputInformation->First) {
    01174                 LastInputEvent = (PINPUT_RECORD) (InputInformation->Last - sizeof(INPUT_RECORD));
    01175             }
    01176             else {
    01177                 LastInputEvent = (PINPUT_RECORD) (InputInformation->In - sizeof(INPUT_RECORD));
    01178             }
    01179 #if defined(FE_SB)
    01180             if (IsConsoleFullWidth(Console->hDC,
    01181                                    Console->CP,InputEvent->Event.KeyEvent.uChar.UnicodeChar)) {
    01182                 ;
    01183             }
    01184             else
    01185             if (InputEvent->Event.KeyEvent.dwControlKeyState & NLS_IME_CONVERSION) {
    01186                 if (LastInputEvent->EventType == KEY_EVENT &&
    01187                     LastInputEvent->Event.KeyEvent.bKeyDown &&
    01188                     (LastInputEvent->Event.KeyEvent.uChar.UnicodeChar ==
    01189                         InputEvent->Event.KeyEvent.uChar.UnicodeChar) &&
    01190                     (LastInputEvent->Event.KeyEvent.dwControlKeyState ==
    01191                         InputEvent->Event.KeyEvent.dwControlKeyState) ) {
    01192                     LastInputEvent->Event.KeyEvent.wRepeatCount +=
    01193                         InputEvent->Event.KeyEvent.wRepeatCount;
    01194                     *EventsWritten = 1;
    01195                     return STATUS_SUCCESS;
    01196                 }
    01197             }
    01198             else
    01199 #endif
    01200             if (LastInputEvent->EventType == KEY_EVENT &&
    01201                 LastInputEvent->Event.KeyEvent.bKeyDown &&
    01202                 (LastInputEvent->Event.KeyEvent.wVirtualScanCode == // scancode same
    01203                     InputEvent->Event.KeyEvent.wVirtualScanCode) &&
    01204                 (LastInputEvent->Event.KeyEvent.uChar.UnicodeChar == // character same
    01205                     InputEvent->Event.KeyEvent.uChar.UnicodeChar) &&
    01206                 (LastInputEvent->Event.KeyEvent.dwControlKeyState == // ctrl/alt/shift state same
    01207                     InputEvent->Event.KeyEvent.dwControlKeyState) ) {
    01208                 LastInputEvent->Event.KeyEvent.wRepeatCount +=
    01209                     InputEvent->Event.KeyEvent.wRepeatCount;
    01210                 *EventsWritten = 1;
    01211                 return STATUS_SUCCESS;
    01212             }
    01213         }
    01214     }
    01215
    01216     BufferLengthInBytes = Length*sizeof(INPUT_RECORD);
    01217     *EventsWritten = 0;
    01218     while (*EventsWritten < Length) {
    01219
    01220         //
    01221         //
    01222         // if out > in, buffer looks like this:
    01223         //
    01224         //             in     out
    01225         //        ______ _____________
    01226         //       |      |      |      |
    01227         //       | data | free | data |
    01228         //       |______|______|______|
    01229         //
    01230         // we can write from in to out-1
    01231         //
    01232
    01233         if (InputInformation->Out > InputInformation->In)       {
    01234             TransferLength = BufferLengthInBytes;
    01235             if  ((InputInformation->Out - InputInformation->In - sizeof(INPUT_RECORD))
    01236                    < BufferLengthInBytes) {
    01237                 Status = SetInputBufferSize(InputInformation,
    01238                                             InputInformation->InputBufferSize+Length+INPUT_BUFFER_SIZE_INCREMENT);
    01239                 if (!NT_SUCCESS(Status)) {
    01240                     KdPrint(("CONSRV: Couldn't grow input buffer, Status == %lX\n",Status));
    01241                     TransferLength = (ULONG)(InputInformation->Out - InputInformation->In - sizeof(INPUT_RECORD));
    01242                     if (TransferLength == 0) {
    01243                         return Status;
    01244                     }
    01245                 } else {
    01246                     goto OutPath;   // after resizing, in > out
    01247                 }
    01248             }
    01249             RtlMoveMemory((PBYTE)InputInformation->In,
    01250                           (PBYTE)Buffer,
    01251                           TransferLength
    01252                          );
    01253             Buffer = (PVOID) (((PBYTE) Buffer)+TransferLength);
    01254             *EventsWritten += TransferLength/sizeof(INPUT_RECORD);
    01255             BufferLengthInBytes -= TransferLength;
    01256             InputInformation->In += TransferLength;
    01257         }
    01258
    01259         //
    01260         // if in >= out, buffer looks like this:
    01261         //
    01262         //             out     in
    01263         //        ______ _____________
    01264         //       |      |      |      |
    01265         //       | free | data | free |
    01266         //       |______|______|______|
    01267         //
    01268         // we write from the in pointer to the end of the buffer then from the
    01269         // beginning of the buffer, until we hit the out pointer or enough bytes
    01270         // are written.
    01271         //
    01272
    01273         else {
    01274             if (InputInformation->Out == InputInformation->In) {
    01275                 *SetWaitEvent = TRUE;
    01276             }
    01277 OutPath:
    01278             if  ((InputInformation->Last - InputInformation->In) > BufferLengthInBytes) {
    01279                 TransferLength = BufferLengthInBytes;
    01280             }
    01281             else {
    01282                 if (InputInformation->First == InputInformation->Out &&
    01283                     InputInformation->In == (InputInformation->Last-sizeof(INPUT_RECORD))) {
    01284                     TransferLength = BufferLengthInBytes;
    01285                     Status = SetInputBufferSize(InputInformation,
    01286                                                 InputInformation->InputBufferSize+Length+INPUT_BUFFER_SIZE_INCREMENT);
    01287                     if (!NT_SUCCESS(Status)) {
    01288                         KdPrint(("CONSRV: Couldn't grow input buffer, Status == %lX\n",Status));
    01289                         return Status;
    01290                     }
    01291                 }
    01292                 else {
    01293                     TransferLength = (ULONG)(InputInformation->Last - InputInformation->In);
    01294                     if (InputInformation->First == InputInformation->Out) {
    01295                         TransferLength -= sizeof(INPUT_RECORD);
    01296                     }
    01297                 }
    01298             }
    01299             RtlMoveMemory((PBYTE)InputInformation->In,
    01300                           (PBYTE)Buffer,
    01301                           TransferLength
    01302                          );
    01303             Buffer = (PVOID) (((PBYTE) Buffer)+TransferLength);
    01304             *EventsWritten += TransferLength/sizeof(INPUT_RECORD);
    01305             BufferLengthInBytes -= TransferLength;
    01306             InputInformation->In += TransferLength;
    01307             if (InputInformation->In == InputInformation->Last) {
    01308                 InputInformation->In = InputInformation->First;
    01309             }
    01310         }
    01311         if (TransferLength == 0) {
    01312             ASSERT (FALSE);
    01313         }
    01314     }
    01315     return STATUS_SUCCESS;
    01316 }

DWORD WriteInputBuffer | ( | IN PCONSOLE_INFORMATION | Console,
|  | IN PINPUT_INFORMATION | InputInformation,
|  | IN PINPUT_RECORD | lpBuffer,
|  | IN DWORD | nLength
| ) |

Definition at line 1522 of file ntcon/server/input.c.

References BOOL, NtSetEvent(), NULL, PreprocessInput(), WakeUpReadersWaitingForData(), and WriteBuffer().

Referenced by DoStringPaste(), HandleFocusEvent(), HandleKeyEvent(), HandleMenuEvent(), HandleMouseEvent(), ScreenBufferSizeChange(), and SrvWriteConsoleInput().

    01531                    :
    01532
    01533     This routine writes to the input buffer.
    01534
    01535 Arguments:
    01536
    01537     InputInformation - Pointer to input buffer information structure.
    01538
    01539     lpBuffer - Buffer to write from.
    01540
    01541     nLength - On input, number of events to write.  On output, number of
    01542     events written.
    01543
    01544 Return Value:
    01545
    01546 Note:
    01547
    01548     The console lock must be held when calling this routine.
    01549
    01550 --*/
    01551
    01552 {
    01553     ULONG EventsWritten;
    01554     BOOL SetWaitEvent;
    01555
    01556     nLength = PreprocessInput(Console, lpBuffer, nLength);
    01557     if (nLength == 0) {
    01558         return 0;
    01559     }
    01560
    01561     //
    01562     // write to buffer
    01563     //
    01564
    01565     WriteBuffer(InputInformation,
    01566                 lpBuffer,
    01567                 nLength,
    01568                 &EventsWritten,
    01569                 &SetWaitEvent
    01570                 );
    01571
    01572     if (SetWaitEvent) {
    01573         NtSetEvent(InputInformation->InputWaitEvent,NULL);
    01574     }
    01575
    01576     //
    01577     // alert any writers waiting for space
    01578     //
    01579
    01580     WakeUpReadersWaitingForData(Console,InputInformation);
    01581
    01582
    01583     return EventsWritten;
    01584 }

## Variable Documentation

CONSOLE_KEY_INFO ConsoleKeyInfo[CONSOLE_MAX_KEY_INFO]

| Definition at line 80 of file ntcon/server/input.c. Referenced by ClearKeyInfo(), ConsoleInputThread(), RetrieveKeyInfo(), and StoreKeyInfo().

LPTHREAD_START_ROUTINE CtrlRoutine

| Definition at line 56 of file ntcon/server/input.c.

int DialogBoxCount

| Definition at line 54 of file ntcon/server/input.c. Referenced by CreateCtrlThread(), HandleKeyEvent(), and ProcessCreateConsoleWindow().

LIST_ENTRY gInputThreadMsg

| Definition at line 1825 of file ntcon/server/input.c. Referenced by InitializeThreadMessages(), QueueThreadMessage(), and UnqueueThreadMessage().

CRITICAL_SECTION gInputThreadMsgLock

| Definition at line 1826 of file ntcon/server/input.c. Referenced by ConServerDllInitialization(), InitializeThreadMessages(), QueueThreadMessage(), and UnqueueThreadMessage().

DWORD InputThreadTlsIndex

| Definition at line 58 of file ntcon/server/input.c. Referenced by ConServerDllInitialization(), ConsoleInputThread(), DialogHookProc(), and ProcessCreateConsoleWindow().

UINT ProgmanHandleMessage

| Definition at line 52 of file ntcon/server/input.c. Referenced by ConsoleInputThread(), ConsoleWindowProc(), and CreateWindowsWindow().