Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenconinput.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
1.7.6.1
|