00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define WWSB_NEUTRAL_FILE 1
00024
00025
#if !defined(FE_SB)
00026
#error This header file should be included with FE_SB
00027
#endif
00028
00029
#if !defined(WWSB_FE) && !defined(WWSB_NOFE)
00030
#error Either WWSB_FE and WWSB_NOFE must be defined.
00031
#endif
00032
00033
#if defined(WWSB_FE) && defined(WWSB_NOFE)
00034
#error Both WWSB_FE and WWSB_NOFE defined.
00035
#endif
00036
00037
#ifdef WWSB_FE
00038
#pragma alloc_text(FE_TEXT, FE_AdjustCursorPosition)
00039
#pragma alloc_text(FE_TEXT, FE_WriteChars)
00040
#pragma alloc_text(FE_TEXT, FE_DoWriteConsole)
00041
#pragma alloc_text(FE_TEXT, FE_DoSrvWriteConsole)
00042
#endif
00043
00044
00045
NTSTATUS
00046 WWSB_AdjustCursorPosition(
00047 IN
PSCREEN_INFORMATION ScreenInfo,
00048 IN COORD CursorPosition,
00049 IN BOOL KeepCursorVisible,
00050 OUT
PSHORT ScrollY OPTIONAL
00051 )
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 {
00076 COORD WindowOrigin;
00077
NTSTATUS Status;
00078
#ifdef WWSB_FE
00079
PCONSOLE_INFORMATION Console = ScreenInfo->Console;
00080
00081
if (!(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER))
00082
return STATUS_SUCCESS;
00083
#endif
00084
00085
if (CursorPosition.X < 0) {
00086
if (CursorPosition.Y > 0) {
00087 CursorPosition.X = (
SHORT)(ScreenInfo->ScreenBufferSize.X+CursorPosition.X);
00088 CursorPosition.Y = (
SHORT)(CursorPosition.Y-1);
00089 }
00090
else {
00091 CursorPosition.X = 0;
00092 }
00093 }
00094
else if (CursorPosition.X >= ScreenInfo->ScreenBufferSize.X) {
00095
00096
00097
00098
00099
00100
00101
if (ScreenInfo->OutputMode & ENABLE_WRAP_AT_EOL_OUTPUT) {
00102 CursorPosition.Y += CursorPosition.X / ScreenInfo->ScreenBufferSize.X;
00103 CursorPosition.X = CursorPosition.X % ScreenInfo->ScreenBufferSize.X;
00104 }
00105
else {
00106 CursorPosition.X = ScreenInfo->BufferInfo.TextInfo.CursorPosition.X;
00107 }
00108 }
00109
#ifdef WWSB_FE
00110
if (CursorPosition.Y >= ScreenInfo->ScreenBufferSize.Y &&
00111 !(Console->
InputBuffer.ImeMode.Open)
00112 )
00113
#else
00114
if (CursorPosition.Y >= ScreenInfo->ScreenBufferSize.Y)
00115
#endif
00116
{
00117
00118
00119
00120
00121
00122
00123
ASSERT (CursorPosition.Y == ScreenInfo->ScreenBufferSize.Y);
00124
StreamScrollRegion(ScreenInfo);
00125
00126
if (ARGUMENT_PRESENT(ScrollY)) {
00127 *ScrollY += (
SHORT)(ScreenInfo->ScreenBufferSize.Y - CursorPosition.Y - 1);
00128 }
00129 CursorPosition.Y += (
SHORT)(ScreenInfo->ScreenBufferSize.Y - CursorPosition.Y - 1);
00130 }
00131
#ifdef WWSB_FE
00132
else if (!(Console->
InputBuffer.ImeMode.Disable) && Console->
InputBuffer.ImeMode.Open)
00133 {
00134
if (CursorPosition.Y == (ScreenInfo->ScreenBufferSize.Y-1)) {
00135 ConsoleImeBottomLineUse(ScreenInfo,2);
00136
if (ARGUMENT_PRESENT(ScrollY)) {
00137 *ScrollY += (
SHORT)(ScreenInfo->ScreenBufferSize.Y - CursorPosition.Y - 2);
00138 }
00139 CursorPosition.Y += (
SHORT)(ScreenInfo->ScreenBufferSize.Y - CursorPosition.Y - 2);
00140
if (!ARGUMENT_PRESENT(ScrollY) && Console->lpCookedReadData) {
00141 ((
PCOOKED_READ_DATA)(Console->lpCookedReadData))->OriginalCursorPosition.Y--;
00142 }
00143 }
00144
else if (CursorPosition.Y == ScreenInfo->Window.Bottom) {
00145 ;
00146 }
00147 }
00148
#endif
00149
00150
00151
00152
00153
00154
#ifdef WWSB_FE
00155
if (CursorPosition.Y > ScreenInfo->Window.Bottom &&
00156 !(Console->
InputBuffer.ImeMode.Open)
00157 )
00158
#else
00159
if (CursorPosition.Y > ScreenInfo->Window.Bottom)
00160
#endif
00161
{
00162 WindowOrigin.X = 0;
00163 WindowOrigin.Y = CursorPosition.Y - ScreenInfo->Window.Bottom;
00164
Status =
SetWindowOrigin(ScreenInfo,
00165
FALSE,
00166 WindowOrigin
00167 );
00168
if (!
NT_SUCCESS(
Status)) {
00169
return Status;
00170 }
00171 }
00172
#ifdef WWSB_FE
00173
else if (Console->
InputBuffer.ImeMode.Open)
00174 {
00175
if (CursorPosition.Y >= ScreenInfo->Window.Bottom &&
00176
CONSOLE_WINDOW_SIZE_Y(ScreenInfo) > 1
00177 ) {
00178 WindowOrigin.X = 0;
00179 WindowOrigin.Y = CursorPosition.Y - ScreenInfo->Window.Bottom + 1;
00180
Status =
SetWindowOrigin(ScreenInfo,
00181
FALSE,
00182 WindowOrigin
00183 );
00184
if (!
NT_SUCCESS(
Status)) {
00185
return Status;
00186 }
00187 }
00188 }
00189
#endif
00190
if (KeepCursorVisible) {
00191
MakeCursorVisible(ScreenInfo,CursorPosition);
00192 }
00193
Status =
SetCursorPosition(ScreenInfo,
00194 CursorPosition,
00195 KeepCursorVisible
00196 );
00197
return Status;
00198 }
00199
00200 #define LOCAL_BUFFER_SIZE 100
00201
00202
NTSTATUS
00203 WWSB_WriteChars(
00204 IN
PSCREEN_INFORMATION ScreenInfo,
00205 IN PWCHAR lpBufferBackupLimit,
00206 IN PWCHAR lpBuffer,
00207 IN PWCHAR lpRealUnicodeString,
00208 IN OUT PDWORD NumBytes,
00209 OUT PLONG NumSpaces OPTIONAL,
00210 IN SHORT OriginalXPosition,
00211 IN DWORD
dwFlags,
00212 OUT PSHORT ScrollY OPTIONAL
00213 )
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 {
00256
DWORD BufferSize;
00257 COORD CursorPosition;
00258
NTSTATUS Status;
00259 ULONG NumChars;
00260
static WCHAR Blanks[
TAB_SIZE] = {
UNICODE_SPACE,
00261
UNICODE_SPACE,
00262
UNICODE_SPACE,
00263
UNICODE_SPACE,
00264
UNICODE_SPACE,
00265
UNICODE_SPACE,
00266
UNICODE_SPACE,
00267
UNICODE_SPACE };
00268
SHORT XPosition;
00269 WCHAR LocalBuffer[
LOCAL_BUFFER_SIZE];
00270 PWCHAR LocalBufPtr;
00271 ULONG i,j;
00272 SMALL_RECT Region;
00273 ULONG TabSize;
00274
DWORD TempNumSpaces;
00275 WCHAR Char;
00276 WCHAR RealUnicodeChar;
00277 WORD Attributes;
00278 PWCHAR lpString;
00279 PWCHAR lpAllocatedString;
00280
BOOL fUnprocessed = ((ScreenInfo->OutputMode & ENABLE_PROCESSED_OUTPUT) == 0);
00281
#ifdef WWSB_FE
00282
CHAR LocalBufferA[
LOCAL_BUFFER_SIZE];
00283 PCHAR LocalBufPtrA;
00284
#endif
00285
00286
ConsoleHideCursor(ScreenInfo);
00287
00288 Attributes = ScreenInfo->Attributes;
00289
BufferSize = *NumBytes;
00290 *NumBytes = 0;
00291 TempNumSpaces = 0;
00292
00293 lpAllocatedString =
NULL;
00294
if (
dwFlags &
WC_FALSIFY_UNICODE) {
00295
00296
00297
00298
00299 lpString =
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),
BufferSize);
00300
if (lpString ==
NULL) {
00301
Status = STATUS_NO_MEMORY;
00302
goto ExitWriteChars;
00303 }
00304
00305 lpAllocatedString = lpString;
00306 RtlCopyMemory(lpString, lpRealUnicodeString,
BufferSize);
00307
Status =
RealUnicodeToFalseUnicode(lpString,
00308
BufferSize /
sizeof(WCHAR),
00309 ScreenInfo->Console->OutputCP
00310 );
00311
if (!
NT_SUCCESS(
Status)) {
00312
goto ExitWriteChars;
00313 }
00314 }
else {
00315 lpString = lpRealUnicodeString;
00316 }
00317
00318
while (*NumBytes <
BufferSize) {
00319
00320
00321
00322
00323
00324
00325 XPosition = ScreenInfo->BufferInfo.TextInfo.CursorPosition.X;
00326 i=0;
00327 LocalBufPtr = LocalBuffer;
00328
#ifdef WWSB_FE
00329
LocalBufPtrA = LocalBufferA;
00330
#endif
00331
while (*NumBytes <
BufferSize &&
00332 i <
LOCAL_BUFFER_SIZE &&
00333 XPosition < ScreenInfo->ScreenBufferSize.X) {
00334 Char = *lpString;
00335 RealUnicodeChar = *lpRealUnicodeString;
00336
if (!
IS_GLYPH_CHAR(RealUnicodeChar) || fUnprocessed) {
00337
#ifdef WWSB_FE
00338
if (IsConsoleFullWidth(ScreenInfo->Console->hDC,
00339 ScreenInfo->Console->OutputCP,Char)) {
00340
if (i < (
LOCAL_BUFFER_SIZE-1) &&
00341 XPosition < (ScreenInfo->ScreenBufferSize.X-1)) {
00342 *LocalBufPtr++ = Char;
00343 *LocalBufPtrA++ = ATTR_LEADING_BYTE;
00344 *LocalBufPtr++ = Char;
00345 *LocalBufPtrA++ = ATTR_TRAILING_BYTE;
00346 XPosition+=2;
00347 i+=2;
00348 lpBuffer++;
00349 }
00350
else
00351
goto EndWhile;
00352 }
00353
else {
00354
#endif
00355
*LocalBufPtr = Char;
00356 LocalBufPtr++;
00357 XPosition++;
00358 i++;
00359 lpBuffer++;
00360
#ifdef WWSB_FE
00361
*LocalBufPtrA++ = 0;
00362 }
00363
#endif
00364
}
else {
00365
ASSERT(ScreenInfo->OutputMode & ENABLE_PROCESSED_OUTPUT);
00366
switch (RealUnicodeChar) {
00367
case UNICODE_BELL:
00368
if (
dwFlags &
WC_ECHO) {
00369
goto CtrlChar;
00370 }
else {
00371
SendNotifyMessage(ScreenInfo->Console->hWnd,
00372
CM_BEEP,
00373 0,
00374 0x47474747);
00375 }
00376
break;
00377
case UNICODE_BACKSPACE:
00378
00379
00380
00381
00382
00383
00384
00385
00386
goto EndWhile;
00387
break;
00388
case UNICODE_TAB:
00389 TabSize =
NUMBER_OF_SPACES_IN_TAB(XPosition);
00390 XPosition = (
SHORT)(XPosition + TabSize);
00391
if (XPosition >= ScreenInfo->ScreenBufferSize.X) {
00392
goto EndWhile;
00393 }
00394
for (j=0;j<TabSize && i<
LOCAL_BUFFER_SIZE;j++,i++) {
00395 *LocalBufPtr = (WCHAR)
' ';
00396 LocalBufPtr++;
00397
#ifdef WWSB_FE
00398
*LocalBufPtrA++ = 0;
00399
#endif
00400
}
00401 lpBuffer++;
00402
break;
00403
case UNICODE_LINEFEED:
00404
case UNICODE_CARRIAGERETURN:
00405
goto EndWhile;
00406
default:
00407
00408
00409
00410
00411
00412
if ((
dwFlags &
WC_ECHO) && (
IS_CONTROL_CHAR(RealUnicodeChar))) {
00413
00414 CtrlChar:
if (i < (
LOCAL_BUFFER_SIZE-1)) {
00415 *LocalBufPtr = (WCHAR)
'^';
00416 LocalBufPtr++;
00417 XPosition++;
00418 i++;
00419 *LocalBufPtr = (WCHAR)(RealUnicodeChar+(WCHAR)
'@');
00420 LocalBufPtr++;
00421 XPosition++;
00422 i++;
00423 lpBuffer++;
00424
#ifdef WWSB_FE
00425
*LocalBufPtrA++ = 0;
00426 *LocalBufPtrA++ = 0;
00427
#endif
00428
}
00429
else {
00430
goto EndWhile;
00431 }
00432 }
else {
00433
if (!(ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) ||
00434 (ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
00435
00436
00437
00438
00439
00440
#ifdef WWSB_FE
00441
WORD CharType;
00442
00443 GetStringTypeW(CT_CTYPE1,&RealUnicodeChar,1,&CharType);
00444
if (CharType == C1_CNTRL)
00445
ConvertOutputToUnicode(ScreenInfo->Console->OutputCP,
00446 &(
char)RealUnicodeChar,
00447 1,
00448 LocalBufPtr,
00449 1);
00450
else
00451 *LocalBufPtr = Char;
00452
#else
00453
*LocalBufPtr = SB_CharToWcharGlyph(
00454 ScreenInfo->Console->OutputCP,
00455 (
char)RealUnicodeChar);
00456
#endif
00457
}
else {
00458 *LocalBufPtr = Char;
00459 }
00460 LocalBufPtr++;
00461 XPosition++;
00462 i++;
00463 lpBuffer++;
00464
#ifdef WWSB_FE
00465
*LocalBufPtrA++ = 0;
00466
#endif
00467
}
00468 }
00469 }
00470 lpString++;
00471 lpRealUnicodeString++;
00472 *NumBytes +=
sizeof(WCHAR);
00473 }
00474 EndWhile:
00475
if (i != 0) {
00476
00477
00478
00479
00480
00481
if (i > (ULONG)ScreenInfo->ScreenBufferSize.X - ScreenInfo->BufferInfo.TextInfo.CursorPosition.X) {
00482 i = (ULONG)ScreenInfo->ScreenBufferSize.X - ScreenInfo->BufferInfo.TextInfo.CursorPosition.X;
00483 }
00484
00485
#ifdef WWSB_FE
00486
FE_StreamWriteToScreenBuffer(LocalBuffer,
00487 (
SHORT)i,
00488 ScreenInfo,
00489 LocalBufferA
00490 );
00491
#else
00492
SB_StreamWriteToScreenBuffer(LocalBuffer,
00493 (
SHORT)i,
00494 ScreenInfo
00495 );
00496
#endif
00497
Region.Left = ScreenInfo->BufferInfo.TextInfo.CursorPosition.X;
00498 Region.Right = (
SHORT)(ScreenInfo->BufferInfo.TextInfo.CursorPosition.X + i - 1);
00499 Region.Top = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y;
00500 Region.Bottom = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y;
00501
WWSB_WriteToScreen(ScreenInfo,&Region);
00502 TempNumSpaces += i;
00503 CursorPosition.X = (
SHORT)(ScreenInfo->BufferInfo.TextInfo.CursorPosition.X + i);
00504 CursorPosition.Y = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y;
00505
Status =
WWSB_AdjustCursorPosition(ScreenInfo,CursorPosition,
00506
dwFlags &
WC_KEEP_CURSOR_VISIBLE,ScrollY);
00507
if (*NumBytes ==
BufferSize) {
00508
ConsoleShowCursor(ScreenInfo);
00509
if (ARGUMENT_PRESENT(NumSpaces)) {
00510 *NumSpaces = TempNumSpaces;
00511 }
00512
Status = STATUS_SUCCESS;
00513
goto ExitWriteChars;
00514 }
00515
continue;
00516 }
else if (*NumBytes ==
BufferSize) {
00517
00518
ASSERT(ScreenInfo->OutputMode & ENABLE_PROCESSED_OUTPUT);
00519
00520
00521
if (ARGUMENT_PRESENT(NumSpaces)) {
00522 *NumSpaces = TempNumSpaces;
00523 }
00524
ConsoleShowCursor(ScreenInfo);
00525
Status = STATUS_SUCCESS;
00526
goto ExitWriteChars;
00527 }
00528
00529
ASSERT(ScreenInfo->OutputMode & ENABLE_PROCESSED_OUTPUT);
00530
switch (*lpString) {
00531
case UNICODE_BACKSPACE:
00532
00533
00534
00535
00536
00537
00538 CursorPosition = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
00539 TempNumSpaces -= 1;
00540
if (lpBuffer == lpBufferBackupLimit) {
00541 CursorPosition.X-=1;
00542 }
00543
else {
00544 PWCHAR pBuffer;
00545 WCHAR TmpBuffer[
LOCAL_BUFFER_SIZE];
00546 PWCHAR Tmp,Tmp2;
00547 WCHAR LastChar;
00548 ULONG i;
00549
00550
if (lpBuffer-lpBufferBackupLimit >
LOCAL_BUFFER_SIZE) {
00551 pBuffer = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),(ULONG)(lpBuffer-lpBufferBackupLimit) *
sizeof(WCHAR));
00552
if (pBuffer ==
NULL) {
00553
Status = STATUS_NO_MEMORY;
00554
goto ExitWriteChars;
00555 }
00556 }
else {
00557 pBuffer = TmpBuffer;
00558 }
00559
00560
for (i=0,Tmp2=pBuffer,Tmp=lpBufferBackupLimit;
00561 i<(ULONG)(lpBuffer-lpBufferBackupLimit);
00562 i++,Tmp++) {
00563
if (*Tmp ==
UNICODE_BACKSPACE) {
00564
if (Tmp2 > pBuffer) {
00565 Tmp2--;
00566 }
00567 }
else {
00568
ASSERT(Tmp2 >= pBuffer);
00569 *Tmp2++ = *Tmp;
00570 }
00571
00572 }
00573
if (Tmp2 == pBuffer) {
00574 LastChar = (WCHAR)
' ';
00575 }
else {
00576 LastChar = *(Tmp2-1);
00577 }
00578
if (pBuffer != TmpBuffer) {
00579
ConsoleHeapFree(pBuffer);
00580 }
00581
00582
if (LastChar ==
UNICODE_TAB) {
00583 CursorPosition.X -=
00584 (
SHORT)(
RetrieveNumberOfSpaces(OriginalXPosition,
00585 lpBufferBackupLimit,
00586 (ULONG)(lpBuffer - lpBufferBackupLimit - 1),
00587 ScreenInfo->Console,
00588 ScreenInfo->Console->OutputCP
00589 ));
00590
if (CursorPosition.X < 0) {
00591 CursorPosition.X = (ScreenInfo->ScreenBufferSize.X - 1)/
TAB_SIZE;
00592 CursorPosition.X *=
TAB_SIZE;
00593 CursorPosition.X += 1;
00594 CursorPosition.Y -= 1;
00595 }
00596 }
00597
else if (
IS_CONTROL_CHAR(LastChar)) {
00598 CursorPosition.X-=1;
00599 TempNumSpaces -= 1;
00600
00601
00602
00603
00604
00605
if (
dwFlags &
WC_DESTRUCTIVE_BACKSPACE) {
00606 NumChars = 1;
00607
Status =
WWSB_WriteOutputString(ScreenInfo,
00608 Blanks, CursorPosition,
00609
CONSOLE_FALSE_UNICODE,
00610 &NumChars,
NULL);
00611
Status =
WWSB_FillOutput(ScreenInfo,
00612 Attributes, CursorPosition,
00613
CONSOLE_ATTRIBUTE, &NumChars);
00614 }
00615 CursorPosition.X-=1;
00616 }
00617
#ifdef WWSB_FE
00618
else if (IsConsoleFullWidth(ScreenInfo->Console->hDC,
00619 ScreenInfo->Console->OutputCP,LastChar))
00620 {
00621 CursorPosition.X-=1;
00622 TempNumSpaces -= 1;
00623
00624
Status =
WWSB_AdjustCursorPosition(ScreenInfo,CursorPosition,
00625
dwFlags &
WC_KEEP_CURSOR_VISIBLE,ScrollY);
00626
if (
dwFlags &
WC_DESTRUCTIVE_BACKSPACE) {
00627 NumChars = 1;
00628
Status =
WWSB_WriteOutputString(ScreenInfo,
00629 Blanks, ScreenInfo->BufferInfo.TextInfo.CursorPosition,
00630
CONSOLE_FALSE_UNICODE,
00631 &NumChars,
NULL);
00632
Status =
WWSB_FillOutput(ScreenInfo,
00633 Attributes, ScreenInfo->BufferInfo.TextInfo.CursorPosition,
00634
CONSOLE_ATTRIBUTE, &NumChars);
00635 }
00636 CursorPosition.X-=1;
00637 }
00638
#endif
00639
else {
00640 CursorPosition.X--;
00641 }
00642 }
00643
if ((
dwFlags &
WC_LIMIT_BACKSPACE) && (CursorPosition.X < 0)) {
00644 CursorPosition.X = 0;
00645 KdPrint((
"CONSRV: Ignoring backspace to previous line\n"));
00646 }
00647
Status =
WWSB_AdjustCursorPosition(ScreenInfo,CursorPosition,
00648 (
dwFlags &
WC_KEEP_CURSOR_VISIBLE) != 0,ScrollY);
00649
if (
dwFlags &
WC_DESTRUCTIVE_BACKSPACE) {
00650 NumChars = 1;
00651
Status =
WWSB_WriteOutputString(ScreenInfo,
00652 Blanks, ScreenInfo->BufferInfo.TextInfo.CursorPosition,
00653
CONSOLE_FALSE_UNICODE,
00654 &NumChars,
NULL);
00655
Status =
WWSB_FillOutput(ScreenInfo,
00656 Attributes, ScreenInfo->BufferInfo.TextInfo.CursorPosition,
00657
CONSOLE_ATTRIBUTE, &NumChars);
00658 }
00659
#ifdef WWSB_FE
00660
if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.X == 0 &&
00661 (ScreenInfo->OutputMode & ENABLE_WRAP_AT_EOL_OUTPUT) &&
00662 lpBuffer > lpBufferBackupLimit) {
00663
if (CheckBisectProcessW(ScreenInfo,
00664 ScreenInfo->Console->OutputCP,
00665 lpBufferBackupLimit,
00666 (ULONG)(lpBuffer+1-lpBufferBackupLimit),
00667 ScreenInfo->ScreenBufferSize.X-OriginalXPosition,
00668 OriginalXPosition,
00669
dwFlags &
WC_ECHO)) {
00670 CursorPosition.X = ScreenInfo->ScreenBufferSize.X-1;
00671 CursorPosition.Y = (
SHORT)(ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y-1);
00672
Status =
WWSB_AdjustCursorPosition(ScreenInfo,CursorPosition,
00673
dwFlags &
WC_KEEP_CURSOR_VISIBLE,ScrollY);
00674 }
00675 }
00676
#endif
00677
break;
00678
case UNICODE_TAB:
00679 TabSize =
NUMBER_OF_SPACES_IN_TAB(ScreenInfo->BufferInfo.TextInfo.CursorPosition.X);
00680 CursorPosition.X = (
SHORT)(ScreenInfo->BufferInfo.TextInfo.CursorPosition.X + TabSize);
00681
00682
00683
00684
00685
00686
00687
00688
00689 lpBuffer++;
00690
00691 TempNumSpaces += TabSize;
00692
if (CursorPosition.X >= ScreenInfo->ScreenBufferSize.X) {
00693 NumChars = ScreenInfo->ScreenBufferSize.X - ScreenInfo->BufferInfo.TextInfo.CursorPosition.X;
00694 CursorPosition.X = 0;
00695 CursorPosition.Y = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y+1;
00696 }
00697
else {
00698 NumChars = CursorPosition.X - ScreenInfo->BufferInfo.TextInfo.CursorPosition.X;
00699 CursorPosition.Y = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y;
00700 }
00701
Status =
WWSB_WriteOutputString(ScreenInfo,
00702 Blanks,
00703 ScreenInfo->BufferInfo.TextInfo.CursorPosition,
00704
CONSOLE_FALSE_UNICODE,
00705 &NumChars,
00706
NULL);
00707
Status =
WWSB_FillOutput(ScreenInfo,
00708 Attributes, ScreenInfo->BufferInfo.TextInfo.CursorPosition,
00709
CONSOLE_ATTRIBUTE,
00710 &NumChars);
00711
Status =
WWSB_AdjustCursorPosition(ScreenInfo,CursorPosition,
00712 (
dwFlags &
WC_KEEP_CURSOR_VISIBLE) != 0,ScrollY);
00713
break;
00714
case UNICODE_CARRIAGERETURN:
00715
00716
00717
00718
00719
00720
00721
00722 lpBuffer++;
00723 CursorPosition.X = 0;
00724 CursorPosition.Y = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y;
00725
Status =
WWSB_AdjustCursorPosition(ScreenInfo,CursorPosition,
00726 (
dwFlags &
WC_KEEP_CURSOR_VISIBLE) != 0,ScrollY);
00727
break;
00728
case UNICODE_LINEFEED:
00729
00730
00731
00732
00733
00734 lpBuffer++;
00735 CursorPosition.X = 0;
00736 CursorPosition.Y = (
SHORT)(ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y+1);
00737
Status =
WWSB_AdjustCursorPosition(ScreenInfo,CursorPosition,
00738 (
dwFlags &
WC_KEEP_CURSOR_VISIBLE) != 0,ScrollY);
00739
break;
00740
default:
00741
#ifdef WWSB_FE
00742
Char = *lpString;
00743
if (Char >= (WCHAR)
' ' &&
00744 IsConsoleFullWidth(ScreenInfo->Console->hDC,
00745 ScreenInfo->Console->OutputCP,Char) &&
00746 XPosition >= (ScreenInfo->ScreenBufferSize.X-1) &&
00747 (ScreenInfo->OutputMode & ENABLE_WRAP_AT_EOL_OUTPUT)) {
00748
00749
SHORT RowIndex;
00750
PROW Row;
00751 PWCHAR Char;
00752 COORD TargetPoint;
00753 PCHAR AttrP;
00754
00755 TargetPoint = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
00756 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->ScreenBufferSize.Y;
00757 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
00758 Char = &Row->
CharRow.
Chars[TargetPoint.X];
00759 AttrP = &Row->
CharRow.KAttrs[TargetPoint.X];
00760
00761
if (*AttrP & ATTR_TRAILING_BYTE)
00762 {
00763 *(Char-1) =
UNICODE_SPACE;
00764 *Char =
UNICODE_SPACE;
00765 *AttrP = 0;
00766 *(AttrP-1) = 0;
00767
00768 Region.Left = ScreenInfo->BufferInfo.TextInfo.CursorPosition.X-1;
00769 Region.Right = (
SHORT)(ScreenInfo->BufferInfo.TextInfo.CursorPosition.X);
00770 Region.Top = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y;
00771 Region.Bottom = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y;
00772
WWSB_WriteToScreen(ScreenInfo,&Region);
00773 }
00774
00775 CursorPosition.X = 0;
00776 CursorPosition.Y = (
SHORT)(ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y+1);
00777
Status =
WWSB_AdjustCursorPosition(ScreenInfo,CursorPosition,
00778
dwFlags &
WC_KEEP_CURSOR_VISIBLE,ScrollY);
00779
continue;
00780 }
00781
#endif
00782
break;
00783 }
00784
if (!
NT_SUCCESS(
Status)) {
00785
ConsoleShowCursor(ScreenInfo);
00786
goto ExitWriteChars;
00787 }
00788
00789 *NumBytes +=
sizeof(WCHAR);
00790 lpString++;
00791 lpRealUnicodeString++;
00792 }
00793
00794
if (ARGUMENT_PRESENT(NumSpaces)) {
00795 *NumSpaces = TempNumSpaces;
00796 }
00797
ConsoleShowCursor(ScreenInfo);
00798
00799
Status = STATUS_SUCCESS;
00800
00801 ExitWriteChars:
00802
if (lpAllocatedString) {
00803
ConsoleHeapFree(lpAllocatedString);
00804 }
00805
return Status;
00806 }
00807
00808 ULONG
00809 WWSB_DoWriteConsole(
00810 IN OUT PCSR_API_MSG m,
00811 IN
PCONSOLE_INFORMATION Console,
00812 IN PCSR_THREAD Thread
00813 )
00814
00815
00816
00817
00818
00819
00820
00821 {
00822
PCONSOLE_WRITECONSOLE_MSG a = (
PCONSOLE_WRITECONSOLE_MSG)&m->u.ApiMessageData;
00823
PHANDLE_DATA HandleData;
00824
NTSTATUS Status;
00825
PSCREEN_INFORMATION ScreenInfo;
00826
DWORD NumCharsToWrite;
00827
#ifdef WWSB_FE
00828
DWORD i;
00829
SHORT j;
00830
#endif
00831
00832
if (Console->Flags & (
CONSOLE_SUSPENDED |
CONSOLE_SELECTING |
CONSOLE_SCROLLBAR_TRACKING)) {
00833 PWCHAR TransBuffer;
00834
00835 TransBuffer = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),a->
NumBytes);
00836
if (TransBuffer ==
NULL) {
00837
return (ULONG)STATUS_NO_MEMORY;
00838 }
00839 RtlCopyMemory(TransBuffer,a->
TransBuffer,a->
NumBytes);
00840 a->
TransBuffer = TransBuffer;
00841 a->
StackBuffer =
FALSE;
00842
if (!CsrCreateWait(&Console->OutputQueue,
00843
WriteConsoleWaitRoutine,
00844 Thread,
00845 m,
00846
NULL,
00847
NULL
00848 )) {
00849
ConsoleHeapFree(TransBuffer);
00850
return (ULONG)STATUS_NO_MEMORY;
00851 }
00852
return (ULONG)
CONSOLE_STATUS_WAIT;
00853 }
00854
00855
Status =
DereferenceIoHandle(
CONSOLE_FROMTHREADPERPROCESSDATA(Thread),
00856 a->
OutputHandle,
00857
CONSOLE_OUTPUT_HANDLE,
00858 GENERIC_WRITE,
00859 &HandleData
00860 );
00861
if (!
NT_SUCCESS(
Status)) {
00862 a->
NumBytes = 0;
00863
return((ULONG)
Status);
00864 }
00865
00866 ScreenInfo = HandleData->
Buffer.ScreenBuffer;
00867
00868
00869
00870
00871
00872
00873
00874 NumCharsToWrite=a->
NumBytes/
sizeof(WCHAR);
00875
if ((ScreenInfo->
OutputMode & ENABLE_PROCESSED_OUTPUT) &&
00876 ((LONG)(ScreenInfo->
BufferInfo.TextInfo.CursorPosition.X + NumCharsToWrite) <
00877 ScreenInfo->
ScreenBufferSize.X) ) {
00878 SMALL_RECT Region;
00879 COORD CursorPosition;
00880
00881
if (a->
Unicode) {
00882
#ifdef WWSB_FE
00883
a->
WriteFlags =
WRITE_SPECIAL_CHARS;
00884
#else
00885
a->
WriteFlags =
FastStreamWrite(a->
TransBuffer,NumCharsToWrite);
00886
#endif
00887
}
00888
if (a->
WriteFlags ==
WRITE_SPECIAL_CHARS) {
00889
goto ProcessedWrite;
00890 }
00891
00892
ConsoleHideCursor(ScreenInfo);
00893
00894
00895
00896
00897
00898
00899 NumCharsToWrite -= a->
WriteFlags;
00900
00901
if (NumCharsToWrite) {
00902
#ifdef WWSB_FE
00903
PWCHAR TransBuffer,TransBufPtr,
String;
00904
PBYTE TransBufferA,TransBufPtrA;
00905
BOOL fLocalHeap =
FALSE;
00906 COORD TargetPoint;
00907
00908
if (NumCharsToWrite > (ULONG)(ScreenInfo->
ScreenBufferSize.X * ScreenInfo->
ScreenBufferSize.Y)) {
00909
00910 TransBuffer = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),NumCharsToWrite * 2 *
sizeof(WCHAR));
00911
if (TransBuffer ==
NULL) {
00912
return (ULONG)STATUS_NO_MEMORY;
00913 }
00914 TransBufferA = (PCHAR)
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),NumCharsToWrite * 2 *
sizeof(
CHAR));
00915
if (TransBufferA ==
NULL) {
00916
ConsoleHeapFree(TransBuffer);
00917
return (ULONG)STATUS_NO_MEMORY;
00918 }
00919
00920 fLocalHeap =
TRUE;
00921 }
00922
else {
00923 TransBuffer = ScreenInfo->
BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferCharacter;
00924 TransBufferA = ScreenInfo->
BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferAttribute;
00925 }
00926
00927
String = a->
TransBuffer;
00928 TransBufPtr = TransBuffer;
00929 TransBufPtrA = TransBufferA;
00930
for (i = 0 , j = 0 ; i < NumCharsToWrite ; i++,j++){
00931
if (IsConsoleFullWidth(ScreenInfo->
Console->
hDC,
00932 ScreenInfo->
Console->
OutputCP,*
String)){
00933 *TransBuffer++ = *
String ;
00934 *TransBufferA++ = ATTR_LEADING_BYTE;
00935 *TransBuffer++ = *
String++ ;
00936 *TransBufferA++ = ATTR_TRAILING_BYTE;
00937 j++;
00938 }
00939
else{
00940 *TransBuffer++ = *
String++ ;
00941 *TransBufferA++ = 0;
00942 }
00943 }
00944 TargetPoint = ScreenInfo->
BufferInfo.TextInfo.CursorPosition;
00945
BisectWrite(j,TargetPoint,ScreenInfo);
00946
if (TargetPoint.Y == ScreenInfo->
ScreenBufferSize.Y-1 &&
00947 TargetPoint.X+j >= ScreenInfo->
ScreenBufferSize.X &&
00948 *(TransBufPtrA+j) & ATTR_LEADING_BYTE){
00949 *(TransBufPtr+ScreenInfo->
ScreenBufferSize.X-TargetPoint.X-1) =
UNICODE_SPACE;
00950 *(TransBufPtrA+ScreenInfo->
ScreenBufferSize.X-TargetPoint.X-1) = 0;
00951
if (j > ScreenInfo->
ScreenBufferSize.X-TargetPoint.X-1) {
00952 *(TransBufPtr+ScreenInfo->
ScreenBufferSize.X-TargetPoint.X) =
UNICODE_SPACE;
00953 *(TransBufPtrA+ScreenInfo->
ScreenBufferSize.X-TargetPoint.X) = 0;
00954 }
00955 }
00956
FE_StreamWriteToScreenBuffer(TransBufPtr,
00957 (
SHORT)j,
00958 ScreenInfo,
00959 TransBufPtrA
00960 );
00961
if (fLocalHeap){
00962
ConsoleHeapFree(TransBufPtr);
00963
ConsoleHeapFree(TransBufPtrA);
00964 }
00965
#else
00966
SB_StreamWriteToScreenBuffer(a->
TransBuffer,
00967 (
SHORT)NumCharsToWrite,
00968 ScreenInfo
00969 );
00970
#endif
00971
Region.Left = ScreenInfo->
BufferInfo.TextInfo.CursorPosition.X;
00972
#ifdef WWSB_FE
00973
Region.Right = (
SHORT)(ScreenInfo->
BufferInfo.TextInfo.CursorPosition.X + j - 1);
00974
#else
00975
Region.Right = (
SHORT)(ScreenInfo->
BufferInfo.TextInfo.CursorPosition.X + NumCharsToWrite - 1);
00976
#endif
00977
Region.Top = ScreenInfo->
BufferInfo.TextInfo.CursorPosition.Y;
00978 Region.Bottom = ScreenInfo->
BufferInfo.TextInfo.CursorPosition.Y;
00979
ASSERT (Region.Right < ScreenInfo->
ScreenBufferSize.X);
00980
if (
ACTIVE_SCREEN_BUFFER(ScreenInfo) &&
00981 !(ScreenInfo->
Console->
Flags &
CONSOLE_IS_ICONIC && ScreenInfo->
Console->
FullScreenFlags == 0)) {
00982
WWSB_WriteRegionToScreen(ScreenInfo,&Region);
00983 }
00984 }
00985
switch (a->
WriteFlags) {
00986
case WRITE_NO_CR_LF:
00987 CursorPosition.X = (
SHORT)(ScreenInfo->
BufferInfo.TextInfo.CursorPosition.X + NumCharsToWrite);
00988 CursorPosition.Y = ScreenInfo->
BufferInfo.TextInfo.CursorPosition.Y;
00989
break;
00990
case WRITE_CR:
00991 CursorPosition.X = 0;
00992 CursorPosition.Y = ScreenInfo->
BufferInfo.TextInfo.CursorPosition.Y;
00993
break;
00994
case WRITE_CR_LF:
00995 CursorPosition.X = 0;
00996 CursorPosition.Y = ScreenInfo->
BufferInfo.TextInfo.CursorPosition.Y+1;
00997
break;
00998
default:
00999
ASSERT(
FALSE);
01000
break;
01001 }
01002
Status =
WWSB_AdjustCursorPosition(ScreenInfo,CursorPosition,
FALSE,
NULL);
01003
ConsoleShowCursor(ScreenInfo);
01004
return STATUS_SUCCESS;
01005 }
01006 ProcessedWrite:
01007
return WWSB_WriteChars(ScreenInfo,
01008 a->
TransBuffer,
01009 a->
TransBuffer,
01010 a->
TransBuffer,
01011 &a->
NumBytes,
01012
NULL,
01013 ScreenInfo->
BufferInfo.TextInfo.CursorPosition.X,
01014
WC_LIMIT_BACKSPACE,
01015
NULL
01016 );
01017 }
01018
01019
NTSTATUS
01020 WWSB_DoSrvWriteConsole(
01021 IN OUT PCSR_API_MSG m,
01022 IN OUT PCSR_REPLY_STATUS ReplyStatus,
01023 IN
PCONSOLE_INFORMATION Console,
01024 IN
PHANDLE_DATA HandleData
01025 )
01026 {
01027
NTSTATUS Status = STATUS_SUCCESS;
01028
PCONSOLE_WRITECONSOLE_MSG a = (
PCONSOLE_WRITECONSOLE_MSG)&m->u.ApiMessageData;
01029
PSCREEN_INFORMATION ScreenInfo;
01030 WCHAR StackBuffer[
STACK_BUFFER_SIZE];
01031
#ifdef WWSB_FE
01032
BOOL fLocalHeap =
FALSE;
01033
#endif
01034
01035 ScreenInfo = HandleData->Buffer.ScreenBuffer;
01036
01037
#ifdef WWSB_FE
01038
01039
ASSERT(!(ScreenInfo->
Flags &
CONSOLE_GRAPHICS_BUFFER));
01040
#endif
01041
01042
01043
01044
01045
01046
01047
if (a->
BufferInMessage) {
01048 a->
BufPtr = a->
Buffer;
01049 }
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
if (!a->
Unicode) {
01061 PWCHAR TransBuffer;
01062
DWORD Length;
01063
DWORD SpecialChars = 0;
01064
UINT Codepage;
01065
#ifdef WWSB_FE
01066
PWCHAR TmpTransBuffer;
01067 ULONG NumBytes1 = 0;
01068 ULONG NumBytes2 = 0;
01069
#endif
01070
01071
if (a->
NumBytes <=
STACK_BUFFER_SIZE) {
01072 TransBuffer = StackBuffer;
01073 a->
StackBuffer =
TRUE;
01074
#ifdef WWSB_FE
01075
TmpTransBuffer = TransBuffer;
01076
#endif
01077
}
01078
#ifdef WWSB_FE
01079
else if (a->
NumBytes > (ULONG)(ScreenInfo->
ScreenBufferSize.X * ScreenInfo->
ScreenBufferSize.Y)) {
01080 TransBuffer = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),(a->
NumBytes+2) *
sizeof(WCHAR));
01081
if (TransBuffer ==
NULL) {
01082
return (ULONG)STATUS_NO_MEMORY;
01083 }
01084 TmpTransBuffer = TransBuffer;
01085 a->
StackBuffer =
FALSE;
01086 fLocalHeap =
TRUE;
01087 }
01088
else {
01089 TransBuffer = ScreenInfo->
BufferInfo.TextInfo.DbcsScreenBuffer.TransWriteConsole;
01090 TmpTransBuffer = TransBuffer;
01091 }
01092
#else
01093
else {
01094 TransBuffer = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),a->
NumBytes *
sizeof(WCHAR));
01095
if (TransBuffer ==
NULL) {
01096
return (ULONG)STATUS_NO_MEMORY;
01097 }
01098 a->
StackBuffer =
FALSE;
01099 }
01100
#endif
01101
01102
01103
01104
01105
01106
01107
#ifdef WWSB_FE
01108
if (! ScreenInfo->WriteConsoleDbcsLeadByte[0]) {
01109 NumBytes1 = 0;
01110 NumBytes2 = a->
NumBytes;
01111 }
01112
else {
01113
if (*(PUCHAR)a->
BufPtr < (UCHAR)
' ') {
01114 NumBytes1 = 0;
01115 NumBytes2 = a->
NumBytes;
01116 }
01117
else if (a->
NumBytes) {
01118 ScreenInfo->WriteConsoleDbcsLeadByte[1] = *(PCHAR)a->
BufPtr;
01119 NumBytes1 =
sizeof(ScreenInfo->WriteConsoleDbcsLeadByte);
01120
if (Console->OutputCP ==
OEMCP) {
01121
if ((ScreenInfo->
Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01122 ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) == 0)) {
01123
01124
01125
01126
01127
01128
01129
01130
01131
DBGCHARS((
"SrvWriteConsole ACP->U %.*s\n",
01132
min(NumBytes1,10), a->
BufPtr));
01133
Status =
RtlConsoleMultiByteToUnicodeN(TransBuffer,
01134 NumBytes1 *
sizeof(WCHAR), &NumBytes1,
01135 ScreenInfo->WriteConsoleDbcsLeadByte, NumBytes1, &SpecialChars);
01136 }
else {
01137
01138
01139
01140
01141
01142
DBGCHARS((
"SrvWriteConsole %d->U %.*s\n", Console->OutputCP,
01143
min(NumBytes1,10), a->
BufPtr));
01144 NumBytes1 =
sizeof(WCHAR) * MultiByteToWideChar(Console->OutputCP,
01145 0, ScreenInfo->WriteConsoleDbcsLeadByte, NumBytes1, TransBuffer, NumBytes1);
01146
if (NumBytes1 == 0) {
01147
Status = STATUS_UNSUCCESSFUL;
01148 }
01149 }
01150 }
01151
else {
01152
if ((ScreenInfo->
Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01153 !(Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
01154
if (Console->OutputCP !=
WINDOWSCP)
01155 Codepage =
USACP;
01156
else
01157 Codepage =
WINDOWSCP;
01158 }
else {
01159 Codepage = Console->OutputCP;
01160 }
01161
01162
if ((ScreenInfo->
Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01163 ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) == 0)) {
01164 NumBytes1 =
ConvertOutputToUnicode(Codepage,
01165 ScreenInfo->WriteConsoleDbcsLeadByte,
01166 NumBytes1,
01167 TransBuffer,
01168 NumBytes1);
01169 }
01170
else {
01171 NumBytes1 = MultiByteToWideChar(Console->OutputCP,
01172 0, ScreenInfo->WriteConsoleDbcsLeadByte, NumBytes1, TransBuffer, NumBytes1);
01173
if (NumBytes1 == 0) {
01174
Status = STATUS_UNSUCCESSFUL;
01175 }
01176 }
01177 NumBytes1 *=
sizeof(WCHAR);
01178 }
01179 TransBuffer++;
01180 (PCHAR)a->
BufPtr += (NumBytes1 /
sizeof(WCHAR));
01181 NumBytes2 = a->
NumBytes - 1;
01182 }
01183
else {
01184 NumBytes2 = 0;
01185 }
01186 ScreenInfo->WriteConsoleDbcsLeadByte[0] = 0;
01187 }
01188
01189
if (NumBytes2 &&
01190
CheckBisectStringA(Console->OutputCP,a->
BufPtr,NumBytes2,&Console->OutputCPInfo)) {
01191 ScreenInfo->WriteConsoleDbcsLeadByte[0] = *((PCHAR)a->
BufPtr+NumBytes2-1);
01192 NumBytes2--;
01193 }
01194
01195 Length = NumBytes2;
01196
#else
01197
Length = a->
NumBytes;
01198
if (a->
NumBytes >= 2 &&
01199 ((PCHAR)a->
BufPtr)[a->
NumBytes-1] ==
'\n' &&
01200 ((PCHAR)a->
BufPtr)[a->
NumBytes-2] ==
'\r') {
01201 Length -= 2;
01202 a->
WriteFlags =
WRITE_CR_LF;
01203 }
else if (a->
NumBytes >= 1 &&
01204 ((PCHAR)a->
BufPtr)[a->
NumBytes-1] ==
'\r') {
01205 Length -= 1;
01206 a->
WriteFlags =
WRITE_CR;
01207 }
else {
01208 a->
WriteFlags =
WRITE_NO_CR_LF;
01209 }
01210
#endif
01211
01212
if (Length != 0) {
01213
if (Console->OutputCP ==
OEMCP) {
01214
if ((ScreenInfo->
Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01215 ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) == 0)) {
01216
01217
01218
01219
01220
01221
01222
01223
01224
DBGCHARS((
"SrvWriteConsole ACP->U %.*s\n",
01225
min(Length,10), a->
BufPtr));
01226
Status =
RtlConsoleMultiByteToUnicodeN(TransBuffer,
01227 Length *
sizeof(WCHAR), &Length,
01228 a->
BufPtr, Length, &SpecialChars);
01229 }
else {
01230
01231
01232
01233
01234
01235
#ifdef WWSB_NOFE
01236
UINT i;
01237
for (i = 0; i < Length; i++) {
01238
if (((PCHAR)a->
BufPtr)[i] < 0x20) {
01239 SpecialChars = 1;
01240
break;
01241 }
01242 }
01243
#endif
01244
DBGCHARS((
"SrvWriteConsole %d->U %.*s\n", Console->OutputCP,
01245
min(Length,10), a->
BufPtr));
01246 Length =
sizeof(WCHAR) * MultiByteToWideChar(Console->OutputCP,
01247 0, a->
BufPtr, Length, TransBuffer, Length);
01248
if (Length == 0) {
01249
Status = STATUS_UNSUCCESSFUL;
01250 }
01251 }
01252 }
01253
else
01254 {
01255
if ((ScreenInfo->
Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01256 !(Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
01257
if (Console->OutputCP !=
WINDOWSCP)
01258 Codepage =
USACP;
01259
else
01260 Codepage =
WINDOWSCP;
01261 }
else {
01262 Codepage = Console->OutputCP;
01263 }
01264
01265
if ((ScreenInfo->
Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01266 ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) == 0)) {
01267 Length =
sizeof(WCHAR) *
ConvertOutputToUnicode(Codepage,
01268 a->
BufPtr,
01269 Length,
01270 TransBuffer,
01271 Length);
01272 }
01273
else {
01274 Length =
sizeof(WCHAR) * MultiByteToWideChar(Console->OutputCP,
01275 0, a->
BufPtr, Length, TransBuffer, Length);
01276
if (Length == 0) {
01277
Status = STATUS_UNSUCCESSFUL;
01278 }
01279 }
01280
01281
#ifdef WWSB_NOFE
01282
SpecialChars = 1;
01283
#endif
01284
}
01285 }
01286
01287
#ifdef WWSB_FE
01288
NumBytes2 = Length;
01289
01290
if ((NumBytes1+NumBytes2) == 0) {
01291
if (!a->
StackBuffer && fLocalHeap) {
01292
ConsoleHeapFree(a->
TransBuffer);
01293 }
01294
return Status;
01295 }
01296
#else
01297
if (!
NT_SUCCESS(
Status)) {
01298
if (!a->
StackBuffer) {
01299
ConsoleHeapFree(TransBuffer);
01300 }
01301
return Status;
01302 }
01303
#endif
01304
01305
#ifdef WWSB_FE
01306
Console->WriteConOutNumBytesTemp = a->
NumBytes;
01307 a->
NumBytes = Console->WriteConOutNumBytesUnicode = NumBytes1 + NumBytes2;
01308 a->
WriteFlags =
WRITE_SPECIAL_CHARS;
01309 a->
TransBuffer = TmpTransBuffer;
01310
#else
01311
DBGOUTPUT((
"TransBuffer=%lx, Length = %x(bytes), SpecialChars=%lx\n",
01312 TransBuffer, Length, SpecialChars));
01313 a->
NumBytes = Length + (a->
WriteFlags *
sizeof(WCHAR));
01314
if (a->
WriteFlags ==
WRITE_CR_LF) {
01315 TransBuffer[(Length+
sizeof(WCHAR))/
sizeof(WCHAR)] =
UNICODE_LINEFEED;
01316 TransBuffer[Length/
sizeof(WCHAR)] =
UNICODE_CARRIAGERETURN;
01317 }
else if (a->
WriteFlags ==
WRITE_CR) {
01318 TransBuffer[Length/
sizeof(WCHAR)] =
UNICODE_CARRIAGERETURN;
01319 }
01320
if (SpecialChars) {
01321
01322 a->
WriteFlags =
WRITE_SPECIAL_CHARS;
01323 }
01324 a->
TransBuffer = TransBuffer;
01325
#endif
01326
}
else {
01327
if ((ScreenInfo->
Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01328 ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) == 0)) {
01329
Status =
RealUnicodeToFalseUnicode(a->
BufPtr,
01330 a->
NumBytes /
sizeof(WCHAR), Console->OutputCP);
01331
if (!
NT_SUCCESS(
Status)) {
01332
return Status;
01333 }
01334 }
01335 a->
WriteFlags = (
DWORD)-1;
01336 a->
TransBuffer = a->
BufPtr;
01337 }
01338
Status =
WWSB_DoWriteConsole(m,Console,CSR_SERVER_QUERYCLIENTTHREAD());
01339
if (
Status ==
CONSOLE_STATUS_WAIT) {
01340 *ReplyStatus = CsrReplyPending;
01341
return (ULONG)STATUS_SUCCESS;
01342 }
else {
01343
if (!a->
Unicode) {
01344
#ifdef WWSB_FE
01345
if (a->
NumBytes == Console->WriteConOutNumBytesUnicode)
01346 a->
NumBytes = Console->WriteConOutNumBytesTemp;
01347
else
01348 a->
NumBytes /=
sizeof(WCHAR);
01349
if (!a->
StackBuffer && fLocalHeap) {
01350
ConsoleHeapFree(a->
TransBuffer);
01351 }
01352
#else
01353
a->
NumBytes /=
sizeof(WCHAR);
01354
if (!a->
StackBuffer) {
01355
ConsoleHeapFree(a->
TransBuffer);
01356 }
01357
#endif
01358
}
01359 }
01360
return Status;
01361 }