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

_stream.h File Reference

Go to the source code of this file.

Defines

#define WWSB_NEUTRAL_FILE   1
#define LOCAL_BUFFER_SIZE   100

Functions

NTSTATUS WWSB_AdjustCursorPosition (IN PSCREEN_INFORMATION ScreenInfo, IN COORD CursorPosition, IN BOOL KeepCursorVisible, OUT PSHORT ScrollY OPTIONAL)
NTSTATUS WWSB_WriteChars (IN PSCREEN_INFORMATION ScreenInfo, IN PWCHAR lpBufferBackupLimit, IN PWCHAR lpBuffer, IN PWCHAR lpRealUnicodeString, IN OUT PDWORD NumBytes, OUT PLONG NumSpaces OPTIONAL, IN SHORT OriginalXPosition, IN DWORD dwFlags, OUT PSHORT ScrollY OPTIONAL)
ULONG WWSB_DoWriteConsole (IN OUT PCSR_API_MSG m, IN PCONSOLE_INFORMATION Console, IN PCSR_THREAD Thread)
NTSTATUS WWSB_DoSrvWriteConsole (IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus, IN PCONSOLE_INFORMATION Console, IN PHANDLE_DATA HandleData)


Define Documentation

#define LOCAL_BUFFER_SIZE   100
 

Definition at line 200 of file _stream.h.

Referenced by WWSB_WriteChars().

#define WWSB_NEUTRAL_FILE   1
 

Definition at line 23 of file _stream.h.


Function Documentation

NTSTATUS WWSB_AdjustCursorPosition IN PSCREEN_INFORMATION  ScreenInfo,
IN COORD  CursorPosition,
IN BOOL  KeepCursorVisible,
OUT PSHORT ScrollY  OPTIONAL
 

Definition at line 46 of file _stream.h.

References ASSERT, CONSOLE_TEXTMODE_BUFFER, CONSOLE_WINDOW_SIZE_Y, FALSE, _CONSOLE_INFORMATION::InputBuffer, MakeCursorVisible(), NT_SUCCESS, NTSTATUS(), PCOOKED_READ_DATA, PSHORT, SetCursorPosition(), SetWindowOrigin(), SHORT, Status, and StreamScrollRegion().

Referenced by WWSB_DoWriteConsole(), and WWSB_WriteChars().

00055 : 00056 00057 This routine updates the cursor position. Its input is the non-special 00058 cased new location of the cursor. For example, if the cursor were being 00059 moved one space backwards from the left edge of the screen, the X 00060 coordinate would be -1. This routine would set the X coordinate to 00061 the right edge of the screen and decrement the Y coordinate by one. 00062 00063 Arguments: 00064 00065 ScreenInfo - Pointer to screen buffer information structure. 00066 00067 CursorPosition - New location of cursor. 00068 00069 KeepCursorVisible - TRUE if changing window origin desirable when hit right edge 00070 00071 Return Value: 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 // at end of line. if wrap mode, wrap cursor. otherwise leave it 00098 // where it is. 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 // at end of buffer. scroll contents of screen buffer so new 00120 // position is visible. 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 // if at right or bottom edge of window, scroll right or down one char. 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 }

NTSTATUS WWSB_DoSrvWriteConsole IN OUT PCSR_API_MSG  m,
IN OUT PCSR_REPLY_STATUS  ReplyStatus,
IN PCONSOLE_INFORMATION  Console,
IN PHANDLE_DATA  HandleData
 

Definition at line 1020 of file _stream.h.

References ASSERT, BOOL, _CONSOLE_WRITECONSOLE_MSG::Buffer, _SCREEN_INFORMATION::BufferInfo, _CONSOLE_WRITECONSOLE_MSG::BufferInMessage, _CONSOLE_WRITECONSOLE_MSG::BufPtr, CheckBisectStringA(), CONSOLE_GRAPHICS_BUFFER, CONSOLE_OEMFONT_DISPLAY, CONSOLE_STATUS_WAIT, ConsoleHeapAlloc, ConsoleHeapFree, ConvertOutputToUnicode(), DBGCHARS, DBGOUTPUT, DWORD, FALSE, _SCREEN_INFORMATION::Flags, MAKE_TAG, min, NT_SUCCESS, NTSTATUS(), NULL, _CONSOLE_WRITECONSOLE_MSG::NumBytes, OEMCP, RealUnicodeToFalseUnicode(), RtlConsoleMultiByteToUnicodeN(), _SCREEN_INFORMATION::ScreenBufferSize, STACK_BUFFER_SIZE, _CONSOLE_WRITECONSOLE_MSG::StackBuffer, Status, TMP_TAG, _CONSOLE_WRITECONSOLE_MSG::TransBuffer, TRUE, UINT, _CONSOLE_WRITECONSOLE_MSG::Unicode, UNICODE_CARRIAGERETURN, UNICODE_LINEFEED, USACP, WINDOWSCP, WRITE_CR, WRITE_CR_LF, WRITE_NO_CR_LF, WRITE_SPECIAL_CHARS, _CONSOLE_WRITECONSOLE_MSG::WriteFlags, and WWSB_DoWriteConsole().

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 // Check code for must CONSOLE_TEXTMODE_BUFFER !! 01039 ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER)); 01040 #endif 01041 01042 // 01043 // if the string was passed in the message, rather than in 01044 // a capture buffer, adjust the pointer. 01045 // 01046 01047 if (a->BufferInMessage) { 01048 a->BufPtr = a->Buffer; 01049 } 01050 01051 // 01052 // if ansi, translate string. for speed, we don't allocate a 01053 // capture buffer if the ansi string was <= 80 chars. if it's 01054 // greater than 80 / sizeof(WCHAR), the translated string won't 01055 // fit into the capture buffer, so reset a->BufPtr to point to 01056 // a heap buffer and set a->CaptureBufferSize so that we don't 01057 // think the buffer is in the message. 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 //a->NumBytes = ConvertOutputToUnicode(Console->OutputCP, 01102 // Buffer, 01103 // a->NumBytes, 01104 // TransBuffer, 01105 // a->NumBytes); 01106 // same as ConvertOutputToUnicode 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 * Translate OEM characters into False Unicode for Window-mode 01125 * OEM font. If OutputCP != OEMCP, characters will not appear 01126 * correctly, because the OEM fonts are designed to support 01127 * only OEMCP (we can't switch fonts in Windowed mode). 01128 * Fullscreen or TT "Unicode" fonts should be used for 01129 * non-OEMCP output 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 * Good! We have Fullscreen or TT "Unicode" fonts, so convert 01139 * the OEM characters to real Unicode according to OutputCP. 01140 * First find out if any special chars are involved. 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 * Translate OEM characters into UnicodeOem for the Window-mode 01218 * OEM font. If OutputCP != OEMCP, characters will not appear 01219 * correctly, because the OEM fonts are designed to support 01220 * only OEMCP (we can't switch fonts in Windowed mode). 01221 * Fullscreen or TT "Unicode" fonts should be used for 01222 * non-OEMCP output 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 * Good! We have Fullscreen or TT "Unicode" fonts, so convert 01232 * the OEM characters to real Unicode according to OutputCP. 01233 * First find out if any special chars are involved. 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 // CRLF didn't get translated 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 }

ULONG WWSB_DoWriteConsole IN OUT PCSR_API_MSG  m,
IN PCONSOLE_INFORMATION  Console,
IN PCSR_THREAD  Thread
 

Definition at line 809 of file _stream.h.

References ACTIVE_SCREEN_BUFFER, ASSERT, BisectWrite(), BOOL, _HANDLE_DATA::Buffer, _SCREEN_INFORMATION::BufferInfo, CHAR, _SCREEN_INFORMATION::Console, CONSOLE_FROMTHREADPERPROCESSDATA, CONSOLE_IS_ICONIC, CONSOLE_OUTPUT_HANDLE, CONSOLE_SCROLLBAR_TRACKING, CONSOLE_SELECTING, CONSOLE_STATUS_WAIT, CONSOLE_SUSPENDED, ConsoleHeapAlloc, ConsoleHeapFree, ConsoleHideCursor(), ConsoleShowCursor(), DereferenceIoHandle(), DWORD, FALSE, FastStreamWrite(), FE_StreamWriteToScreenBuffer(), _CONSOLE_INFORMATION::Flags, _CONSOLE_INFORMATION::FullScreenFlags, _CONSOLE_INFORMATION::hDC, MAKE_TAG, NT_SUCCESS, NTSTATUS(), NULL, _CONSOLE_WRITECONSOLE_MSG::NumBytes, _CONSOLE_INFORMATION::OutputCP, _CONSOLE_WRITECONSOLE_MSG::OutputHandle, _SCREEN_INFORMATION::OutputMode, PBYTE, PCONSOLE_WRITECONSOLE_MSG, PHANDLE_DATA, SB_StreamWriteToScreenBuffer(), _SCREEN_INFORMATION::ScreenBufferSize, SHORT, _CONSOLE_WRITECONSOLE_MSG::StackBuffer, Status, String, TMP_TAG, _CONSOLE_WRITECONSOLE_MSG::TransBuffer, TRUE, _CONSOLE_WRITECONSOLE_MSG::Unicode, UNICODE_SPACE, WC_LIMIT_BACKSPACE, WRITE_CR, WRITE_CR_LF, WRITE_NO_CR_LF, WRITE_SPECIAL_CHARS, WriteConsoleWaitRoutine(), _CONSOLE_WRITECONSOLE_MSG::WriteFlags, WWSB_AdjustCursorPosition(), WWSB_WriteChars(), and WWSB_WriteRegionToScreen().

Referenced by WWSB_DoSrvWriteConsole().

00816 : console lock must be held when calling this routine 00817 // 00818 // string has been translated to unicode at this point 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 // see if we're the typical case - a string containing no special 00870 // characters, optionally terminated with CRLF. if so, skip the 00871 // special processing. 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 // WriteFlags is designed so that the number of special characters 00896 // is also the flag value. 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 }

NTSTATUS WWSB_WriteChars IN PSCREEN_INFORMATION  ScreenInfo,
IN PWCHAR  lpBufferBackupLimit,
IN PWCHAR  lpBuffer,
IN PWCHAR  lpRealUnicodeString,
IN OUT PDWORD  NumBytes,
OUT PLONG NumSpaces  OPTIONAL,
IN SHORT  OriginalXPosition,
IN DWORD  dwFlags,
OUT PSHORT ScrollY  OPTIONAL
 

Definition at line 203 of file _stream.h.

References ASSERT, BOOL, BufferSize, CHAR, _ROW::CharRow, _CHAR_ROW::Chars, CM_BEEP, CONSOLE_ATTRIBUTE, CONSOLE_FALSE_UNICODE, CONSOLE_OEMFONT_DISPLAY, ConsoleHeapAlloc, ConsoleHeapFree, ConsoleHideCursor(), ConsoleShowCursor(), ConvertOutputToUnicode(), dwFlags, DWORD, FE_StreamWriteToScreenBuffer(), IS_CONTROL_CHAR, IS_GLYPH_CHAR, LOCAL_BUFFER_SIZE, MAKE_TAG, NT_SUCCESS, NTSTATUS(), NULL, NUMBER_OF_SPACES_IN_TAB, RealUnicodeToFalseUnicode(), RetrieveNumberOfSpaces(), SB_StreamWriteToScreenBuffer(), SendNotifyMessage(), SHORT, Status, TAB_SIZE, TMP_TAG, UNICODE_BACKSPACE, UNICODE_BELL, UNICODE_CARRIAGERETURN, UNICODE_LINEFEED, UNICODE_SPACE, UNICODE_TAB, WC_DESTRUCTIVE_BACKSPACE, WC_ECHO, WC_FALSIFY_UNICODE, WC_KEEP_CURSOR_VISIBLE, WC_LIMIT_BACKSPACE, WWSB_AdjustCursorPosition(), WWSB_FillOutput(), WWSB_WriteOutputString(), and WWSB_WriteToScreen().

Referenced by WWSB_DoWriteConsole().

00217 : 00218 00219 This routine writes a string to the screen, processing any embedded 00220 unicode characters. The string is also copied to the input buffer, if 00221 the output mode is line mode. 00222 00223 Arguments: 00224 00225 ScreenInfo - Pointer to screen buffer information structure. 00226 00227 lpBufferBackupLimit - Pointer to beginning of buffer. 00228 00229 lpBuffer - Pointer to buffer to copy string to. assumed to be at least 00230 as long as lpRealUnicodeString. This pointer is updated to point to the 00231 next position in the buffer. 00232 00233 lpRealUnicodeString - Pointer to string to write. 00234 00235 NumBytes - On input, number of bytes to write. On output, number of 00236 bytes written. 00237 00238 NumSpaces - On output, the number of spaces consumed by the written characters. 00239 00240 dwFlags - 00241 WC_DESTRUCTIVE_BACKSPACE backspace overwrites characters. 00242 WC_KEEP_CURSOR_VISIBLE change window origin desirable when hit rt. edge 00243 WC_ECHO if called by Read (echoing characters) 00244 WC_FALSIFY_UNICODE if RealUnicodeToFalseUnicode need be called. 00245 00246 Return Value: 00247 00248 Note: 00249 00250 This routine does not process tabs and backspace properly. That code 00251 will be implemented as part of the line editing services. 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 // translation from OEM -> ANSI -> OEM doesn't 00296 // necessarily yield the same value, so do 00297 // translation in a separate buffer. 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 // as an optimization, collect characters in buffer and 00322 // print out all at once. 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 // automatically go to EndWhile. this is because 00380 // backspace is not destructive, so "aBkSp" prints 00381 // a with the cursor on the "a". we could achieve 00382 // this behavior staying in this loop and figuring out 00383 // the string that needs to be printed, but it would 00384 // be expensive and it's the exceptional case. 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 // if char is ctrl char, write ^char. 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 * As a special favor to incompetent apps 00437 * that attempt to display control chars, 00438 * convert to corresponding OEM Glyph Chars 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 // Make sure we don't write past the end of the buffer. 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 // this catches the case where the number of backspaces == 00520 // the number of characters. 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 // move cursor backwards one space. overwrite current char with blank. 00535 // 00536 // we get here because we have to backspace from the beginning of the line 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 // overwrite second character of ^x sequence. 00603 // 00604 00605 if (dwFlags & WC_DESTRUCTIVE_BACKSPACE) { 00606 NumChars = 1; 00607 Status = WWSB_WriteOutputString(ScreenInfo, 00608 Blanks, CursorPosition, 00609 CONSOLE_FALSE_UNICODE, // faster than real 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) { // bug 7672 00627 NumChars = 1; 00628 Status = WWSB_WriteOutputString(ScreenInfo, 00629 Blanks, ScreenInfo->BufferInfo.TextInfo.CursorPosition, 00630 CONSOLE_FALSE_UNICODE, // faster than real 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, //faster than real 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 // move cursor forward to next tab stop. fill space with blanks. 00684 // we get here when the tab extends beyond the right edge of the 00685 // window. if the tab goes wraps the line, set the cursor to the first 00686 // position in the next line. 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, // faster than real 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 // Carriage return moves the cursor to the beginning of the line. 00718 // We don't need to worry about handling cr or lf for 00719 // backspace because input is sent to the user on cr or lf. 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 // move cursor to the beginning of the next line. 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 }


Generated on Sat May 15 19:42:48 2004 for test by doxygen 1.3.7