00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "precomp.h"
00022
#pragma hdrstop
00023
00024 #define IS_CONTROL_CHAR(wch) ((wch) < L' ')
00025 #define IS_GLYPH_CHAR(wch) (((wch) < L' ') || ((wch) == 0x007F))
00026
00027 #define LINE_INPUT_BUFFER_SIZE (256 * sizeof(WCHAR))
00028
00029 #define CONSOLE_CTRL_2 0x0
00030
00031
NTSTATUS
00032
WaitForMoreToRead(
00033 IN
PINPUT_INFORMATION InputInformation,
00034 IN PCSR_API_MSG Message OPTIONAL,
00035 IN CSR_WAIT_ROUTINE WaitRoutine OPTIONAL,
00036 IN PVOID WaitParameter OPTIONAL,
00037 IN ULONG WaitParameterLength OPTIONAL,
00038 IN BOOLEAN WaitBlockExists OPTIONAL
00039 );
00040
00041 BOOLEAN
00042
WriteConsoleWaitRoutine(
00043 IN PLIST_ENTRY WaitQueue,
00044 IN PCSR_THREAD WaitingThread,
00045 IN PCSR_API_MSG WaitReplyMessage,
00046 IN PVOID WaitParameter,
00047 IN PVOID SatisfyParameter1,
00048 IN PVOID SatisfyParameter2,
00049 IN ULONG WaitFlags
00050 );
00051
00052 HANDLE
00053 FindActiveScreenBufferHandle(
00054 IN
PCONSOLE_PER_PROCESS_DATA ProcessData,
00055 IN
PCONSOLE_INFORMATION Console
00056 )
00057 {
00058 ULONG i;
00059 HANDLE ActiveScreenHandle;
00060
PHANDLE_DATA ActiveScreenHandleData;
00061
NTSTATUS Status;
00062
00063 ActiveScreenHandle =
INVALID_HANDLE_VALUE;
00064
for (i=0;i<ProcessData->HandleTableSize;i++) {
00065
Status =
DereferenceIoHandleNoCheck(ProcessData,
00066 (HANDLE) i,
00067 &ActiveScreenHandleData
00068 );
00069
if (
NT_SUCCESS(
Status) &&
00070 Console->CurrentScreenBuffer == ActiveScreenHandleData->
Buffer.ScreenBuffer) {
00071
ASSERT (ActiveScreenHandleData->
HandleType & (
CONSOLE_OUTPUT_HANDLE |
CONSOLE_GRAPHICS_OUTPUT_HANDLE));
00072 ActiveScreenHandle = (HANDLE) i;
00073
break;
00074 }
00075 }
00076
return ActiveScreenHandle;
00077 }
00078
00079 ULONG
00080 SrvOpenConsole(
00081 IN OUT PCSR_API_MSG m,
00082 IN OUT PCSR_REPLY_STATUS ReplyStatus
00083 )
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 {
00100
PCONSOLE_OPENCONSOLE_MSG a = (
PCONSOLE_OPENCONSOLE_MSG)&m->u.ApiMessageData;
00101
NTSTATUS Status;
00102
PCONSOLE_INFORMATION Console;
00103 HANDLE
Handle;
00104
PHANDLE_DATA HandleData;
00105
PCONSOLE_PER_PROCESS_DATA ProcessData;
00106
00107
Status =
ApiPreamble(a->
ConsoleHandle,
00108 &Console
00109 );
00110
if (!
NT_SUCCESS(
Status)) {
00111
return Status;
00112 }
00113
00114
try {
00115
Handle = (HANDLE) -1;
00116 ProcessData =
CONSOLE_PERPROCESSDATA();
00117
if (a->
HandleType ==
CONSOLE_INPUT_HANDLE) {
00118
00119
Status =
AllocateIoHandle(ProcessData,
00120 a->
HandleType,
00121 &
Handle
00122 );
00123
if (!
NT_SUCCESS(
Status)) {
00124 leave;
00125 }
00126
Status =
DereferenceIoHandleNoCheck(ProcessData,
00127
Handle,
00128 &HandleData
00129 );
00130
ASSERT (
NT_SUCCESS(
Status));
00131
if (!
NT_SUCCESS(
Status)) {
00132 leave;
00133 }
00134
if (!
InitializeInputHandle(HandleData,
00135 &Console->
InputBuffer)) {
00136
Status = STATUS_NO_MEMORY;
00137 leave;
00138 }
00139
if (a->
InheritHandle) {
00140 HandleData->
HandleType |=
CONSOLE_INHERITABLE;
00141 }
00142
Status =
ConsoleAddShare(a->
DesiredAccess,
00143 a->
ShareMode,
00144 &HandleData->
Buffer.InputBuffer->ShareAccess,
00145 HandleData
00146 );
00147
if (!
NT_SUCCESS(
Status)) {
00148 HandleData->
Buffer.InputBuffer->RefCount--;
00149 leave;
00150 }
00151 }
00152
else if (a->
HandleType ==
CONSOLE_OUTPUT_HANDLE){
00153
PSCREEN_INFORMATION ScreenInfo;
00154
00155
00156
00157
00158
00159 ScreenInfo = Console->
CurrentScreenBuffer;
00160
if (ScreenInfo ==
NULL) {
00161
Status = STATUS_OBJECT_NAME_NOT_FOUND;
00162 leave;
00163 }
00164
Status =
AllocateIoHandle(ProcessData,
00165 a->
HandleType,
00166 &
Handle
00167 );
00168
if (!
NT_SUCCESS(
Status)) {
00169 leave;
00170 }
00171
Status =
DereferenceIoHandleNoCheck(ProcessData,
00172
Handle,
00173 &HandleData
00174 );
00175
ASSERT (
NT_SUCCESS(
Status));
00176
if (!
NT_SUCCESS(
Status)) {
00177 leave;
00178 }
00179
InitializeOutputHandle(HandleData, ScreenInfo);
00180
if (a->
InheritHandle) {
00181 HandleData->
HandleType |=
CONSOLE_INHERITABLE;
00182 }
00183
Status =
ConsoleAddShare(a->
DesiredAccess,
00184 a->
ShareMode,
00185 &HandleData->
Buffer.ScreenBuffer->ShareAccess,
00186 HandleData
00187 );
00188
if (!
NT_SUCCESS(
Status)) {
00189 HandleData->
Buffer.ScreenBuffer->RefCount--;
00190 leave;
00191 }
00192 }
00193
else {
00194
Status = STATUS_INVALID_PARAMETER;
00195 leave;
00196 }
00197 a->
Handle =
INDEX_TO_HANDLE(
Handle);
00198
Status = STATUS_SUCCESS;
00199 } finally {
00200
if (!
NT_SUCCESS(
Status) &&
Handle != (HANDLE)-1) {
00201
FreeIoHandle(ProcessData,
00202
Handle
00203 );
00204 }
00205
UnlockConsole(Console);
00206 }
00207
return Status;
00208 UNREFERENCED_PARAMETER(ReplyStatus);
00209 }
00210
00211
00212
00213
00214 #define EITHER_CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
00215 #define EITHER_ALT_PRESSED (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)
00216 #define MOD_PRESSED (SHIFT_PRESSED | EITHER_CTRL_PRESSED | EITHER_ALT_PRESSED)
00217
00218 DWORD ConsKbdState[] = {
00219 0,
00220 SHIFT_PRESSED,
00221
EITHER_CTRL_PRESSED,
00222 SHIFT_PRESSED |
EITHER_CTRL_PRESSED,
00223
EITHER_ALT_PRESSED,
00224 SHIFT_PRESSED |
EITHER_ALT_PRESSED,
00225
EITHER_CTRL_PRESSED |
EITHER_ALT_PRESSED,
00226 SHIFT_PRESSED |
EITHER_CTRL_PRESSED |
EITHER_ALT_PRESSED
00227 };
00228
00229 #define KEYEVENTSTATE_EQUAL_WINMODS(Event, WinMods)\
00230
((Event.Event.KeyEvent.dwControlKeyState & ConsKbdState[WinMods]) && \
00231
!(Event.Event.KeyEvent.dwControlKeyState & MOD_PRESSED & ~ConsKbdState[WinMods]))
00232
00233 BOOL IsDbcsExemptionForHighAnsi(
00234 UINT wCodePage,
00235 WORD wNumpadChar)
00236 {
00237 UserAssert(
HIBYTE(wNumpadChar) == 0);
00238
00239
if (wCodePage ==
CP_JAPANESE &&
IS_JPN_1BYTE_KATAKANA(wNumpadChar)) {
00240
00241
00242
00243
00244
return FALSE;
00245 }
00246
else if (wNumpadChar >= 0x80 && wNumpadChar <= 0xff) {
00247
00248
00249
00250
00251
return TRUE;
00252 }
00253
00254
00255
00256
00257
00258
00259
return FALSE;
00260 }
00261
00262
NTSTATUS
00263 GetChar(
00264 IN
PINPUT_INFORMATION InputInfo,
00265 OUT PWCHAR Char,
00266 IN BOOLEAN Wait,
00267 IN
PCONSOLE_INFORMATION Console,
00268 IN
PHANDLE_DATA HandleData,
00269 IN PCSR_API_MSG Message OPTIONAL,
00270 IN CSR_WAIT_ROUTINE WaitRoutine OPTIONAL,
00271 IN PVOID WaitParameter OPTIONAL,
00272 IN ULONG WaitParameterLength OPTIONAL,
00273 IN BOOLEAN WaitBlockExists OPTIONAL,
00274 OUT PBOOLEAN CommandLineEditingKeys OPTIONAL,
00275 OUT PBOOLEAN CommandLinePopupKeys OPTIONAL,
00276 OUT PBOOLEAN EnableScrollMode OPTIONAL,
00277 OUT PDWORD KeyState OPTIONAL
00278 )
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 {
00320 ULONG NumRead;
00321 INPUT_RECORD
Event;
00322
NTSTATUS Status;
00323
00324
if (ARGUMENT_PRESENT(CommandLineEditingKeys)) {
00325 *CommandLineEditingKeys =
FALSE;
00326 }
00327
if (ARGUMENT_PRESENT(CommandLinePopupKeys)) {
00328 *CommandLinePopupKeys =
FALSE;
00329 }
00330
if (ARGUMENT_PRESENT(EnableScrollMode)) {
00331 *EnableScrollMode =
FALSE;
00332 }
00333
if (ARGUMENT_PRESENT(KeyState)) {
00334 *KeyState = 0;
00335 }
00336
00337 NumRead = 1;
00338
while (
TRUE) {
00339
Status =
ReadInputBuffer(InputInfo,
00340 &
Event,
00341 &NumRead,
00342
FALSE,
00343 Wait,
00344
TRUE,
00345 Console,
00346 HandleData,
00347 Message,
00348 WaitRoutine,
00349 WaitParameter,
00350 WaitParameterLength,
00351 WaitBlockExists
00352 #
if defined(FE_SB)
00353 ,
00354
TRUE
00355 #endif
00356 );
00357
if (!
NT_SUCCESS(
Status)) {
00358
return Status;
00359 }
00360
if (NumRead == 0) {
00361
if (Wait) {
00362
ASSERT (
FALSE);
00363 }
00364
else {
00365
return STATUS_UNSUCCESSFUL;
00366 }
00367 }
00368
if (
Event.EventType == KEY_EVENT) {
00369
BOOL fCommandLineEditKey;
00370
00371
if (ARGUMENT_PRESENT(CommandLineEditingKeys)) {
00372 fCommandLineEditKey =
IsCommandLineEditingKey(&
Event.Event.KeyEvent);
00373 }
else if (ARGUMENT_PRESENT(CommandLinePopupKeys)) {
00374 fCommandLineEditKey =
IsCommandLinePopupKey(&
Event.Event.KeyEvent);
00375 }
else {
00376 fCommandLineEditKey =
FALSE;
00377 }
00378
00379
00380
00381
00382
if (ARGUMENT_PRESENT(KeyState)) {
00383 *KeyState =
Event.Event.KeyEvent.dwControlKeyState;
00384 }
00385
00386
if (
Event.Event.KeyEvent.uChar.UnicodeChar != 0 &&
00387 !fCommandLineEditKey) {
00388
00389
00390
00391
00392
if (!
Event.Event.KeyEvent.bKeyDown &&
00393
Event.Event.KeyEvent.wVirtualKeyCode == VK_MENU) {
00394
if (
Event.Event.KeyEvent.dwControlKeyState & ALTNUMPAD_BIT)
00395 {
00396
if (CONSOLE_IS_DBCS_CP(Console) &&
HIBYTE(
Event.Event.KeyEvent.uChar.UnicodeChar)) {
00397
char chT[2] = {
00398
HIBYTE(
Event.Event.KeyEvent.uChar.UnicodeChar),
00399
LOBYTE(
Event.Event.KeyEvent.uChar.UnicodeChar),
00400 };
00401 *Char =
CharToWchar(Console, Console->CP, chT);
00402 }
else {
00403
00404
00405
char chT =
LOBYTE(
Event.Event.KeyEvent.uChar.UnicodeChar);
00406
UINT uCodePage = Console->CP;
00407
00408
00409
00410
00411
if (CONSOLE_IS_DBCS_CP(Console)) {
00412
if (
IsDbcsExemptionForHighAnsi(uCodePage, chT)) {
00413
00414
00415
00416
00417
00418 uCodePage = 1252;
00419 }
00420 }
00421 *Char =
CharToWchar(Console, uCodePage, &chT);
00422 }
00423 }
else {
00424 *Char =
Event.Event.KeyEvent.uChar.UnicodeChar;
00425 }
00426
return STATUS_SUCCESS;
00427 }
00428
00429
00430
00431
else if (
Event.Event.KeyEvent.bKeyDown &&
00432
Event.Event.KeyEvent.wVirtualKeyCode != VK_ESCAPE &&
00433
Event.Event.KeyEvent.uChar.UnicodeChar != 0x0a) {
00434
00435 *Char =
Event.Event.KeyEvent.uChar.UnicodeChar;
00436
return STATUS_SUCCESS;
00437 }
00438 }
00439
00440
if (
Event.Event.KeyEvent.bKeyDown) {
00441
SHORT sTmp;
00442
if (ARGUMENT_PRESENT(CommandLineEditingKeys) &&
00443 fCommandLineEditKey) {
00444 *CommandLineEditingKeys =
TRUE;
00445 *Char = (WCHAR)
Event.Event.KeyEvent.wVirtualKeyCode;
00446
return STATUS_SUCCESS;
00447 }
00448
else if (ARGUMENT_PRESENT(CommandLinePopupKeys) &&
00449 fCommandLineEditKey) {
00450 *CommandLinePopupKeys =
TRUE;
00451 *Char = (
CHAR)
Event.Event.KeyEvent.wVirtualKeyCode;
00452
return STATUS_SUCCESS;
00453 }
00454
00455 sTmp =
VkKeyScan(0);
00456
00457
if ((
LOBYTE(sTmp) ==
Event.Event.KeyEvent.wVirtualKeyCode) &&
00458
KEYEVENTSTATE_EQUAL_WINMODS(
Event,
HIBYTE(sTmp))) {
00459
00460
00461
00462 *Char =
Event.Event.KeyEvent.uChar.UnicodeChar;
00463
return STATUS_SUCCESS;
00464 }
00465 }
00466 }
00467 }
00468 }
00469
00470 BOOLEAN
00471 RawReadWaitRoutine(
00472 IN PLIST_ENTRY WaitQueue,
00473 IN PCSR_THREAD WaitingThread,
00474 IN PCSR_API_MSG WaitReplyMessage,
00475 IN PVOID WaitParameter,
00476 IN PVOID SatisfyParameter1,
00477 IN PVOID SatisfyParameter2,
00478 IN ULONG WaitFlags
00479 )
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 {
00513
NTSTATUS Status;
00514 PWCHAR lpBuffer;
00515
PCONSOLE_READCONSOLE_MSG a;
00516
PCONSOLE_INFORMATION Console;
00517
PRAW_READ_DATA RawReadData;
00518
PHANDLE_DATA HandleData;
00519 BOOLEAN RetVal =
TRUE;
00520
#ifdef FE_SB
00521
DWORD NumBytes;
00522
BOOL fAddDbcsLead =
FALSE;
00523
#endif
00524
00525 a = (
PCONSOLE_READCONSOLE_MSG)&WaitReplyMessage->u.ApiMessageData;
00526 RawReadData = (
PRAW_READ_DATA)WaitParameter;
00527
00528
Status =
DereferenceIoHandleNoCheck(RawReadData->
ProcessData,
00529 RawReadData->
HandleIndex,
00530 &HandleData
00531 );
00532
ASSERT (
NT_SUCCESS(
Status));
00533
00534
00535
00536
00537
00538
00539
00540
if (SatisfyParameter1 !=
NULL &&
00541 SatisfyParameter1 != HandleData) {
00542
return FALSE;
00543 }
00544
if ((ULONG_PTR)SatisfyParameter2 &
CONSOLE_CTRL_C_SEEN) {
00545
return FALSE;
00546 }
00547
00548 Console = RawReadData->
Console;
00549
00550
00551
00552
00553
00554
00555 a->
NumBytes = 0;
00556
#ifdef FE_SB
00557
NumBytes = 0 ;
00558
#endif
00559
try {
00560
LockReadCount(HandleData);
00561
ASSERT(HandleData->
InputReadData->
ReadCount);
00562 HandleData->
InputReadData->
ReadCount -= 1;
00563
UnlockReadCount(HandleData);
00564
00565
00566
00567
00568
00569
00570
if ((ULONG_PTR)SatisfyParameter2 &
CONSOLE_CTRL_BREAK_SEEN) {
00571 WaitReplyMessage->ReturnValue = STATUS_ALERTED;
00572 leave;
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
if (WaitFlags & CSR_PROCESS_TERMINATING) {
00582
Status = STATUS_THREAD_IS_TERMINATING;
00583 leave;
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
if (HandleData->
InputReadData->
InputHandleFlags &
HANDLE_CLOSING) {
00594
ASSERT (SatisfyParameter1 == HandleData);
00595
Status = STATUS_ALERTED;
00596 leave;
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
ASSERT (
ConsoleLocked(Console));
00611
00612
if (a->
CaptureBufferSize <=
BUFFER_SIZE) {
00613 lpBuffer = a->
Buffer;
00614 }
00615
else {
00616 lpBuffer = RawReadData->
BufPtr;
00617 }
00618
00619
00620
00621
00622
00623
#ifdef FE_SB
00624
if (!a->
Unicode && CONSOLE_IS_DBCS_CP(Console)) {
00625
if (HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar) {
00626 fAddDbcsLead =
TRUE;
00627 *lpBuffer = HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar;
00628 RawReadData->
BufferSize-=
sizeof(WCHAR);
00629 RtlZeroMemory(&HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte,
sizeof(INPUT_RECORD));
00630
Status = STATUS_SUCCESS;
00631
if (RawReadData->
BufferSize == 0) {
00632 a->
NumBytes = 1;
00633
return FALSE;
00634 }
00635 }
00636
else{
00637
Status =
GetChar(RawReadData->
InputInfo,
00638 lpBuffer,
00639
TRUE,
00640 Console,
00641 HandleData,
00642 WaitReplyMessage,
00643
RawReadWaitRoutine,
00644 RawReadData,
00645
sizeof(*RawReadData),
00646
TRUE,
00647
NULL,
00648
NULL,
00649
NULL,
00650
NULL
00651 );
00652 }
00653 }
00654
else
00655
#endif
00656
Status =
GetChar(RawReadData->
InputInfo,
00657 lpBuffer,
00658
TRUE,
00659 Console,
00660 HandleData,
00661 WaitReplyMessage,
00662
RawReadWaitRoutine,
00663 RawReadData,
00664
sizeof(*RawReadData),
00665
TRUE,
00666
NULL,
00667
NULL,
00668
NULL,
00669
NULL
00670 );
00671
00672
if (!
NT_SUCCESS(
Status)) {
00673
if (
Status ==
CONSOLE_STATUS_WAIT) {
00674 RetVal =
FALSE;
00675 }
00676 leave;
00677 }
00678
#ifdef FE_SB
00679
IsConsoleFullWidth(Console->
hDC,
00680 Console->
CP,*lpBuffer) ? NumBytes+=2 : NumBytes++;
00681
#endif
00682
lpBuffer++;
00683 a->
NumBytes +=
sizeof(WCHAR);
00684
while (a->
NumBytes < RawReadData->BufferSize) {
00685
00686
00687
00688
00689
00690
Status =
GetChar(RawReadData->InputInfo,lpBuffer,
FALSE,
NULL,
NULL,
NULL,
NULL,
NULL,0,
TRUE,
NULL,
NULL,
NULL,
NULL);
00691
if (!
NT_SUCCESS(
Status)) {
00692
Status = STATUS_SUCCESS;
00693
break;
00694 }
00695
#ifdef FE_SB
00696
IsConsoleFullWidth(Console->
hDC,
00697 Console->
CP,*lpBuffer) ? NumBytes+=2 : NumBytes++;
00698
#endif
00699
lpBuffer++;
00700 a->
NumBytes +=
sizeof(WCHAR);
00701 }
00702 } finally {
00703
00704
00705
00706
00707
00708
00709
if (
Status !=
CONSOLE_STATUS_WAIT) {
00710
if (!a->
Unicode) {
00711
00712
00713
00714
00715
00716 PCHAR TransBuffer;
00717
00718
#ifdef FE_SB
00719
TransBuffer = (PCHAR)
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),NumBytes);
00720
#else
00721
TransBuffer = (PCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),a->
NumBytes /
sizeof(WCHAR));
00722
#endif
00723
if (TransBuffer ==
NULL) {
00724
return TRUE;
00725 }
00726
00727
if (a->
CaptureBufferSize <=
BUFFER_SIZE) {
00728 lpBuffer = a->
Buffer;
00729 }
00730
else {
00731 lpBuffer = RawReadData->
BufPtr;
00732 }
00733
00734
#ifdef FE_SB
00735
if (CONSOLE_IS_DBCS_CP(Console))
00736 {
00737 a->
NumBytes =
TranslateUnicodeToOem(Console,
00738 lpBuffer,
00739 a->
NumBytes / sizeof (WCHAR),
00740 TransBuffer,
00741 NumBytes,
00742 &HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte);
00743 }
00744
else
00745
#endif
00746
a->
NumBytes =
ConvertToOem(RawReadData->
Console->
CP,
00747 lpBuffer,
00748 a->
NumBytes / sizeof (WCHAR),
00749 TransBuffer,
00750 a->
NumBytes / sizeof (WCHAR)
00751 );
00752 RtlCopyMemory(lpBuffer,TransBuffer,a->
NumBytes);
00753
#ifdef FE_SB
00754
if (fAddDbcsLead)
00755 a->
NumBytes++;
00756
#endif
00757
ConsoleHeapFree(TransBuffer);
00758 }
00759 WaitReplyMessage->ReturnValue =
Status;
00760
ConsoleHeapFree(RawReadData);
00761 }
00762 }
00763
return RetVal;
00764
00765
00766
00767
00768
00769 UNREFERENCED_PARAMETER(WaitQueue);
00770 UNREFERENCED_PARAMETER(WaitingThread);
00771 }
00772
00773 ULONG
00774 RetrieveTotalNumberOfSpaces(
00775 IN SHORT OriginalCursorPositionX,
00776 IN PWCHAR Buffer,
00777 IN ULONG CurrentPosition
00778 #
if defined(FE_SB)
00779 ,
00780 IN
PCONSOLE_INFORMATION Console
00781 #endif
00782 )
00783
00784
00785
00786
00787
00788
00789
00790
00791 {
00792 WCHAR Char;
00793 ULONG i,NumSpacesForChar,NumSpaces;
00794
SHORT XPosition;
00795
00796 XPosition=OriginalCursorPositionX;
00797 NumSpaces=0;
00798
for (i=0;i<CurrentPosition;i++) {
00799 Char =
Buffer[i];
00800
if (Char ==
UNICODE_TAB) {
00801 NumSpacesForChar =
NUMBER_OF_SPACES_IN_TAB(XPosition);
00802 }
else if (
IS_CONTROL_CHAR(Char)) {
00803 NumSpacesForChar = 2;
00804
#if defined(FE_SB)
00805
}
else if (IsConsoleFullWidth(Console->hDC,Console->CP,Char)) {
00806 NumSpacesForChar = 2;
00807
#endif
00808
}
else {
00809 NumSpacesForChar = 1;
00810 }
00811 XPosition = (
SHORT)(XPosition+NumSpacesForChar);
00812 NumSpaces += NumSpacesForChar;
00813 }
00814
return NumSpaces;
00815 }
00816
00817 ULONG
00818 RetrieveNumberOfSpaces(
00819 IN SHORT OriginalCursorPositionX,
00820 IN PWCHAR Buffer,
00821 IN ULONG CurrentPosition
00822 #
if defined(FE_SB)
00823 ,
00824 IN
PCONSOLE_INFORMATION Console,
00825 IN DWORD CodePage
00826 #endif
00827 )
00828
00829
00830
00831
00832
00833
00834
00835
00836 {
00837 WCHAR Char;
00838 ULONG i,NumSpaces;
00839
SHORT XPosition;
00840
00841 Char =
Buffer[CurrentPosition];
00842
if (Char ==
UNICODE_TAB) {
00843 NumSpaces=0;
00844 XPosition=OriginalCursorPositionX;
00845
for (i=0;i<=CurrentPosition;i++) {
00846 Char =
Buffer[i];
00847
if (Char ==
UNICODE_TAB) {
00848 NumSpaces =
NUMBER_OF_SPACES_IN_TAB(XPosition);
00849 }
else if (
IS_CONTROL_CHAR(Char)) {
00850 NumSpaces = 2;
00851
#if defined(FE_SB)
00852
}
else if (IsConsoleFullWidth(Console->hDC,CodePage,Char)) {
00853 NumSpaces = 2;
00854
#endif
00855
}
else {
00856 NumSpaces = 1;
00857 }
00858 XPosition = (
SHORT)(XPosition+NumSpaces);
00859 }
00860
return NumSpaces;
00861 }
00862
else if (
IS_CONTROL_CHAR(Char)) {
00863
return 2;
00864 }
00865
#if defined(FE_SB)
00866
else if (IsConsoleFullWidth(Console->hDC,CodePage,Char)) {
00867
return 2;
00868 }
00869
#endif
00870
else {
00871
return 1;
00872 }
00873 }
00874
00875
BOOL
00876 ProcessCookedReadInput(
00877 IN
PCOOKED_READ_DATA CookedReadData,
00878 IN WCHAR Char,
00879 IN DWORD KeyState,
00880 OUT PNTSTATUS Status
00881 )
00882
00883
00884
00885
00886
00887
00888
00889
00890 {
00891
DWORD NumSpaces;
00892
SHORT ScrollY=0;
00893 ULONG NumToWrite;
00894 WCHAR wchOrig = Char;
00895
BOOL fStartFromDelim;
00896
00897 *
Status = STATUS_SUCCESS;
00898
if (CookedReadData->BytesRead >= (CookedReadData->BufferSize-(2*
sizeof(WCHAR))) &&
00899 Char !=
UNICODE_CARRIAGERETURN &&
00900 Char !=
UNICODE_BACKSPACE) {
00901
return FALSE;
00902 }
00903
00904
if (CookedReadData->CtrlWakeupMask != 0 &&
00905 Char <
L' ' && (CookedReadData->CtrlWakeupMask & (1 << Char))) {
00906 *CookedReadData->BufPtr = Char;
00907 CookedReadData->BytesRead +=
sizeof(WCHAR);
00908 CookedReadData->BufPtr+=1;
00909 CookedReadData->CurrentPosition+=1;
00910 CookedReadData->ControlKeyState = KeyState;
00911
return TRUE;
00912 }
00913
00914
00915
if (Char == EXTKEY_ERASE_PREV_WORD) {
00916 Char =
UNICODE_BACKSPACE;
00917
00918 }
00919
if (
AT_EOL(CookedReadData)) {
00920
00921
00922
00923
00924
00925
00926
00927
if (Char ==
UNICODE_BACKSPACE2) {
00928 Char =
UNICODE_BACKSPACE;
00929 }
00930
if (Char !=
UNICODE_BACKSPACE ||
00931 CookedReadData->BufPtr != CookedReadData->BackupLimit) {
00932
00933 fStartFromDelim =
gExtendedEditKey &&
IS_WORD_DELIM(CookedReadData->BufPtr[-1]);
00934
00935 eol_repeat:
00936
if (CookedReadData->Echo) {
00937 NumToWrite=
sizeof(WCHAR);
00938 *
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
00939 CookedReadData->BackupLimit,
00940 CookedReadData->BufPtr,
00941 &Char,
00942 &NumToWrite,
00943 (PLONG)&NumSpaces,
00944 CookedReadData->OriginalCursorPosition.X,
00945
WC_DESTRUCTIVE_BACKSPACE |
00946
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
00947 &ScrollY
00948 );
00949
if (
NT_SUCCESS(*
Status)) {
00950 CookedReadData->OriginalCursorPosition.Y += ScrollY;
00951 }
else {
00952 RIPMSG1(RIP_WARNING,
"WriteCharsFromInput failed %x", *
Status);
00953 }
00954 }
00955 CookedReadData->NumberOfVisibleChars += NumSpaces;
00956
if (Char ==
UNICODE_BACKSPACE && CookedReadData->Processed) {
00957 CookedReadData->BytesRead -=
sizeof(WCHAR);
00958 *CookedReadData->BufPtr=(WCHAR)
' ';
00959 CookedReadData->BufPtr-=1;
00960 CookedReadData->CurrentPosition-=1;
00961
00962
00963
if (
gExtendedEditKey &&
00964 wchOrig == EXTKEY_ERASE_PREV_WORD &&
00965 CookedReadData->BufPtr != CookedReadData->BackupLimit &&
00966 fStartFromDelim ^ !
IS_WORD_DELIM(CookedReadData->BufPtr[-1])) {
00967
goto eol_repeat;
00968 }
00969 }
00970
else {
00971 *CookedReadData->BufPtr = Char;
00972 CookedReadData->BytesRead +=
sizeof(WCHAR);
00973 CookedReadData->BufPtr+=1;
00974 CookedReadData->CurrentPosition+=1;
00975 }
00976 }
00977 }
else {
00978
BOOL CallWrite=
TRUE;
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
if (Char ==
UNICODE_BACKSPACE && CookedReadData->Processed) {
00992
00993
00994
00995
00996
00997
00998
if (CookedReadData->BufPtr != CookedReadData->BackupLimit) {
00999
01000 fStartFromDelim =
gExtendedEditKey &&
IS_WORD_DELIM(CookedReadData->BufPtr[-1]);
01001
01002 bs_repeat:
01003
01004
01005
01006
01007
01008
01009
01010
if (CookedReadData->Echo) {
01011 NumToWrite=
sizeof(WCHAR);
01012 *
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
01013 CookedReadData->BackupLimit,
01014 CookedReadData->BufPtr,
01015 &Char,
01016 &NumToWrite,
01017
NULL,
01018 CookedReadData->OriginalCursorPosition.X,
01019
WC_DESTRUCTIVE_BACKSPACE |
01020
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
01021
NULL);
01022
01023
if (!
NT_SUCCESS(*
Status)) {
01024 RIPMSG1(RIP_WARNING,
"WriteCharsFromInput failed %x", *
Status);
01025 }
01026 }
01027 CookedReadData->BytesRead -=
sizeof(WCHAR);
01028 CookedReadData->BufPtr-=1;
01029 CookedReadData->CurrentPosition-=1;
01030 RtlCopyMemory(CookedReadData->BufPtr,
01031 CookedReadData->BufPtr+1,
01032 CookedReadData->BytesRead - (CookedReadData->CurrentPosition *
sizeof(WCHAR))
01033 );
01034
#if defined(FE_SB)
01035
{
01036 PWCHAR buf = (PWCHAR)((
PBYTE)CookedReadData->BackupLimit +
01037 CookedReadData->BytesRead );
01038 *buf = (WCHAR)
' ';
01039 }
01040
#endif
01041
NumSpaces = 0;
01042
01043
01044
if (
gExtendedEditKey &&
01045 wchOrig == EXTKEY_ERASE_PREV_WORD &&
01046 CookedReadData->BufPtr != CookedReadData->BackupLimit &&
01047 fStartFromDelim ^ !
IS_WORD_DELIM(CookedReadData->BufPtr[-1])) {
01048
goto bs_repeat;
01049 }
01050 }
else {
01051 CallWrite =
FALSE;
01052 }
01053 }
else {
01054
01055
01056
01057
01058
01059
if (Char ==
UNICODE_CARRIAGERETURN) {
01060 CookedReadData->BufPtr = (PWCHAR)((
PBYTE)CookedReadData->BackupLimit + CookedReadData->BytesRead);
01061 *CookedReadData->BufPtr = Char;
01062 CookedReadData->BufPtr+=1;
01063 CookedReadData->BytesRead +=
sizeof(WCHAR);
01064 CookedReadData->CurrentPosition += 1;
01065 }
else {
01066
#if defined(FE_SB)
01067
BOOL fBisect =
FALSE;
01068
if (CookedReadData->Echo) {
01069
if (CheckBisectProcessW(CookedReadData->ScreenInfo,
01070 CookedReadData->ScreenInfo->Console->CP,
01071 CookedReadData->BackupLimit,
01072 CookedReadData->CurrentPosition+1,
01073 CookedReadData->ScreenInfo->ScreenBufferSize.X
01074 -CookedReadData->OriginalCursorPosition.X,
01075 CookedReadData->OriginalCursorPosition.X,
01076
TRUE)) {
01077 fBisect =
TRUE;
01078 }
01079 }
01080
#endif
01081
if (
INSERT_MODE(CookedReadData)) {
01082 memmove(CookedReadData->BufPtr+1,
01083 CookedReadData->BufPtr,
01084 CookedReadData->BytesRead - (CookedReadData->CurrentPosition *
sizeof(WCHAR))
01085 );
01086 CookedReadData->BytesRead +=
sizeof(WCHAR);
01087 }
01088 *CookedReadData->BufPtr = Char;
01089 CookedReadData->BufPtr+=1;
01090 CookedReadData->CurrentPosition += 1;
01091
01092
01093
01094
01095
01096
if (CookedReadData->Echo) {
01097 NumSpaces =
RetrieveNumberOfSpaces(CookedReadData->OriginalCursorPosition.X,
01098 CookedReadData->BackupLimit,
01099 CookedReadData->CurrentPosition-1
01100 #
if defined(FE_SB)
01101 ,
01102 CookedReadData->ScreenInfo->Console,
01103 CookedReadData->ScreenInfo->Console->CP
01104 #endif
01105 );
01106
#if defined(FE_SB)
01107
if (NumSpaces > 0 && fBisect)
01108 NumSpaces--;
01109
#endif
01110
}
01111 }
01112 }
01113
01114
if (CookedReadData->Echo && CallWrite) {
01115
01116 COORD CursorPosition;
01117
01118
01119
01120
01121
01122 CursorPosition = CookedReadData->ScreenInfo->BufferInfo.TextInfo.CursorPosition;
01123 CursorPosition.X = (
SHORT)(CursorPosition.X+NumSpaces);
01124
01125
01126
01127
01128
01129
DeleteCommandLine(CookedReadData,
01130
FALSE);
01131
01132
01133
01134
01135
01136 NumToWrite = CookedReadData->BytesRead;
01137 *
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
01138 CookedReadData->BackupLimit,
01139 CookedReadData->BackupLimit,
01140 CookedReadData->BackupLimit,
01141 &NumToWrite,
01142 (PLONG)&CookedReadData->NumberOfVisibleChars,
01143 CookedReadData->OriginalCursorPosition.X,
01144 (Char !=
UNICODE_CARRIAGERETURN) ?
01145
WC_DESTRUCTIVE_BACKSPACE |
WC_ECHO :
01146
WC_DESTRUCTIVE_BACKSPACE |
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
01147 &ScrollY
01148 );
01149
if (!
NT_SUCCESS(*
Status)) {
01150 RIPMSG1(RIP_WARNING,
"WriteCharsFromInput failed %x", *
Status);
01151 CookedReadData->BytesRead = 0;
01152
return TRUE;
01153 }
01154
01155
01156
01157
01158
01159
if (Char !=
UNICODE_CARRIAGERETURN) {
01160
#if defined(FE_SB)
01161
if (CheckBisectProcessW(CookedReadData->ScreenInfo,
01162 CookedReadData->ScreenInfo->Console->CP,
01163 CookedReadData->BackupLimit,
01164 CookedReadData->CurrentPosition+1,
01165 CookedReadData->ScreenInfo->ScreenBufferSize.X
01166 -CookedReadData->OriginalCursorPosition.X,
01167 CookedReadData->OriginalCursorPosition.X,
01168
TRUE)) {
01169
if (CursorPosition.X == (CookedReadData->ScreenInfo->ScreenBufferSize.X-1))
01170 CursorPosition.X++;
01171 }
01172
#endif
01173
01174
01175 CookedReadData->OriginalCursorPosition.Y += ScrollY;
01176 CursorPosition.Y += ScrollY;
01177 *
Status =
AdjustCursorPosition(CookedReadData->ScreenInfo,
01178 CursorPosition,
01179
TRUE,
01180
NULL);
01181
ASSERT(
NT_SUCCESS(*
Status));
01182
if (!
NT_SUCCESS(*
Status)) {
01183 CookedReadData->BytesRead = 0;
01184
return TRUE;
01185 }
01186 }
01187 }
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
if (Char ==
UNICODE_CARRIAGERETURN) {
01197
if (CookedReadData->Processed) {
01198
if (CookedReadData->BytesRead < CookedReadData->BufferSize) {
01199 *CookedReadData->BufPtr =
UNICODE_LINEFEED;
01200
if (CookedReadData->Echo) {
01201 NumToWrite=
sizeof(WCHAR);
01202 *
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
01203 CookedReadData->BackupLimit,
01204 CookedReadData->BufPtr,
01205 CookedReadData->BufPtr,
01206 &NumToWrite,
01207
NULL,
01208 CookedReadData->OriginalCursorPosition.X,
01209
WC_DESTRUCTIVE_BACKSPACE |
01210
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
01211
NULL);
01212
01213
if (!
NT_SUCCESS(*
Status)) {
01214 RIPMSG1(RIP_WARNING,
"WriteCharsFromInput failed %x", *
Status);
01215 }
01216 }
01217 CookedReadData->BytesRead +=
sizeof(WCHAR);
01218 CookedReadData->BufPtr++;
01219 CookedReadData->CurrentPosition += 1;
01220 }
01221 }
01222
01223
01224
01225
if (CookedReadData->Line) {
01226
if (CookedReadData->InsertMode != CookedReadData->Console->InsertMode) {
01227
ProcessCommandLine(CookedReadData,VK_INSERT,0,
NULL,
NULL,
FALSE);
01228 }
01229 *
Status = STATUS_SUCCESS;
01230
return TRUE;
01231 }
01232 }
01233
return FALSE;
01234 }
01235
01236
NTSTATUS
01237 CookedRead(
01238 IN
PCOOKED_READ_DATA CookedReadData,
01239 IN PCSR_API_MSG WaitReplyMessage,
01240 IN PCSR_THREAD WaitingThread,
01241 IN BOOLEAN WaitRoutine
01242 )
01243 {
01244 WCHAR Char;
01245 BOOLEAN CommandLineEditingKeys,EnableScrollMode;
01246
DWORD KeyState;
01247
NTSTATUS Status=STATUS_SUCCESS;
01248
PCONSOLE_READCONSOLE_MSG a;
01249
PHANDLE_DATA HandleData;
01250
#ifdef FE_SB
01251
DWORD NumBytes;
01252 ULONG NumToWrite;
01253
BOOL fAddDbcsLead =
FALSE;
01254
#endif
01255
01256
Status =
DereferenceIoHandleNoCheck(CookedReadData->ProcessData,
01257 CookedReadData->HandleIndex,
01258 &HandleData
01259 );
01260
ASSERT (
NT_SUCCESS(
Status));
01261 a = (
PCONSOLE_READCONSOLE_MSG)&WaitReplyMessage->u.ApiMessageData;
01262
while (CookedReadData->BytesRead < CookedReadData->BufferSize) {
01263
01264
01265
01266
01267
01268
Status =
GetChar(CookedReadData->InputInfo,
01269 &Char,
01270
TRUE,
01271 CookedReadData->Console,
01272 HandleData,
01273 WaitReplyMessage,
01274
CookedReadWaitRoutine,
01275 CookedReadData,
01276
sizeof(*CookedReadData),
01277 WaitRoutine,
01278 &CommandLineEditingKeys,
01279
NULL,
01280 &EnableScrollMode,
01281 &KeyState
01282 );
01283
if (!
NT_SUCCESS(
Status)) {
01284
if (
Status !=
CONSOLE_STATUS_WAIT) {
01285 CookedReadData->BytesRead = 0;
01286 }
01287
break;
01288 }
01289
01290
01291
01292
01293
01294
01295
01296
if (CookedReadData->OriginalCursorPosition.X == -1) {
01297 CookedReadData->OriginalCursorPosition = CookedReadData->ScreenInfo->BufferInfo.TextInfo.CursorPosition;
01298 }
01299
01300
if (CommandLineEditingKeys) {
01301
Status =
ProcessCommandLine(CookedReadData,Char,KeyState,WaitReplyMessage,WaitingThread,WaitRoutine);
01302
if (
Status ==
CONSOLE_STATUS_READ_COMPLETE ||
01303
Status ==
CONSOLE_STATUS_WAIT) {
01304
break;
01305 }
01306
if (!
NT_SUCCESS(
Status)) {
01307
if (
Status ==
CONSOLE_STATUS_WAIT_NO_BLOCK) {
01308
Status =
CONSOLE_STATUS_WAIT;
01309
if (!WaitRoutine) {
01310
01311
01312
01313
WaitForMoreToRead(CookedReadData->InputInfo,
01314 WaitReplyMessage,
01315
CookedReadWaitRoutine,
01316 CookedReadData,
01317
sizeof(*CookedReadData),
01318
FALSE
01319 );
01320 }
01321 }
else {
01322 CookedReadData->BytesRead = 0;
01323 }
01324
break;
01325 }
01326 }
else {
01327
if (
ProcessCookedReadInput(CookedReadData,
01328 Char,
01329 KeyState,
01330 &
Status
01331 )) {
01332 CookedReadData->Console->Flags |=
CONSOLE_IGNORE_NEXT_KEYUP;
01333
break;
01334 }
01335 }
01336 }
01337
01338
01339
01340
01341
01342
01343
01344
if (
Status !=
CONSOLE_STATUS_WAIT) {
01345
01346
DWORD LineCount=1;
01347
if (CookedReadData->Echo) {
01348 BOOLEAN FoundCR;
01349 ULONG i,
StringLength;
01350 PWCHAR StringPtr;
01351
01352
01353
01354
01355 StringPtr = CookedReadData->BackupLimit;
01356
StringLength = CookedReadData->BytesRead;
01357 FoundCR =
FALSE;
01358
for (i=0;i<(CookedReadData->BytesRead/
sizeof(WCHAR));i++) {
01359
if (*StringPtr++ ==
UNICODE_CARRIAGERETURN) {
01360
StringLength = i*
sizeof(WCHAR);
01361 FoundCR =
TRUE;
01362
break;
01363 }
01364 }
01365
01366
if (FoundCR) {
01367
01368
01369
01370
01371
AddCommand(CookedReadData->CommandHistory,CookedReadData->BackupLimit,(
USHORT)
StringLength,CookedReadData->Console->Flags &
CONSOLE_HISTORY_NODUP);
01372
01373
01374
01375
01376
01377 i = CookedReadData->BufferSize;
01378
if (
NT_SUCCESS(
MatchandCopyAlias(CookedReadData->Console,
01379 CookedReadData->BackupLimit,
01380 (
USHORT)
StringLength,
01381 CookedReadData->BackupLimit,
01382 (
PUSHORT)&i,
01383 CookedReadData->ExeName,
01384 CookedReadData->ExeNameLength,
01385 &LineCount
01386 ))) {
01387 CookedReadData->BytesRead = i;
01388 }
01389 }
01390
01391
CloseOutputHandle(
CONSOLE_FROMTHREADPERPROCESSDATA(WaitingThread),
01392 CookedReadData->Console,
01393 &CookedReadData->TempHandle,
01394
NULL,
01395
FALSE
01396 );
01397 }
01398 WaitReplyMessage->ReturnValue =
Status;
01399
01400
01401
01402
01403
01404
01405
01406
if (CookedReadData->BytesRead > CookedReadData->UserBufferSize || LineCount > 1) {
01407
if (LineCount > 1) {
01408 PWSTR Tmp;
01409 HandleData->
InputReadData->
InputHandleFlags |=
HANDLE_MULTI_LINE_INPUT;
01410
#ifdef FE_SB
01411
if (!a->
Unicode && CONSOLE_IS_DBCS_CP(CookedReadData->Console)) {
01412
if (HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar) {
01413 fAddDbcsLead =
TRUE;
01414 *CookedReadData->UserBuffer++ = HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar;
01415 CookedReadData->UserBufferSize-=
sizeof(WCHAR);
01416 RtlZeroMemory(&HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte,
sizeof(INPUT_RECORD));
01417 }
01418 NumBytes = 0;
01419
for (Tmp=CookedReadData->BackupLimit;
01420 *Tmp!=
UNICODE_LINEFEED && CookedReadData->UserBufferSize/
sizeof(WCHAR) > NumBytes;
01421 (IsConsoleFullWidth(CookedReadData->Console->hDC,
01422 CookedReadData->Console->CP,*Tmp) ? NumBytes+=2 : NumBytes++),Tmp++) ;
01423 }
01424
#endif
01425
for (Tmp=CookedReadData->BackupLimit;*Tmp!=
UNICODE_LINEFEED;Tmp++)
01426
ASSERT(Tmp<(CookedReadData->BackupLimit+CookedReadData->BytesRead));
01427 a->
NumBytes = (ULONG)(Tmp-CookedReadData->BackupLimit+1)*
sizeof(*Tmp);
01428 }
else {
01429
#ifdef FE_SB
01430
if (!a->
Unicode && CONSOLE_IS_DBCS_CP(CookedReadData->Console)) {
01431 PWSTR Tmp;
01432
01433
if (HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar) {
01434 fAddDbcsLead =
TRUE;
01435 *CookedReadData->UserBuffer++ = HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar;
01436 CookedReadData->UserBufferSize-=
sizeof(WCHAR);
01437 RtlZeroMemory(&HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte,
sizeof(INPUT_RECORD));
01438 }
01439 NumBytes = 0;
01440 NumToWrite = CookedReadData->BytesRead;
01441
for (Tmp=CookedReadData->BackupLimit;
01442 NumToWrite && CookedReadData->UserBufferSize/
sizeof(WCHAR) > NumBytes;
01443 (IsConsoleFullWidth(CookedReadData->Console->hDC,
01444 CookedReadData->Console->CP,*Tmp) ? NumBytes+=2 : NumBytes++),Tmp++,NumToWrite-=
sizeof(WCHAR)) ;
01445 }
01446
#endif
01447
a->
NumBytes = CookedReadData->UserBufferSize;
01448 }
01449 HandleData->
InputReadData->
InputHandleFlags |=
HANDLE_INPUT_PENDING;
01450 HandleData->
InputReadData->
BufPtr = CookedReadData->BackupLimit;
01451 HandleData->
InputReadData->
BytesAvailable = CookedReadData->BytesRead - a->
NumBytes;
01452 HandleData->
InputReadData->
CurrentBufPtr=(PWCHAR)((
PBYTE)CookedReadData->BackupLimit+a->
NumBytes);
01453 RtlCopyMemory(CookedReadData->UserBuffer,CookedReadData->BackupLimit,a->
NumBytes);
01454 }
01455
else {
01456
#ifdef FE_SB
01457
if (!a->
Unicode && CONSOLE_IS_DBCS_CP(CookedReadData->Console)) {
01458 PWSTR Tmp;
01459
01460
if (HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar) {
01461 fAddDbcsLead =
TRUE;
01462 *CookedReadData->UserBuffer++ = HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar;
01463 CookedReadData->UserBufferSize-=
sizeof(WCHAR);
01464 RtlZeroMemory(&HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte,
sizeof(INPUT_RECORD));
01465
01466
if (CookedReadData->UserBufferSize == 0) {
01467 a->
NumBytes = 1;
01468
ConsoleHeapFree(CookedReadData->BackupLimit);
01469
return STATUS_SUCCESS;
01470 }
01471 }
01472 NumBytes = 0;
01473 NumToWrite = CookedReadData->BytesRead;
01474
for (Tmp=CookedReadData->BackupLimit;
01475 NumToWrite && CookedReadData->UserBufferSize/
sizeof(WCHAR) > NumBytes;
01476 (IsConsoleFullWidth(CookedReadData->Console->hDC,
01477 CookedReadData->Console->CP,*Tmp) ? NumBytes+=2 : NumBytes++),Tmp++,NumToWrite-=
sizeof(WCHAR)) ;
01478 }
01479
#endif
01480
a->
NumBytes = CookedReadData->BytesRead;
01481 RtlCopyMemory(CookedReadData->UserBuffer,CookedReadData->BackupLimit,a->
NumBytes);
01482
ConsoleHeapFree(CookedReadData->BackupLimit);
01483 }
01484 a->
ControlKeyState = CookedReadData->ControlKeyState;
01485
01486
if (!a->
Unicode) {
01487
01488
01489
01490
01491
01492 PCHAR TransBuffer;
01493
01494
#ifdef FE_SB
01495
if (CONSOLE_IS_DBCS_CP(CookedReadData->Console))
01496 TransBuffer = (PCHAR)
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),NumBytes);
01497
else
01498
#endif
01499
TransBuffer = (PCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),a->
NumBytes /
sizeof(WCHAR));
01500
if (TransBuffer ==
NULL) {
01501
return STATUS_NO_MEMORY;
01502 }
01503
01504
#ifdef FE_SB
01505
if (CONSOLE_IS_DBCS_CP(CookedReadData->Console))
01506 {
01507 a->
NumBytes =
TranslateUnicodeToOem(CookedReadData->Console,
01508 CookedReadData->UserBuffer,
01509 a->
NumBytes / sizeof (WCHAR),
01510 TransBuffer,
01511 NumBytes,
01512 &HandleData->
Buffer.InputBuffer->ReadConInpDbcsLeadByte);
01513 }
01514
else
01515
#endif
01516
a->
NumBytes =
ConvertToOem(CookedReadData->Console->CP,
01517 CookedReadData->UserBuffer,
01518 a->
NumBytes / sizeof (WCHAR),
01519 TransBuffer,
01520 a->
NumBytes / sizeof (WCHAR)
01521 );
01522 RtlCopyMemory(CookedReadData->UserBuffer,TransBuffer,a->
NumBytes);
01523
#ifdef FE_SB
01524
if (fAddDbcsLead)
01525 a->
NumBytes++;
01526
#endif
01527
ConsoleHeapFree(TransBuffer);
01528 }
01529
ConsoleHeapFree(CookedReadData->ExeName);
01530
if (WaitRoutine) {
01531
#ifdef FE_SB
01532
CookedReadData->Console->lpCookedReadData =
NULL;
01533
#endif
01534
ConsoleHeapFree(CookedReadData);
01535 }
01536 }
01537
return Status;
01538 }
01539
01540 BOOLEAN
01541 CookedReadWaitRoutine(
01542 IN PLIST_ENTRY WaitQueue,
01543 IN PCSR_THREAD WaitingThread,
01544 IN PCSR_API_MSG WaitReplyMessage,
01545 IN PVOID WaitParameter,
01546 IN PVOID SatisfyParameter1,
01547 IN PVOID SatisfyParameter2,
01548 IN ULONG WaitFlags
01549 )
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586 {
01587
NTSTATUS Status;
01588
PCONSOLE_INFORMATION Console;
01589
PCOOKED_READ_DATA CookedReadData;
01590
PCONSOLE_READCONSOLE_MSG a;
01591
PHANDLE_DATA HandleData;
01592
01593 a = (
PCONSOLE_READCONSOLE_MSG)&WaitReplyMessage->u.ApiMessageData;
01594 CookedReadData = (
PCOOKED_READ_DATA)WaitParameter;
01595
01596
Status =
DereferenceIoHandleNoCheck(CookedReadData->
ProcessData,
01597 CookedReadData->
HandleIndex,
01598 &HandleData
01599 );
01600
ASSERT (
NT_SUCCESS(
Status));
01601
ASSERT(!(HandleData->
InputReadData->
InputHandleFlags &
HANDLE_INPUT_PENDING));
01602
01603
01604
01605
01606
01607
01608
01609
if (SatisfyParameter1 !=
NULL &&
01610 SatisfyParameter1 != HandleData) {
01611
01612
return FALSE;
01613 }
01614
01615 Console = CookedReadData->
Console;
01616
01617
01618
01619
01620
01621
01622
LockReadCount(HandleData);
01623
ASSERT(HandleData->
InputReadData->
ReadCount);
01624 HandleData->
InputReadData->
ReadCount -= 1;
01625
UnlockReadCount(HandleData);
01626
01627
01628
01629
01630
01631
if ((ULONG_PTR)SatisfyParameter2 & (
CONSOLE_CTRL_C_SEEN |
CONSOLE_CTRL_BREAK_SEEN)) {
01632
if (CookedReadData->
Echo) {
01633
CloseOutputHandle(
CONSOLE_FROMTHREADPERPROCESSDATA(WaitingThread),
01634 CookedReadData->
Console,
01635 &CookedReadData->
TempHandle,
01636
NULL,
01637
FALSE
01638 );
01639 }
01640
01641 WaitReplyMessage->ReturnValue = STATUS_ALERTED;
01642
ConsoleHeapFree(CookedReadData->
BackupLimit);
01643
ConsoleHeapFree(CookedReadData->
ExeName);
01644
#if defined(FE_SB)
01645
CookedReadData->
Console->lpCookedReadData =
NULL;
01646
#endif
01647
ConsoleHeapFree(CookedReadData);
01648
return TRUE;
01649 }
01650
01651
01652
01653
01654
01655
01656
01657
if (WaitFlags & CSR_PROCESS_TERMINATING) {
01658
if (CookedReadData->
Echo) {
01659
CloseOutputHandle(
CONSOLE_FROMTHREADPERPROCESSDATA(WaitingThread),
01660 CookedReadData->
Console,
01661 &CookedReadData->
TempHandle,
01662
NULL,
01663
FALSE
01664 );
01665 }
01666
01667 WaitReplyMessage->ReturnValue = (ULONG)STATUS_THREAD_IS_TERMINATING;
01668
01669
01670
01671
01672
01673
CleanUpPopups(CookedReadData);
01674
ConsoleHeapFree(CookedReadData->
BackupLimit);
01675
ConsoleHeapFree(CookedReadData->
ExeName);
01676
#if defined(FE_SB)
01677
CookedReadData->
Console->lpCookedReadData =
NULL;
01678
#endif
01679
ConsoleHeapFree(CookedReadData);
01680
return TRUE;
01681 }
01682
01683
01684
01685
01686
01687
01688
01689
01690
if (HandleData->
InputReadData->
InputHandleFlags &
HANDLE_CLOSING) {
01691
ASSERT (SatisfyParameter1 == HandleData);
01692
if (CookedReadData->
Echo) {
01693
CloseOutputHandle(
CONSOLE_FROMTHREADPERPROCESSDATA(WaitingThread),
01694 CookedReadData->
Console,
01695 &CookedReadData->
TempHandle,
01696
NULL,
01697
FALSE
01698 );
01699 }
01700
01701 WaitReplyMessage->ReturnValue = STATUS_ALERTED;
01702
01703
01704
01705
01706
01707
CleanUpPopups(CookedReadData);
01708
ConsoleHeapFree(CookedReadData->
BackupLimit);
01709
ConsoleHeapFree(CookedReadData->
ExeName);
01710
#if defined(FE_SB)
01711
CookedReadData->
Console->lpCookedReadData =
NULL;
01712
#endif
01713
ConsoleHeapFree(CookedReadData);
01714
return TRUE;
01715 }
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
ASSERT (
ConsoleLocked(Console));
01729
01730
if (CookedReadData->
CommandHistory) {
01731
PCLE_POPUP Popup;
01732
if (!
CLE_NO_POPUPS(CookedReadData->
CommandHistory)) {
01733 Popup = CONTAINING_RECORD( CookedReadData->
CommandHistory->
PopupList.Flink,
CLE_POPUP, ListLink );
01734
Status = (Popup->
PopupInputRoutine)(CookedReadData,
01735 WaitReplyMessage,
01736 WaitingThread,
01737
TRUE);
01738
if (
Status ==
CONSOLE_STATUS_READ_COMPLETE ||
01739 (
Status !=
CONSOLE_STATUS_WAIT &&
01740
Status !=
CONSOLE_STATUS_WAIT_NO_BLOCK) ) {
01741
ConsoleHeapFree(CookedReadData->
BackupLimit);
01742
ConsoleHeapFree(CookedReadData->
ExeName);
01743
#if defined(FE_SB)
01744
CookedReadData->
Console->lpCookedReadData =
NULL;
01745
#endif
01746
ConsoleHeapFree(CookedReadData);
01747
return TRUE;
01748 }
01749
return FALSE;
01750 }
01751 }
01752
if (a->
CaptureBufferSize <=
BUFFER_SIZE &&
01753 CookedReadData->
BytesRead == 0) {
01754 CookedReadData->
UserBuffer = a->
Buffer;
01755 }
01756
Status =
CookedRead(CookedReadData,
01757 WaitReplyMessage,
01758 WaitingThread,
01759
TRUE
01760 );
01761
01762
if (
Status !=
CONSOLE_STATUS_WAIT) {
01763
return TRUE;
01764 }
else {
01765
return FALSE;
01766 }
01767
01768
01769
01770
01771
01772 UNREFERENCED_PARAMETER(WaitQueue);
01773 UNREFERENCED_PARAMETER(SatisfyParameter2);
01774 }
01775
01776
01777
NTSTATUS
01778 ReadChars(
01779 IN
PINPUT_INFORMATION InputInfo,
01780 IN
PCONSOLE_INFORMATION Console,
01781 IN
PCONSOLE_PER_PROCESS_DATA ProcessData,
01782 IN
PSCREEN_INFORMATION ScreenInfo,
01783 IN OUT PWCHAR lpBuffer,
01784 IN OUT PDWORD NumBytes,
01785 IN DWORD InitialNumBytes,
01786 IN DWORD CtrlWakeupMask,
01787 IN
PHANDLE_DATA HandleData,
01788 IN
PCOMMAND_HISTORY CommandHistory,
01789 IN PCSR_API_MSG Message OPTIONAL,
01790 IN HANDLE HandleIndex,
01791 IN USHORT ExeNameLength,
01792 IN PWCHAR ExeName,
01793 IN BOOLEAN Unicode
01794 )
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823 {
01824
DWORD BufferSize;
01825
NTSTATUS Status;
01826
HANDLE_DATA TempHandle;
01827 BOOLEAN
Echo =
FALSE;
01828 ULONG NumToWrite;
01829
#ifdef FE_SB
01830
PCONSOLE_READCONSOLE_MSG a = (
PCONSOLE_READCONSOLE_MSG)&Message->u.ApiMessageData;
01831
BOOL fAddDbcsLead =
FALSE;
01832 ULONG NumToBytes;
01833
#endif
01834
01835
BufferSize = *NumBytes;
01836 *NumBytes = 0;
01837
01838
if (HandleData->InputReadData->InputHandleFlags &
HANDLE_INPUT_PENDING) {
01839
01840
01841
01842
01843
01844
01845
01846
if (HandleData->InputReadData->InputHandleFlags &
HANDLE_MULTI_LINE_INPUT) {
01847 PWSTR Tmp;
01848
#ifdef FE_SB
01849
if (!
Unicode && CONSOLE_IS_DBCS_CP(Console)) {
01850
01851
if (HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar) {
01852 fAddDbcsLead =
TRUE;
01853 *lpBuffer++ = HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar;
01854
BufferSize--;
01855 HandleData->InputReadData->BytesAvailable--;
01856 RtlZeroMemory(&HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte,
sizeof(INPUT_RECORD));
01857 }
01858
if (HandleData->InputReadData->BytesAvailable == 0 ||
01859
BufferSize == 0) {
01860 HandleData->InputReadData->InputHandleFlags &= ~(
HANDLE_INPUT_PENDING |
HANDLE_MULTI_LINE_INPUT);
01861
ConsoleHeapFree(HandleData->InputReadData->BufPtr);
01862 *NumBytes = 1;
01863
return STATUS_SUCCESS;
01864 }
01865
else {
01866
for (NumToWrite=0,Tmp=HandleData->InputReadData->CurrentBufPtr,NumToBytes=0;
01867 NumToBytes < HandleData->InputReadData->BytesAvailable && NumToBytes <
BufferSize/
sizeof(WCHAR) && *Tmp!=
UNICODE_LINEFEED;
01868 (IsConsoleFullWidth(Console->hDC,
01869 Console->CP,*Tmp) ? NumToBytes+=2 : NumToBytes++),Tmp++,NumToWrite+=
sizeof(WCHAR)) ;
01870 }
01871 }
01872
#endif
01873
for (NumToWrite=0,Tmp=HandleData->InputReadData->CurrentBufPtr;
01874 NumToWrite < HandleData->InputReadData->BytesAvailable && *Tmp!=
UNICODE_LINEFEED;
01875 Tmp++,NumToWrite+=
sizeof(WCHAR)) ;
01876 NumToWrite +=
sizeof(WCHAR);
01877
if (NumToWrite >
BufferSize) {
01878 NumToWrite =
BufferSize;
01879 }
01880 }
else {
01881
#ifdef FE_SB
01882
if (!
Unicode && CONSOLE_IS_DBCS_CP(Console)) {
01883 PWSTR Tmp;
01884
01885
if (HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar) {
01886 fAddDbcsLead =
TRUE;
01887 *lpBuffer++ = HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar;
01888
BufferSize-=
sizeof(WCHAR);
01889 HandleData->InputReadData->BytesAvailable-=
sizeof(WCHAR);
01890 RtlZeroMemory(&HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte,
sizeof(INPUT_RECORD));
01891 }
01892
if (HandleData->InputReadData->BytesAvailable == 0) {
01893 HandleData->InputReadData->InputHandleFlags &= ~(
HANDLE_INPUT_PENDING |
HANDLE_MULTI_LINE_INPUT);
01894
ConsoleHeapFree(HandleData->InputReadData->BufPtr);
01895 *NumBytes = 1;
01896
return STATUS_SUCCESS;
01897 }
01898
else {
01899
for (NumToWrite=0,Tmp=HandleData->InputReadData->CurrentBufPtr,NumToBytes=0;
01900 NumToBytes < HandleData->InputReadData->BytesAvailable && NumToBytes <
BufferSize/
sizeof(WCHAR);
01901 (IsConsoleFullWidth(Console->hDC,
01902 Console->CP,*Tmp) ? NumToBytes+=2 : NumToBytes++),Tmp++,NumToWrite+=
sizeof(WCHAR)) ;
01903 }
01904 }
01905
#endif
01906
NumToWrite = (
BufferSize < HandleData->InputReadData->BytesAvailable) ?
01907
BufferSize : HandleData->InputReadData->BytesAvailable;
01908 }
01909 RtlCopyMemory(lpBuffer,HandleData->InputReadData->CurrentBufPtr,NumToWrite);
01910 HandleData->InputReadData->BytesAvailable-= NumToWrite;
01911
if (HandleData->InputReadData->BytesAvailable == 0) {
01912 HandleData->InputReadData->InputHandleFlags &= ~(
HANDLE_INPUT_PENDING |
HANDLE_MULTI_LINE_INPUT);
01913
ConsoleHeapFree(HandleData->InputReadData->BufPtr);
01914 }
01915
else {
01916 HandleData->InputReadData->CurrentBufPtr=(PWCHAR)((
PBYTE)HandleData->InputReadData->CurrentBufPtr+NumToWrite);
01917 }
01918
if (!
Unicode) {
01919
01920
01921
01922
01923
01924
01925 PCHAR TransBuffer;
01926
01927
#ifdef FE_SB
01928
if (CONSOLE_IS_DBCS_CP(Console))
01929 TransBuffer = (PCHAR)
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),NumToBytes);
01930
else
01931
#endif
01932
TransBuffer = (PCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),NumToWrite /
sizeof(WCHAR));
01933
if (TransBuffer ==
NULL) {
01934
return STATUS_NO_MEMORY;
01935 }
01936
01937
#ifdef FE_SB
01938
if (CONSOLE_IS_DBCS_CP(Console))
01939 {
01940 NumToWrite =
TranslateUnicodeToOem(Console,
01941 lpBuffer,
01942 NumToWrite /
sizeof (WCHAR),
01943 TransBuffer,
01944 NumToBytes,
01945 &HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte);
01946 }
01947
else
01948
#endif
01949
NumToWrite =
ConvertToOem(Console->CP,
01950 lpBuffer,
01951 NumToWrite / sizeof (WCHAR),
01952 TransBuffer,
01953 NumToWrite /
sizeof (WCHAR)
01954 );
01955 RtlCopyMemory(lpBuffer,TransBuffer,NumToWrite);
01956
#ifdef FE_SB
01957
if (fAddDbcsLead)
01958 NumToWrite++;
01959
#endif
01960
ConsoleHeapFree(TransBuffer);
01961 }
01962 *NumBytes = NumToWrite;
01963
return STATUS_SUCCESS;
01964 }
01965
01966
01967
01968
01969
01970
01971
if ((InputInfo->InputMode & (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) ==
01972 (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) {
01973 HANDLE ActiveScreenHandle;
01974
01975
Echo =
FALSE;
01976 ActiveScreenHandle =
FindActiveScreenBufferHandle(ProcessData,Console);
01977
if (ActiveScreenHandle !=
INVALID_HANDLE_VALUE) {
01978 TempHandle.
HandleType =
CONSOLE_OUTPUT_HANDLE;
01979 TempHandle.
Buffer.ScreenBuffer = Console->CurrentScreenBuffer;
01980
if (TempHandle.
Buffer.ScreenBuffer !=
NULL) {
01981
Status =
ConsoleAddShare(GENERIC_WRITE,
01982 FILE_SHARE_READ | FILE_SHARE_WRITE,
01983 &TempHandle.
Buffer.ScreenBuffer->ShareAccess,
01984 &TempHandle
01985 );
01986
if (
NT_SUCCESS(
Status)) {
01987
Echo =
TRUE;
01988 TempHandle.
Buffer.ScreenBuffer->RefCount++;
01989 }
01990 }
01991 }
01992 }
01993
01994
if (InputInfo->InputMode & ENABLE_LINE_INPUT) {
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
COOKED_READ_DATA CookedReadData;
02006 ULONG i;
02007 PWCHAR TempBuffer;
02008 ULONG TempBufferSize;
02009
02010
02011
02012
02013
02014
02015
02016 TempBufferSize = (
BufferSize <
LINE_INPUT_BUFFER_SIZE) ?
LINE_INPUT_BUFFER_SIZE :
BufferSize;
02017 TempBuffer = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),TempBufferSize);
02018
if (TempBuffer==
NULL) {
02019
if (
Echo) {
02020
CloseOutputHandle(ProcessData,
02021 Console,
02022 &TempHandle,
02023
NULL,
02024
FALSE
02025 );
02026 }
02027
return STATUS_NO_MEMORY;
02028 }
02029
02030
02031
02032
02033
02034
02035
for (i=0;i<TempBufferSize/
sizeof(WCHAR);i++) {
02036 TempBuffer[i] = (WCHAR)
' ';
02037 }
02038
02039 CookedReadData.
InputInfo = InputInfo;
02040 CookedReadData.
ScreenInfo = ScreenInfo;
02041 CookedReadData.
Console = Console;
02042 CookedReadData.
TempHandle.
HandleType = TempHandle.
HandleType;
02043 CookedReadData.
TempHandle.
Buffer.ScreenBuffer = TempHandle.
Buffer.ScreenBuffer;
02044 CookedReadData.
BufferSize = TempBufferSize;
02045 CookedReadData.
BytesRead = 0;
02046 CookedReadData.
CurrentPosition = 0;
02047 CookedReadData.
BufPtr = TempBuffer;
02048 CookedReadData.
BackupLimit = TempBuffer;
02049 CookedReadData.
UserBufferSize =
BufferSize;
02050 CookedReadData.
UserBuffer = lpBuffer;
02051 CookedReadData.
OriginalCursorPosition.X = -1;
02052 CookedReadData.
OriginalCursorPosition.Y = -1;
02053 CookedReadData.
NumberOfVisibleChars = 0;
02054 CookedReadData.
CtrlWakeupMask = CtrlWakeupMask;
02055 CookedReadData.
CommandHistory = CommandHistory;
02056 CookedReadData.
Echo =
Echo;
02057 CookedReadData.
InsertMode = Console->InsertMode;
02058 CookedReadData.
Processed = (InputInfo->InputMode & ENABLE_PROCESSED_INPUT) != 0;
02059 CookedReadData.
Line = (InputInfo->InputMode & ENABLE_LINE_INPUT) != 0;
02060 CookedReadData.
ProcessData = ProcessData;
02061 CookedReadData.
HandleIndex = HandleIndex;
02062 CookedReadData.
ExeName = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
HISTORY_TAG ),
ExeNameLength);
02063
if (InitialNumBytes != 0) {
02064 RtlCopyMemory(CookedReadData.
BufPtr, CookedReadData.
UserBuffer, InitialNumBytes);
02065 CookedReadData.
BytesRead += InitialNumBytes;
02066 CookedReadData.
NumberOfVisibleChars = (InitialNumBytes /
sizeof(WCHAR));
02067 CookedReadData.
BufPtr += (InitialNumBytes /
sizeof(WCHAR));
02068 CookedReadData.
CurrentPosition = (InitialNumBytes /
sizeof(WCHAR));
02069 CookedReadData.
OriginalCursorPosition = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
02070 CookedReadData.
OriginalCursorPosition.X -= (
SHORT)CookedReadData.
CurrentPosition;
02071
02072
02073
while (CookedReadData.
OriginalCursorPosition.X < 0) {
02074 CookedReadData.
OriginalCursorPosition.X += ScreenInfo->ScreenBufferSize.X;
02075 CookedReadData.
OriginalCursorPosition.Y -= 1;
02076 }
02077 }
02078
if (CookedReadData.
ExeName) {
02079 RtlCopyMemory(CookedReadData.
ExeName,ExeName,
ExeNameLength);
02080 CookedReadData.
ExeNameLength =
ExeNameLength;
02081 }
02082
#ifdef FE_SB
02083
Console->lpCookedReadData = (PVOID)&CookedReadData;
02084
#endif
02085
02086
Status =
CookedRead(&CookedReadData,
02087 Message,
02088 CSR_SERVER_QUERYCLIENTTHREAD(),
02089
FALSE
02090 );
02091
#ifdef FE_SB
02092
if (
Status !=
CONSOLE_STATUS_WAIT) {
02093 Console->lpCookedReadData =
NULL;
02094 }
02095
#endif
02096
return Status;
02097 }
02098
02099
02100
02101
02102
02103
else {
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
RAW_READ_DATA RawReadData;
02115
02116 RawReadData.
InputInfo = InputInfo;
02117 RawReadData.
Console = Console;
02118 RawReadData.
BufferSize =
BufferSize;
02119 RawReadData.
BufPtr = lpBuffer;
02120 RawReadData.
ProcessData = ProcessData;
02121 RawReadData.
HandleIndex = HandleIndex;
02122
if (*NumBytes <
BufferSize) {
02123 PWCHAR pwchT;
02124
02125
#ifdef FE_SB
02126
PWCHAR lpBufferTmp = lpBuffer;
02127
02128 NumToWrite = 0;
02129
if (!
Unicode && CONSOLE_IS_DBCS_CP(Console)) {
02130
if (HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar) {
02131 fAddDbcsLead =
TRUE;
02132 *lpBuffer++ = HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte.Event.KeyEvent.uChar.AsciiChar;
02133
BufferSize-=
sizeof(WCHAR);
02134 RtlZeroMemory(&HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte,
sizeof(INPUT_RECORD));
02135
Status = STATUS_SUCCESS;
02136
if (
BufferSize == 0) {
02137 *NumBytes = 1;
02138
return STATUS_SUCCESS;
02139 }
02140 }
02141
else{
02142
Status =
GetChar(InputInfo,
02143 lpBuffer,
02144
TRUE,
02145 Console,
02146 HandleData,
02147 Message,
02148
RawReadWaitRoutine,
02149 &RawReadData,
02150
sizeof(RawReadData),
02151
FALSE,
02152
NULL,
02153
NULL,
02154
NULL,
02155
NULL
02156 );
02157 }
02158 }
02159
else
02160
#endif
02161
Status =
GetChar(InputInfo,
02162 lpBuffer,
02163
TRUE,
02164 Console,
02165 HandleData,
02166 Message,
02167
RawReadWaitRoutine,
02168 &RawReadData,
02169
sizeof(RawReadData),
02170
FALSE,
02171
NULL,
02172
NULL,
02173
NULL,
02174
NULL
02175 );
02176
02177
if (!
NT_SUCCESS(
Status)) {
02178 *NumBytes = 0;
02179
return Status;
02180 }
02181
#ifdef FE_SB
02182
if (! fAddDbcsLead) {
02183 IsConsoleFullWidth(Console->hDC,
02184 Console->CP,*lpBuffer) ? *NumBytes+=2 : ++*NumBytes;
02185 NumToWrite+=
sizeof(WCHAR);
02186 lpBuffer++;
02187 }
02188
if (CONSOLE_IS_DBCS_CP(Console)) {
02189
while (NumToWrite <
BufferSize) {
02190
Status =
GetChar(InputInfo,lpBuffer,
FALSE,
NULL,
NULL,
NULL,
NULL,
NULL,0,
FALSE,
NULL,
NULL,
NULL,
NULL);
02191
if (!
NT_SUCCESS(
Status)) {
02192
return STATUS_SUCCESS;
02193 }
02194 IsConsoleFullWidth(Console->hDC,
02195 Console->CP,*lpBuffer) ? *NumBytes+=2 : ++*NumBytes;
02196 lpBuffer++;
02197 NumToWrite+=
sizeof(WCHAR);
02198 }
02199 }
02200
else{
02201
#endif
02202
pwchT = lpBuffer + 1;
02203 *NumBytes +=
sizeof(WCHAR);
02204
while (*NumBytes <
BufferSize) {
02205
Status =
GetChar(InputInfo,pwchT,
FALSE,
NULL,
NULL,
NULL,
NULL,
NULL,0,
FALSE,
NULL,
NULL,
NULL,
NULL);
02206
if (!
NT_SUCCESS(
Status)) {
02207
break;
02208 }
02209 pwchT++;
02210 *NumBytes +=
sizeof(WCHAR);
02211 }
02212
#ifdef FE_SB
02213
}
02214
#endif
02215
02216
02217
02218
02219
02220
02221
if (!
Unicode) {
02222
02223 PCHAR TransBuffer;
02224
02225 TransBuffer = (PCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),*NumBytes /
sizeof(WCHAR));
02226
if (TransBuffer ==
NULL) {
02227
return STATUS_NO_MEMORY;
02228 }
02229
02230
#ifdef FE_SB
02231
lpBuffer = lpBufferTmp;
02232
if (CONSOLE_IS_DBCS_CP(Console))
02233 {
02234 *NumBytes =
TranslateUnicodeToOem(Console,
02235 lpBuffer,
02236 NumToWrite /
sizeof (WCHAR),
02237 TransBuffer,
02238 *NumBytes,
02239 &HandleData->Buffer.InputBuffer->ReadConInpDbcsLeadByte);
02240 }
02241
else
02242
#endif
02243
*NumBytes =
ConvertToOem(Console->CP,
02244 lpBuffer,
02245 *NumBytes / sizeof (WCHAR),
02246 TransBuffer,
02247 *NumBytes /
sizeof (WCHAR)
02248 );
02249 RtlCopyMemory(lpBuffer,TransBuffer,*NumBytes);
02250
#ifdef FE_SB
02251
if (fAddDbcsLead)
02252 ++*NumBytes;
02253
#endif
02254
ConsoleHeapFree(TransBuffer);
02255 }
02256 }
02257 }
02258
return STATUS_SUCCESS;
02259 }
02260
02261
02262 ULONG
02263 SrvReadConsole(
02264 IN OUT PCSR_API_MSG m,
02265 IN OUT PCSR_REPLY_STATUS ReplyStatus
02266 )
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282 {
02283
PCONSOLE_READCONSOLE_MSG a = (
PCONSOLE_READCONSOLE_MSG)&m->u.ApiMessageData;
02284
PCONSOLE_INFORMATION Console;
02285
PHANDLE_DATA HandleData;
02286
NTSTATUS Status;
02287 PWCHAR
Buffer;
02288
PCONSOLE_PER_PROCESS_DATA ProcessData;
02289
02290
Status =
ApiPreamble(a->
ConsoleHandle,
02291 &Console
02292 );
02293
if (!
NT_SUCCESS(
Status)) {
02294
return Status;
02295 }
02296
02297 ProcessData =
CONSOLE_PERPROCESSDATA();
02298
Status =
DereferenceIoHandle(ProcessData,
02299 a->
InputHandle,
02300
CONSOLE_INPUT_HANDLE,
02301 GENERIC_READ,
02302 &HandleData
02303 );
02304
if (!
NT_SUCCESS(
Status)) {
02305 a->
NumBytes = 0;
02306 }
else {
02307
02308
if (a->
CaptureBufferSize <=
BUFFER_SIZE) {
02309
Buffer = a->
Buffer;
02310 }
02311
else {
02312
Buffer = a->
BufPtr;
02313
if (!CsrValidateMessageBuffer(m, &a->
BufPtr, a->
CaptureBufferSize,
sizeof(
BYTE))) {
02314
UnlockConsole(Console);
02315
return STATUS_INVALID_PARAMETER;
02316 }
02317 }
02318
02319
#if defined(FE_SB)
02320
Console->ReadConInpNumBytesTemp = a->
NumBytes /
sizeof(WCHAR);
02321
#endif
02322
Status =
ReadChars(HandleData->
Buffer.InputBuffer,
02323 Console,
02324 ProcessData,
02325 Console->
CurrentScreenBuffer,
02326
Buffer,
02327 &a->
NumBytes,
02328 a->
InitialNumBytes,
02329 a->
CtrlWakeupMask,
02330 HandleData,
02331
FindCommandHistory(Console,
CONSOLE_CLIENTPROCESSHANDLE()),
02332 m,
02333
HANDLE_TO_INDEX(a->
InputHandle),
02334 a->
ExeNameLength,
02335 a->
Buffer,
02336 a->
Unicode
02337 );
02338
if (
Status ==
CONSOLE_STATUS_WAIT) {
02339 *ReplyStatus = CsrReplyPending;
02340 }
02341 }
02342
UnlockConsole(Console);
02343
return((ULONG)
Status);
02344 }
02345
02346
02347
VOID
02348 MakeCursorVisible(
02349 IN
PSCREEN_INFORMATION ScreenInfo,
02350 IN COORD CursorPosition
02351 )
02352 {
02353 COORD WindowOrigin;
02354
NTSTATUS Status;
02355
02356 WindowOrigin.X = 0;
02357 WindowOrigin.Y = 0;
02358
if (CursorPosition.X > ScreenInfo->Window.Right) {
02359 WindowOrigin.X = CursorPosition.X - ScreenInfo->Window.Right;
02360 }
02361
else if (CursorPosition.X < ScreenInfo->Window.Left) {
02362 WindowOrigin.X = CursorPosition.X - ScreenInfo->Window.Left;
02363 }
02364
if (CursorPosition.Y > ScreenInfo->Window.Bottom) {
02365 WindowOrigin.Y = CursorPosition.Y - ScreenInfo->Window.Bottom;
02366 }
02367
else if (CursorPosition.Y < ScreenInfo->Window.Top) {
02368 WindowOrigin.Y = CursorPosition.Y - ScreenInfo->Window.Top;
02369 }
02370
if (WindowOrigin.X != 0 || WindowOrigin.Y != 0) {
02371
Status =
SetWindowOrigin(ScreenInfo,
02372
FALSE,
02373 WindowOrigin
02374 );
02375
if (!
NT_SUCCESS(
Status)) {
02376
return;
02377 }
02378 }
02379 }
02380
02381 #define WRITE_NO_CR_LF 0
02382 #define WRITE_CR 1
02383 #define WRITE_CR_LF 2
02384 #define WRITE_SPECIAL_CHARS 4
02385 #define WRITE_UNICODE_CRLF 0x000a000d
02386
02387
DWORD
02388 FastStreamWrite(
02389 IN PWCHAR lpString,
02390 IN DWORD NumChars
02391 )
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420 {
02421
DWORD UNALIGNED *Tmp;
02422
register PWCHAR StrPtr=lpString;
02423
while (NumChars) {
02424
if (*StrPtr <
UNICODE_SPACE) {
02425 Tmp = (PDWORD)StrPtr;
02426
if (NumChars == 2 &&
02427 *Tmp ==
WRITE_UNICODE_CRLF) {
02428
return WRITE_CR_LF;
02429 }
else if (NumChars == 1 &&
02430 *StrPtr == (WCHAR)
'\r') {
02431
return WRITE_CR;
02432 }
else {
02433
return WRITE_SPECIAL_CHARS;
02434 }
02435 }
02436 StrPtr++;
02437 NumChars--;
02438 }
02439
return WRITE_NO_CR_LF;
02440 }
02441
02442 VOID UnblockWriteConsole(
02443 IN
PCONSOLE_INFORMATION Console,
02444 IN DWORD Reason)
02445 {
02446 Console->Flags &= ~Reason;
02447
02448
if ((Console->Flags & (
CONSOLE_SUSPENDED |
CONSOLE_SELECTING |
CONSOLE_SCROLLBAR_TRACKING)) == 0) {
02449
02450
02451
02452
if (CsrNotifyWait(&Console->OutputQueue,
TRUE,
NULL,
NULL)) {
02453
02454
ASSERT ((Console->WaitQueue ==
NULL) ||
02455 (Console->WaitQueue == &Console->OutputQueue));
02456 Console->WaitQueue = &Console->OutputQueue;
02457 }
02458 }
02459 }
02460
02461
02462 ULONG
02463 SrvWriteConsole(
02464 IN OUT PCSR_API_MSG m,
02465 IN OUT PCSR_REPLY_STATUS ReplyStatus
02466 )
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482 {
02483
NTSTATUS Status;
02484
PCONSOLE_WRITECONSOLE_MSG a = (
PCONSOLE_WRITECONSOLE_MSG)&m->u.ApiMessageData;
02485
PCONSOLE_INFORMATION Console;
02486
PHANDLE_DATA HandleData;
02487
02488
Status =
ApiPreamble(a->
ConsoleHandle,
02489 &Console
02490 );
02491
if (!
NT_SUCCESS(
Status)) {
02492
return Status;
02493 }
02494
02495
if (!a->
BufferInMessage) {
02496
if (!CsrValidateMessageBuffer(m, &a->
BufPtr, a->
NumBytes,
sizeof(
BYTE))) {
02497
UnlockConsole(Console);
02498
return STATUS_INVALID_PARAMETER;
02499 }
02500 }
02501
else if (a->
NumBytes >
sizeof(a->
Buffer)) {
02502
UnlockConsole(Console);
02503
return STATUS_INVALID_PARAMETER;
02504 }
02505
02506
02507
02508
02509
02510
02511
Status =
DereferenceIoHandle(
CONSOLE_PERPROCESSDATA(),
02512 a->
OutputHandle,
02513
CONSOLE_OUTPUT_HANDLE,
02514 GENERIC_WRITE,
02515 &HandleData
02516 );
02517
if (!
NT_SUCCESS(
Status)) {
02518
UnlockConsole(Console);
02519
return Status;
02520 }
02521
02522
Status =
DoSrvWriteConsole(m,ReplyStatus,Console,HandleData);
02523
02524
UnlockConsole(Console);
02525
return Status;
02526 }
02527
02528 BOOLEAN
02529 WriteConsoleWaitRoutine(
02530 IN PLIST_ENTRY WaitQueue,
02531 IN PCSR_THREAD WaitingThread,
02532 IN PCSR_API_MSG WaitReplyMessage,
02533 IN PVOID WaitParameter,
02534 IN PVOID SatisfyParameter1,
02535 IN PVOID SatisfyParameter2,
02536 IN ULONG WaitFlags
02537 )
02538 {
02539
NTSTATUS Status;
02540
PCONSOLE_WRITECONSOLE_MSG a = (
PCONSOLE_WRITECONSOLE_MSG)&WaitReplyMessage->u.ApiMessageData;
02541
PCONSOLE_INFORMATION Console;
02542
02543
if (WaitFlags & CSR_PROCESS_TERMINATING) {
02544 WaitReplyMessage->ReturnValue = (ULONG)STATUS_THREAD_IS_TERMINATING;
02545
return TRUE;
02546 }
02547
LockConsoleHandleTable();
02548
Status =
DereferenceConsoleHandle(a->
ConsoleHandle,
02549 &Console
02550 );
02551
UnlockConsoleHandleTable();
02552
ASSERT (
NT_SUCCESS(
Status));
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
ASSERT (
ConsoleLocked(Console));
02565
02566
02567
02568
02569
02570
02571
02572
if (a->
Unicode && a->
BufferInMessage) {
02573 a->
TransBuffer = a->
Buffer;
02574 }
02575
02576
Status =
DoWriteConsole(WaitReplyMessage,Console,WaitingThread);
02577
if (
Status ==
CONSOLE_STATUS_WAIT) {
02578
return FALSE;
02579 }
02580
if (!a->
Unicode) {
02581
#ifdef FE_SB
02582
if (CONSOLE_IS_DBCS_OUTPUTCP(Console))
02583 {
02584
if (a->
NumBytes == Console->WriteConOutNumBytesUnicode)
02585 a->
NumBytes = Console->WriteConOutNumBytesTemp;
02586
else
02587 a->
NumBytes /=
sizeof(WCHAR);
02588 }
02589
else
02590
#endif
02591
a->
NumBytes /=
sizeof(WCHAR);
02592
ConsoleHeapFree(a->
TransBuffer);
02593 }
02594 WaitReplyMessage->ReturnValue =
Status;
02595
return TRUE;
02596 UNREFERENCED_PARAMETER(WaitQueue);
02597 UNREFERENCED_PARAMETER(WaitParameter);
02598 UNREFERENCED_PARAMETER(SatisfyParameter1);
02599 UNREFERENCED_PARAMETER(SatisfyParameter2);
02600 }
02601
02602 ULONG
02603 SrvDuplicateHandle(
02604 IN OUT PCSR_API_MSG m,
02605 IN OUT PCSR_REPLY_STATUS ReplyStatus
02606 )
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622 {
02623
PCONSOLE_DUPHANDLE_MSG a = (
PCONSOLE_DUPHANDLE_MSG)&m->u.ApiMessageData;
02624
PCONSOLE_INFORMATION Console;
02625
PHANDLE_DATA SourceHandleData,TargetHandleData;
02626
PCONSOLE_SHARE_ACCESS ShareAccess;
02627
NTSTATUS Status;
02628
PCONSOLE_PER_PROCESS_DATA ProcessData;
02629
02630
Status =
ApiPreamble(a->
ConsoleHandle,
02631 &Console
02632 );
02633
if (!
NT_SUCCESS(
Status)) {
02634
return Status;
02635 }
02636 ProcessData =
CONSOLE_PERPROCESSDATA();
02637
Status =
DereferenceIoHandleNoCheck(ProcessData,
02638
HANDLE_TO_INDEX(a->
SourceHandle),
02639 &SourceHandleData
02640 );
02641
if (!
NT_SUCCESS(
Status)) {
02642
goto exit;
02643 }
02644
if (a->
Options & DUPLICATE_SAME_ACCESS) {
02645 a->
DesiredAccess = SourceHandleData->
Access;
02646 }
02647
02648
02649
02650
02651
02652
else if ((a->
DesiredAccess & SourceHandleData->
Access) != a->
DesiredAccess) {
02653
Status = STATUS_INVALID_PARAMETER;
02654
goto exit;
02655 }
02656
Status =
AllocateIoHandle(ProcessData,
02657 SourceHandleData->
HandleType,
02658 &a->
TargetHandle
02659 );
02660
if (!
NT_SUCCESS(
Status)) {
02661
goto exit;
02662 }
02663
02664
02665
02666
02667
02668
02669
Status =
DereferenceIoHandleNoCheck(ProcessData,
02670
HANDLE_TO_INDEX(a->
SourceHandle),
02671 &SourceHandleData
02672 );
02673
ASSERT (
NT_SUCCESS(
Status));
02674
if (!
NT_SUCCESS(
Status)) {
02675
goto exit;
02676 }
02677
Status =
DereferenceIoHandleNoCheck(ProcessData,
02678 a->
TargetHandle,
02679 &TargetHandleData
02680 );
02681
ASSERT (
NT_SUCCESS(
Status));
02682
if (!
NT_SUCCESS(
Status)) {
02683
FreeIoHandle(ProcessData,
02684 a->
TargetHandle
02685 );
02686
goto exit;
02687 }
02688
if (SourceHandleData->
HandleType &
CONSOLE_INPUT_HANDLE) {
02689
02690
if (!
InitializeInputHandle(TargetHandleData,
02691 SourceHandleData->
Buffer.InputBuffer)) {
02692
FreeIoHandle(ProcessData,
02693 a->
TargetHandle
02694 );
02695
Status = STATUS_NO_MEMORY;
02696
goto exit;
02697 }
02698 ShareAccess = &SourceHandleData->
Buffer.InputBuffer->ShareAccess;
02699 }
02700
else {
02701
02702
InitializeOutputHandle(TargetHandleData,SourceHandleData->
Buffer.ScreenBuffer);
02703 ShareAccess = &SourceHandleData->
Buffer.ScreenBuffer->ShareAccess;
02704 }
02705 TargetHandleData->
HandleType = SourceHandleData->
HandleType;
02706
if (a->
InheritHandle) {
02707 TargetHandleData->
HandleType |=
CONSOLE_INHERITABLE;
02708 }
else {
02709 TargetHandleData->
HandleType &= ~
CONSOLE_INHERITABLE;
02710 }
02711
02712
Status =
ConsoleDupShare(a->
DesiredAccess,
02713 SourceHandleData->
ShareAccess,
02714 ShareAccess,
02715 TargetHandleData
02716 );
02717
if (!
NT_SUCCESS(
Status)) {
02718
FreeIoHandle(ProcessData,
02719 a->
TargetHandle
02720 );
02721
if (SourceHandleData->
HandleType &
CONSOLE_INPUT_HANDLE) {
02722 SourceHandleData->
Buffer.InputBuffer->RefCount--;
02723 }
02724
else {
02725 SourceHandleData->
Buffer.ScreenBuffer->RefCount--;
02726 }
02727 }
02728
else {
02729 a->
TargetHandle =
INDEX_TO_HANDLE(a->
TargetHandle);
02730 }
02731
02732
if (a->
Options & DUPLICATE_CLOSE_SOURCE) {
02733
if (SourceHandleData->
HandleType &
CONSOLE_INPUT_HANDLE)
02734
CloseInputHandle(ProcessData,Console,SourceHandleData,
HANDLE_TO_INDEX(a->
SourceHandle));
02735
else {
02736
CloseOutputHandle(ProcessData,Console,SourceHandleData,
HANDLE_TO_INDEX(a->
SourceHandle),
TRUE);
02737 }
02738 }
02739
02740
exit:
02741
UnlockConsole(Console);
02742
return Status;
02743 UNREFERENCED_PARAMETER(ReplyStatus);
02744 }
02745
02746 ULONG
02747 SrvGetHandleInformation(
02748 IN OUT PCSR_API_MSG m,
02749 IN OUT PCSR_REPLY_STATUS ReplyStatus
02750 )
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766 {
02767
PCONSOLE_GETHANDLEINFORMATION_MSG a = (
PCONSOLE_GETHANDLEINFORMATION_MSG)&m->u.ApiMessageData;
02768
PCONSOLE_INFORMATION Console;
02769
PHANDLE_DATA HandleData;
02770
NTSTATUS Status;
02771
02772
Status =
ApiPreamble(a->
ConsoleHandle,
02773 &Console
02774 );
02775
if (!
NT_SUCCESS(
Status)) {
02776
return Status;
02777 }
02778
Status =
DereferenceIoHandleNoCheck(
CONSOLE_PERPROCESSDATA(),
02779
HANDLE_TO_INDEX(a->
Handle),
02780 &HandleData
02781 );
02782
if (
NT_SUCCESS(
Status)) {
02783 a->
Flags = 0;
02784
if (HandleData->
HandleType &
CONSOLE_INHERITABLE) {
02785 a->
Flags |= HANDLE_FLAG_INHERIT;
02786 }
02787 }
02788
UnlockConsole(Console);
02789
return Status;
02790 UNREFERENCED_PARAMETER(ReplyStatus);
02791 }
02792
02793 ULONG
02794 SrvSetHandleInformation(
02795 IN OUT PCSR_API_MSG m,
02796 IN OUT PCSR_REPLY_STATUS ReplyStatus
02797 )
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813 {
02814
PCONSOLE_SETHANDLEINFORMATION_MSG a = (
PCONSOLE_SETHANDLEINFORMATION_MSG)&m->u.ApiMessageData;
02815
PCONSOLE_INFORMATION Console;
02816
PHANDLE_DATA HandleData;
02817
NTSTATUS Status;
02818
02819
Status =
ApiPreamble(a->
ConsoleHandle,
02820 &Console
02821 );
02822
if (!
NT_SUCCESS(
Status)) {
02823
return Status;
02824 }
02825
Status =
DereferenceIoHandleNoCheck(
CONSOLE_PERPROCESSDATA(),
02826
HANDLE_TO_INDEX(a->
Handle),
02827 &HandleData
02828 );
02829
if (
NT_SUCCESS(
Status)) {
02830
if (a->
Mask & HANDLE_FLAG_INHERIT) {
02831
if (a->
Flags & HANDLE_FLAG_INHERIT) {
02832 HandleData->
HandleType |=
CONSOLE_INHERITABLE;
02833 }
else {
02834 HandleData->
HandleType &= ~
CONSOLE_INHERITABLE;
02835 }
02836 }
02837 }
02838
UnlockConsole(Console);
02839
return Status;
02840 UNREFERENCED_PARAMETER(ReplyStatus);
02841 }
02842
02843
NTSTATUS
02844 CloseInputHandle(
02845 IN
PCONSOLE_PER_PROCESS_DATA ProcessData,
02846 IN
PCONSOLE_INFORMATION Console,
02847 IN
PHANDLE_DATA HandleData,
02848 IN HANDLE Handle
02849 )
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875 {
02876 BOOLEAN WaitSatisfied =
FALSE;
02877
02878
ASSERT(ProcessData->Foo == 0xF00);
02879
if (HandleData->InputReadData->InputHandleFlags &
HANDLE_INPUT_PENDING) {
02880 HandleData->InputReadData->InputHandleFlags &= ~
HANDLE_INPUT_PENDING;
02881
ConsoleHeapFree(HandleData->InputReadData->BufPtr);
02882 }
02883
02884
02885
02886
02887
02888
02889
02890
LockReadCount(HandleData);
02891
if (HandleData->InputReadData->ReadCount != 0) {
02892
UnlockReadCount(HandleData);
02893 HandleData->InputReadData->InputHandleFlags |=
HANDLE_CLOSING;
02894
02895 WaitSatisfied |= CsrNotifyWait(&HandleData->Buffer.InputBuffer->ReadWaitQueue,
02896
TRUE,
02897 (PVOID) HandleData,
02898
NULL
02899 );
02900
LockReadCount(HandleData);
02901 }
02902
if (WaitSatisfied) {
02903
02904
ASSERT ((Console->WaitQueue ==
NULL) ||
02905 (Console->WaitQueue == &HandleData->Buffer.InputBuffer->ReadWaitQueue));
02906 Console->WaitQueue = &HandleData->Buffer.InputBuffer->ReadWaitQueue;
02907 }
02908
if (HandleData->InputReadData->ReadCount != 0) {
02909 KdPrint((
"ReadCount is %lX\n",HandleData->InputReadData->ReadCount));
02910 }
02911
ASSERT (HandleData->InputReadData->ReadCount == 0);
02912
UnlockReadCount(HandleData);
02913
02914
ASSERT (HandleData->Buffer.InputBuffer->RefCount);
02915 HandleData->Buffer.InputBuffer->RefCount--;
02916
if (HandleData->Buffer.InputBuffer->RefCount == 0) {
02917
ReinitializeInputBuffer(HandleData->Buffer.InputBuffer);
02918 }
02919
else {
02920
ConsoleRemoveShare(HandleData->Access,
02921 HandleData->ShareAccess,
02922 &HandleData->Buffer.InputBuffer->ShareAccess
02923 );
02924 }
02925
return FreeIoHandle(ProcessData,
Handle);
02926 }
02927
02928
NTSTATUS
02929 CloseOutputHandle(
02930 IN
PCONSOLE_PER_PROCESS_DATA ProcessData,
02931 IN
PCONSOLE_INFORMATION Console,
02932 IN
PHANDLE_DATA HandleData,
02933 IN HANDLE Handle,
02934 IN BOOLEAN FreeHandle
02935 )
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966 {
02967
NTSTATUS Status;
02968
02969
ASSERT(ProcessData->Foo == 0xF00);
02970
ASSERT (HandleData->Buffer.ScreenBuffer->RefCount);
02971 HandleData->Buffer.ScreenBuffer->RefCount--;
02972
if (HandleData->Buffer.ScreenBuffer->RefCount == 0) {
02973
RemoveScreenBuffer(Console,HandleData->Buffer.ScreenBuffer);
02974
if (HandleData->Buffer.ScreenBuffer == Console->CurrentScreenBuffer &&
02975 Console->ScreenBuffers != Console->CurrentScreenBuffer) {
02976
if (Console->ScreenBuffers !=
NULL) {
02977
SetActiveScreenBuffer(Console->ScreenBuffers);
02978 }
else {
02979 Console->CurrentScreenBuffer =
NULL;
02980 }
02981 }
02982
Status =
FreeScreenBuffer(HandleData->Buffer.ScreenBuffer);
02983 }
02984
else {
02985
Status =
ConsoleRemoveShare(HandleData->Access,
02986 HandleData->ShareAccess,
02987 &HandleData->Buffer.ScreenBuffer->ShareAccess
02988 );
02989 }
02990
if (FreeHandle)
02991
Status =
FreeIoHandle(ProcessData,
Handle);
02992
return Status;
02993 }
02994
02995
02996 ULONG
02997 SrvCloseHandle(
02998 IN OUT PCSR_API_MSG m,
02999 IN OUT PCSR_REPLY_STATUS ReplyStatus
03000 )
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016 {
03017
PCONSOLE_CLOSEHANDLE_MSG a = (
PCONSOLE_CLOSEHANDLE_MSG)&m->u.ApiMessageData;
03018
PCONSOLE_INFORMATION Console;
03019
PHANDLE_DATA HandleData;
03020
NTSTATUS Status;
03021
PCONSOLE_PER_PROCESS_DATA ProcessData;
03022
03023
Status =
ApiPreamble(a->
ConsoleHandle,
03024 &Console
03025 );
03026
if (!
NT_SUCCESS(
Status)) {
03027
return Status;
03028 }
03029 ProcessData =
CONSOLE_PERPROCESSDATA();
03030
Status =
DereferenceIoHandleNoCheck(ProcessData,
03031
HANDLE_TO_INDEX(a->
Handle),
03032 &HandleData
03033 );
03034
if (
NT_SUCCESS(
Status)) {
03035
if (HandleData->
HandleType &
CONSOLE_INPUT_HANDLE)
03036
Status =
CloseInputHandle(ProcessData,Console,HandleData,
HANDLE_TO_INDEX(a->
Handle));
03037
else {
03038
Status =
CloseOutputHandle(ProcessData,Console,HandleData,
HANDLE_TO_INDEX(a->
Handle),
TRUE);
03039 }
03040 }
03041
UnlockConsole(Console);
03042
return((ULONG)
Status);
03043 UNREFERENCED_PARAMETER(ReplyStatus);
03044 }
03045
03046
NTSTATUS
03047 WriteCharsFromInput(
03048 IN
PSCREEN_INFORMATION ScreenInfo,
03049 IN PWCHAR lpBufferBackupLimit,
03050 IN PWCHAR lpBuffer,
03051 IN PWCHAR lpString,
03052 IN OUT PDWORD NumBytes,
03053 OUT PLONG NumSpaces OPTIONAL,
03054 IN SHORT OriginalXPosition,
03055 IN DWORD dwFlags,
03056 OUT PSHORT ScrollY OPTIONAL
03057 )
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100 {
03101
DWORD Length,i;
03102
03103
if (ScreenInfo->Flags &
CONSOLE_GRAPHICS_BUFFER) {
03104
return STATUS_UNSUCCESSFUL;
03105 }
03106
03107
if (!(ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) ||
03108 (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
03109
goto SimpleWrite;
03110 }
03111
03112 Length = *NumBytes /
sizeof(WCHAR);
03113
for (i=0;i<Length;i++) {
03114
if (lpString[i] > 0x7f) {
03115
dwFlags |=
WC_FALSIFY_UNICODE;
03116
break;
03117 }
03118 }
03119
03120 SimpleWrite:
03121
return WriteChars(ScreenInfo,
03122 lpBufferBackupLimit,
03123 lpBuffer,
03124 lpString,
03125 NumBytes,
03126 NumSpaces,
03127 OriginalXPosition,
03128
dwFlags,
03129 ScrollY
03130 );
03131 }
03132
03133
#if defined(FE_SB)
03134
03135
#define WWSB_NOFE
03136
#include "dispatch.h"
03137
#include "_stream.h"
03138
#undef WWSB_NOFE
03139
#define WWSB_FE
03140
#include "dispatch.h"
03141
#include "_stream.h"
03142
#undef WWSB_FE
03143
03144
#endif // FE_SB
03145