ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

coninput.c
Go to the documentation of this file.
00001 /*
00002  * reactos/subsys/csrss/win32csr/conio.c
00003  *
00004  * Console I/O functions
00005  *
00006  * ReactOS Operating System
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #define NDEBUG
00012 #include "w32csr.h"
00013 #include <debug.h>
00014 
00015 /* GLOBALS *******************************************************************/
00016 
00017 #define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
00018     WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
00019 
00020 #define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
00021     MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1)
00022 
00023 /* FUNCTIONS *****************************************************************/
00024 
00025 CSR_API(CsrReadConsole)
00026 {
00027     PLIST_ENTRY CurrentEntry;
00028     ConsoleInput *Input;
00029     PCHAR Buffer;
00030     PWCHAR UnicodeBuffer;
00031     ULONG i = 0;
00032     ULONG nNumberOfCharsToRead, CharSize;
00033     PCSRSS_CONSOLE Console;
00034     NTSTATUS Status;
00035 
00036     DPRINT("CsrReadConsole\n");
00037 
00038     CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
00039 
00040     nNumberOfCharsToRead = Request->Data.ReadConsoleRequest.NrCharactersToRead;
00041 
00042     Buffer = (PCHAR)Request->Data.ReadConsoleRequest.Buffer;
00043     UnicodeBuffer = (PWCHAR)Buffer;
00044     if (!Win32CsrValidateBuffer(ProcessData, Buffer, nNumberOfCharsToRead, CharSize))
00045         return STATUS_ACCESS_VIOLATION;
00046 
00047     if (Request->Data.ReadConsoleRequest.NrCharactersRead * sizeof(WCHAR) > nNumberOfCharsToRead * CharSize)
00048         return STATUS_INVALID_PARAMETER;
00049 
00050     Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
00051                               &Console, GENERIC_READ);
00052     if (! NT_SUCCESS(Status))
00053     {
00054         return Status;
00055     }
00056     Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent;
00057 
00058     Status = STATUS_PENDING; /* we haven't read anything (yet) */
00059     if (Console->Mode & ENABLE_LINE_INPUT)
00060     {
00061         if (Console->LineBuffer == NULL)
00062         {
00063             /* Starting a new line */
00064             Console->LineMaxSize = max(256, nNumberOfCharsToRead);
00065             Console->LineBuffer = HeapAlloc(Win32CsrApiHeap, 0, Console->LineMaxSize * sizeof(WCHAR));
00066             if (Console->LineBuffer == NULL)
00067             {
00068                 Status = STATUS_NO_MEMORY;
00069                 goto done;
00070             }
00071             Console->LineComplete = FALSE;
00072             Console->LineUpPressed = FALSE;
00073             Console->LineInsertToggle = 0;
00074             Console->LineWakeupMask = Request->Data.ReadConsoleRequest.CtrlWakeupMask;
00075             Console->LineSize = Request->Data.ReadConsoleRequest.NrCharactersRead;
00076             Console->LinePos = Console->LineSize;
00077             /* pre-filling the buffer is only allowed in the Unicode API,
00078              * so we don't need to worry about conversion */
00079             memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
00080             if (Console->LineSize == Console->LineMaxSize)
00081             {
00082                 Console->LineComplete = TRUE;
00083                 Console->LinePos = 0;
00084             }
00085         }
00086 
00087         /* If we don't have a complete line yet, process the pending input */
00088         while (!Console->LineComplete && !IsListEmpty(&Console->InputEvents))
00089         {
00090             /* remove input event from queue */
00091             CurrentEntry = RemoveHeadList(&Console->InputEvents);
00092             if (IsListEmpty(&Console->InputEvents))
00093             {
00094                 ResetEvent(Console->ActiveEvent);
00095             }
00096             Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
00097 
00098             /* only pay attention to key down */
00099             if (KEY_EVENT == Input->InputEvent.EventType
00100                     && Input->InputEvent.Event.KeyEvent.bKeyDown)
00101             {
00102                 LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent);
00103                 Request->Data.ReadConsoleRequest.ControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
00104             }
00105             HeapFree(Win32CsrApiHeap, 0, Input);
00106         }
00107 
00108         /* Check if we have a complete line to read from */
00109         if (Console->LineComplete)
00110         {
00111             while (i < nNumberOfCharsToRead && Console->LinePos != Console->LineSize)
00112             {
00113                 WCHAR Char = Console->LineBuffer[Console->LinePos++];
00114                 if (Request->Data.ReadConsoleRequest.Unicode)
00115                     UnicodeBuffer[i++] = Char;
00116                 else
00117                     ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char);
00118             }
00119             if (Console->LinePos == Console->LineSize)
00120             {
00121                 /* Entire line has been read */
00122                 HeapFree(Win32CsrApiHeap, 0, Console->LineBuffer);
00123                 Console->LineBuffer = NULL;
00124             }
00125             Status = STATUS_SUCCESS;
00126         }
00127     }
00128     else
00129     {
00130         /* Character input */
00131         while (i < nNumberOfCharsToRead && !IsListEmpty(&Console->InputEvents))
00132         {
00133             /* remove input event from queue */
00134             CurrentEntry = RemoveHeadList(&Console->InputEvents);
00135             if (IsListEmpty(&Console->InputEvents))
00136             {
00137                 ResetEvent(Console->ActiveEvent);
00138             }
00139             Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
00140 
00141             /* only pay attention to valid ascii chars, on key down */
00142             if (KEY_EVENT == Input->InputEvent.EventType
00143                     && Input->InputEvent.Event.KeyEvent.bKeyDown
00144                     && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
00145             {
00146                 WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
00147                 if (Request->Data.ReadConsoleRequest.Unicode)
00148                     UnicodeBuffer[i++] = Char;
00149                 else
00150                     ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char);
00151                 Status = STATUS_SUCCESS; /* did read something */
00152             }
00153             HeapFree(Win32CsrApiHeap, 0, Input);
00154         }
00155     }
00156 done:
00157     Request->Data.ReadConsoleRequest.NrCharactersRead = i;
00158     ConioUnlockConsole(Console);
00159 
00160     return Status;
00161 }
00162 
00163 static VOID FASTCALL
00164 ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent)
00165 {
00166     if (InputEvent->EventType == KEY_EVENT)
00167     {
00168         WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
00169         InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
00170         ConsoleInputUnicodeCharToAnsiChar(Console,
00171                                           &InputEvent->Event.KeyEvent.uChar.AsciiChar,
00172                                           &UnicodeChar);
00173     }
00174 }
00175 
00176 static NTSTATUS FASTCALL
00177 ConioProcessChar(PCSRSS_CONSOLE Console,
00178                  PINPUT_RECORD InputEvent)
00179 {
00180     ConsoleInput *ConInRec;
00181 
00182     /* Check for pause or unpause */
00183     if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown)
00184     {
00185         WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode;
00186         if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD))
00187         {
00188             DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState;
00189             if (Console->Mode & ENABLE_LINE_INPUT &&
00190                 (vk == VK_PAUSE || (vk == 'S' &&
00191                                     (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
00192                                     !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
00193             {
00194                 ConioPause(Console, PAUSED_FROM_KEYBOARD);
00195                 return STATUS_SUCCESS;
00196             }
00197         }
00198         else
00199         {
00200             if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN &&
00201                 vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL)
00202             {
00203                 ConioUnpause(Console, PAUSED_FROM_KEYBOARD);
00204                 return STATUS_SUCCESS;
00205             }
00206         }
00207     }
00208 
00209     /* add event to the queue */
00210     ConInRec = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
00211     if (ConInRec == NULL)
00212         return STATUS_INSUFFICIENT_RESOURCES;
00213     ConInRec->InputEvent = *InputEvent;
00214     InsertTailList(&Console->InputEvents, &ConInRec->ListEntry);
00215     SetEvent(Console->ActiveEvent);
00216     return STATUS_SUCCESS;
00217 }
00218 
00219 static DWORD FASTCALL
00220 ConioGetShiftState(PBYTE KeyState)
00221 {
00222     DWORD ssOut = 0;
00223 
00224     if (KeyState[VK_CAPITAL] & 1)
00225         ssOut |= CAPSLOCK_ON;
00226 
00227     if (KeyState[VK_NUMLOCK] & 1)
00228         ssOut |= NUMLOCK_ON;
00229 
00230     if (KeyState[VK_SCROLL] & 1)
00231         ssOut |= SCROLLLOCK_ON;
00232 
00233     if (KeyState[VK_SHIFT] & 0x80)
00234         ssOut |= SHIFT_PRESSED;
00235 
00236     if (KeyState[VK_LCONTROL] & 0x80)
00237         ssOut |= LEFT_CTRL_PRESSED;
00238     if (KeyState[VK_RCONTROL] & 0x80)
00239         ssOut |= RIGHT_CTRL_PRESSED;
00240 
00241     if (KeyState[VK_LMENU] & 0x80)
00242         ssOut |= LEFT_ALT_PRESSED;
00243     if (KeyState[VK_RMENU] & 0x80)
00244         ssOut |= RIGHT_ALT_PRESSED;
00245 
00246     return ssOut;
00247 }
00248 
00249 VOID WINAPI
00250 ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
00251 {
00252     static BYTE KeyState[256] = { 0 };
00253     /* MSDN mentions that you should use the last virtual key code received
00254      * when putting a virtual key identity to a WM_CHAR message since multiple
00255      * or translated keys may be involved. */
00256     static UINT LastVirtualKey = 0;
00257     DWORD ShiftState;
00258     UINT RepeatCount;
00259     WCHAR UnicodeChar;
00260     UINT VirtualKeyCode;
00261     UINT VirtualScanCode;
00262     BOOL Down = FALSE;
00263     INPUT_RECORD er;
00264     BOOLEAN Fake;          // synthesized, not a real event
00265     BOOLEAN NotChar;       // message should not be used to return a character
00266 
00267     RepeatCount = 1;
00268     VirtualScanCode = (msg->lParam >> 16) & 0xff;
00269     Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
00270            msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
00271 
00272     GetKeyboardState(KeyState);
00273     ShiftState = ConioGetShiftState(KeyState);
00274 
00275     if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
00276     {
00277         VirtualKeyCode = LastVirtualKey;
00278         UnicodeChar = msg->wParam;
00279     }
00280     else
00281     {
00282         WCHAR Chars[2];
00283         INT RetChars = 0;
00284 
00285         VirtualKeyCode = msg->wParam;
00286         RetChars = ToUnicodeEx(VirtualKeyCode,
00287                                VirtualScanCode,
00288                                KeyState,
00289                                Chars,
00290                                2,
00291                                0,
00292                                0);
00293         UnicodeChar = (1 == RetChars ? Chars[0] : 0);
00294     }
00295 
00296     er.EventType = KEY_EVENT;
00297     er.Event.KeyEvent.bKeyDown = Down;
00298     er.Event.KeyEvent.wRepeatCount = RepeatCount;
00299     er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
00300     er.Event.KeyEvent.dwControlKeyState = ShiftState;
00301     er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
00302     er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
00303 
00304     if (TextMode)
00305     {
00306         if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
00307                 && VK_TAB == VirtualKeyCode)
00308         {
00309             if (Down)
00310             {
00311                 TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
00312             }
00313 
00314             return;
00315         }
00316         else if (VK_MENU == VirtualKeyCode && ! Down)
00317         {
00318             if (TuiSwapConsole(0))
00319             {
00320                 return;
00321             }
00322         }
00323     }
00324     else
00325     {
00326         if ((ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED) || KeyState[VK_MENU] & 0x80) &&
00327             (VirtualKeyCode == VK_ESCAPE || VirtualKeyCode == VK_TAB || VirtualKeyCode == VK_SPACE))
00328         {
00329            DefWindowProcW( msg->hwnd, msg->message, msg->wParam, msg->lParam);
00330            return;
00331         }
00332     }
00333 
00334     if (NULL == Console)
00335     {
00336         DPRINT1("No Active Console!\n");
00337         return;
00338     }
00339 
00340     Fake = UnicodeChar &&
00341             (msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
00342             msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
00343     NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
00344     if (NotChar)
00345         LastVirtualKey = msg->wParam;
00346 
00347     DPRINT  ("csrss: %s %s %s %s %02x %02x '%lc' %04x\n",
00348              Down ? "down" : "up  ",
00349              (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
00350              "char" : "key ",
00351              Fake ? "fake" : "real",
00352              NotChar ? "notc" : "char",
00353              VirtualScanCode,
00354              VirtualKeyCode,
00355              (UnicodeChar >= L' ') ? UnicodeChar : L'.',
00356              ShiftState);
00357 
00358     if (Fake)
00359         return;
00360 
00361     /* process Ctrl-C and Ctrl-Break */
00362     if (Console->Mode & ENABLE_PROCESSED_INPUT &&
00363             er.Event.KeyEvent.bKeyDown &&
00364             ((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) ||
00365              (er.Event.KeyEvent.wVirtualKeyCode == 'C')) &&
00366             (er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80))
00367     {
00368         PCSR_PROCESS current;
00369         PLIST_ENTRY current_entry;
00370         DPRINT1("Console_Api Ctrl-C\n");
00371         current_entry = Console->ProcessList.Flink;
00372         while (current_entry != &Console->ProcessList)
00373         {
00374             current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
00375             current_entry = current_entry->Flink;
00376             ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
00377         }
00378         if (Console->LineBuffer && !Console->LineComplete)
00379         {
00380             /* Line input is in progress; end it */
00381             Console->LinePos = Console->LineSize = 0;
00382             Console->LineComplete = TRUE;
00383         }
00384         return;
00385     }
00386 
00387     if (0 != (er.Event.KeyEvent.dwControlKeyState
00388               & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
00389             && (VK_UP == er.Event.KeyEvent.wVirtualKeyCode
00390                 || VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode))
00391     {
00392         if (er.Event.KeyEvent.bKeyDown)
00393         {
00394             /* scroll up or down */
00395             if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode)
00396             {
00397                 /* only scroll up if there is room to scroll up into */
00398                 if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1)
00399                 {
00400                     Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
00401                                                        Console->ActiveBuffer->MaxY - 1) %
00402                                                       Console->ActiveBuffer->MaxY;
00403                     Console->ActiveBuffer->CurrentY++;
00404                 }
00405             }
00406             else
00407             {
00408                 /* only scroll down if there is room to scroll down into */
00409                 if (Console->ActiveBuffer->CurrentY != 0)
00410                 {
00411                     Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
00412                                                       Console->ActiveBuffer->MaxY;
00413                     Console->ActiveBuffer->CurrentY--;
00414                 }
00415             }
00416             ConioDrawConsole(Console);
00417         }
00418         return;
00419     }
00420     ConioProcessChar(Console, &er);
00421 }
00422 
00423 CSR_API(CsrReadInputEvent)
00424 {
00425     PLIST_ENTRY CurrentEntry;
00426     PCSRSS_CONSOLE Console;
00427     NTSTATUS Status;
00428     BOOLEAN Done = FALSE;
00429     ConsoleInput *Input;
00430 
00431     DPRINT("CsrReadInputEvent\n");
00432 
00433     Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent;
00434 
00435     Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ);
00436     if (! NT_SUCCESS(Status))
00437     {
00438         return Status;
00439     }
00440 
00441     /* only get input if there is any */
00442     CurrentEntry = Console->InputEvents.Flink;
00443     while (CurrentEntry != &Console->InputEvents)
00444     {
00445         Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
00446         CurrentEntry = CurrentEntry->Flink;
00447 
00448         if (Done)
00449         {
00450             Request->Data.ReadInputRequest.MoreEvents = TRUE;
00451             break;
00452         }
00453 
00454         RemoveEntryList(&Input->ListEntry);
00455 
00456         if (!Done)
00457         {
00458             Request->Data.ReadInputRequest.Input = Input->InputEvent;
00459             if (Request->Data.ReadInputRequest.Unicode == FALSE)
00460             {
00461                 ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input);
00462             }
00463             Done = TRUE;
00464         }
00465 
00466         HeapFree(Win32CsrApiHeap, 0, Input);
00467     }
00468 
00469     if (Done)
00470         Status = STATUS_SUCCESS;
00471     else
00472         Status = STATUS_PENDING;
00473 
00474     if (IsListEmpty(&Console->InputEvents))
00475     {
00476         ResetEvent(Console->ActiveEvent);
00477     }
00478 
00479     ConioUnlockConsole(Console);
00480 
00481     return Status;
00482 }
00483 
00484 CSR_API(CsrFlushInputBuffer)
00485 {
00486     PLIST_ENTRY CurrentEntry;
00487     PCSRSS_CONSOLE Console;
00488     ConsoleInput* Input;
00489     NTSTATUS Status;
00490 
00491     DPRINT("CsrFlushInputBuffer\n");
00492 
00493     Status = ConioLockConsole(ProcessData,
00494                               Request->Data.FlushInputBufferRequest.ConsoleInput,
00495                               &Console,
00496                               GENERIC_WRITE);
00497     if(! NT_SUCCESS(Status))
00498     {
00499         return Status;
00500     }
00501 
00502     /* Discard all entries in the input event queue */
00503     while (!IsListEmpty(&Console->InputEvents))
00504     {
00505         CurrentEntry = RemoveHeadList(&Console->InputEvents);
00506         Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
00507         /* Destroy the event */
00508         HeapFree(Win32CsrApiHeap, 0, Input);
00509     }
00510     ResetEvent(Console->ActiveEvent);
00511 
00512     ConioUnlockConsole(Console);
00513 
00514     return STATUS_SUCCESS;
00515 }
00516 
00517 CSR_API(CsrGetNumberOfConsoleInputEvents)
00518 {
00519     NTSTATUS Status;
00520     PCSRSS_CONSOLE Console;
00521     PLIST_ENTRY CurrentItem;
00522     DWORD NumEvents;
00523 
00524     DPRINT("CsrGetNumberOfConsoleInputEvents\n");
00525 
00526     Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
00527     if (! NT_SUCCESS(Status))
00528     {
00529         return Status;
00530     }
00531 
00532     CurrentItem = Console->InputEvents.Flink;
00533     NumEvents = 0;
00534 
00535     /* If there are any events ... */
00536     while (CurrentItem != &Console->InputEvents)
00537     {
00538         CurrentItem = CurrentItem->Flink;
00539         NumEvents++;
00540     }
00541 
00542     ConioUnlockConsole(Console);
00543 
00544     Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents;
00545 
00546     return STATUS_SUCCESS;
00547 }
00548 
00549 CSR_API(CsrPeekConsoleInput)
00550 {
00551     NTSTATUS Status;
00552     PCSRSS_CONSOLE Console;
00553     DWORD Length;
00554     PLIST_ENTRY CurrentItem;
00555     PINPUT_RECORD InputRecord;
00556     ConsoleInput* Item;
00557     UINT NumItems;
00558 
00559     DPRINT("CsrPeekConsoleInput\n");
00560 
00561     Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
00562     if(! NT_SUCCESS(Status))
00563     {
00564         return Status;
00565     }
00566 
00567     InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord;
00568     Length = Request->Data.PeekConsoleInputRequest.Length;
00569 
00570     if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD)))
00571     {
00572         ConioUnlockConsole(Console);
00573         return STATUS_ACCESS_VIOLATION;
00574     }
00575 
00576     NumItems = 0;
00577 
00578     if (! IsListEmpty(&Console->InputEvents))
00579     {
00580         CurrentItem = Console->InputEvents.Flink;
00581 
00582         while (CurrentItem != &Console->InputEvents && NumItems < Length)
00583         {
00584             Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
00585 
00586             ++NumItems;
00587             *InputRecord = Item->InputEvent;
00588 
00589             if (Request->Data.PeekConsoleInputRequest.Unicode == FALSE)
00590             {
00591                 ConioInputEventToAnsi(Console, InputRecord);
00592             }
00593 
00594             InputRecord++;
00595             CurrentItem = CurrentItem->Flink;
00596         }
00597     }
00598 
00599     ConioUnlockConsole(Console);
00600 
00601     Request->Data.PeekConsoleInputRequest.Length = NumItems;
00602 
00603     return STATUS_SUCCESS;
00604 }
00605 
00606 CSR_API(CsrWriteConsoleInput)
00607 {
00608     PINPUT_RECORD InputRecord;
00609     PCSRSS_CONSOLE Console;
00610     NTSTATUS Status;
00611     DWORD Length;
00612     DWORD i;
00613 
00614     DPRINT("CsrWriteConsoleInput\n");
00615 
00616     Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE);
00617     if (! NT_SUCCESS(Status))
00618     {
00619         return Status;
00620     }
00621 
00622     InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord;
00623     Length = Request->Data.WriteConsoleInputRequest.Length;
00624 
00625     if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD)))
00626     {
00627         ConioUnlockConsole(Console);
00628         return STATUS_ACCESS_VIOLATION;
00629     }
00630 
00631     for (i = 0; i < Length && NT_SUCCESS(Status); i++)
00632     {
00633         if (!Request->Data.WriteConsoleInputRequest.Unicode &&
00634             InputRecord->EventType == KEY_EVENT)
00635         {
00636             CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar;
00637             ConsoleInputAnsiCharToUnicodeChar(Console,
00638                                               &InputRecord->Event.KeyEvent.uChar.UnicodeChar,
00639                                               &AsciiChar);
00640         }
00641         Status = ConioProcessChar(Console, InputRecord++);
00642     }
00643 
00644     ConioUnlockConsole(Console);
00645 
00646     Request->Data.WriteConsoleInputRequest.Length = i;
00647 
00648     return Status;
00649 }
00650 
00651 /* EOF */

Generated on Sun May 27 2012 04:38:44 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.