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

stream.c File Reference

#include "precomp.h"

Go to the source code of this file.

Defines

#define IS_CONTROL_CHAR(wch)   ((wch) < L' ')
#define IS_GLYPH_CHAR(wch)   (((wch) < L' ') || ((wch) == 0x007F))
#define LINE_INPUT_BUFFER_SIZE   (256 * sizeof(WCHAR))
#define CONSOLE_CTRL_2   0x0
#define EITHER_CTRL_PRESSED   (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
#define EITHER_ALT_PRESSED   (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)
#define MOD_PRESSED   (SHIFT_PRESSED | EITHER_CTRL_PRESSED | EITHER_ALT_PRESSED)
#define KEYEVENTSTATE_EQUAL_WINMODS(Event, WinMods)
#define WRITE_NO_CR_LF   0
#define WRITE_CR   1
#define WRITE_CR_LF   2
#define WRITE_SPECIAL_CHARS   4
#define WRITE_UNICODE_CRLF   0x000a000d

Functions

NTSTATUS WaitForMoreToRead (IN PINPUT_INFORMATION InputInformation, IN PCSR_API_MSG Message OPTIONAL, IN CSR_WAIT_ROUTINE WaitRoutine OPTIONAL, IN PVOID WaitParameter OPTIONAL, IN ULONG WaitParameterLength OPTIONAL, IN BOOLEAN WaitBlockExists OPTIONAL)
BOOLEAN WriteConsoleWaitRoutine (IN PLIST_ENTRY WaitQueue, IN PCSR_THREAD WaitingThread, IN PCSR_API_MSG WaitReplyMessage, IN PVOID WaitParameter, IN PVOID SatisfyParameter1, IN PVOID SatisfyParameter2, IN ULONG WaitFlags)
HANDLE FindActiveScreenBufferHandle (IN PCONSOLE_PER_PROCESS_DATA ProcessData, IN PCONSOLE_INFORMATION Console)
ULONG SrvOpenConsole (IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus)
BOOL IsDbcsExemptionForHighAnsi (UINT wCodePage, WORD wNumpadChar)
NTSTATUS GetChar (IN PINPUT_INFORMATION InputInfo, OUT PWCHAR Char, IN BOOLEAN Wait, IN PCONSOLE_INFORMATION Console, IN PHANDLE_DATA HandleData, IN PCSR_API_MSG Message OPTIONAL, IN CSR_WAIT_ROUTINE WaitRoutine OPTIONAL, IN PVOID WaitParameter OPTIONAL, IN ULONG WaitParameterLength OPTIONAL, IN BOOLEAN WaitBlockExists OPTIONAL, OUT PBOOLEAN CommandLineEditingKeys OPTIONAL, OUT PBOOLEAN CommandLinePopupKeys OPTIONAL, OUT PBOOLEAN EnableScrollMode OPTIONAL, OUT PDWORD KeyState OPTIONAL)
BOOLEAN RawReadWaitRoutine (IN PLIST_ENTRY WaitQueue, IN PCSR_THREAD WaitingThread, IN PCSR_API_MSG WaitReplyMessage, IN PVOID WaitParameter, IN PVOID SatisfyParameter1, IN PVOID SatisfyParameter2, IN ULONG WaitFlags)
ULONG RetrieveTotalNumberOfSpaces (IN SHORT OriginalCursorPositionX, IN PWCHAR Buffer, IN ULONG CurrentPosition)
ULONG RetrieveNumberOfSpaces (IN SHORT OriginalCursorPositionX, IN PWCHAR Buffer, IN ULONG CurrentPosition)
BOOL ProcessCookedReadInput (IN PCOOKED_READ_DATA CookedReadData, IN WCHAR Char, IN DWORD KeyState, OUT PNTSTATUS Status)
NTSTATUS CookedRead (IN PCOOKED_READ_DATA CookedReadData, IN PCSR_API_MSG WaitReplyMessage, IN PCSR_THREAD WaitingThread, IN BOOLEAN WaitRoutine)
BOOLEAN CookedReadWaitRoutine (IN PLIST_ENTRY WaitQueue, IN PCSR_THREAD WaitingThread, IN PCSR_API_MSG WaitReplyMessage, IN PVOID WaitParameter, IN PVOID SatisfyParameter1, IN PVOID SatisfyParameter2, IN ULONG WaitFlags)
NTSTATUS ReadChars (IN PINPUT_INFORMATION InputInfo, IN PCONSOLE_INFORMATION Console, IN PCONSOLE_PER_PROCESS_DATA ProcessData, IN PSCREEN_INFORMATION ScreenInfo, IN OUT PWCHAR lpBuffer, IN OUT PDWORD NumBytes, IN DWORD InitialNumBytes, IN DWORD CtrlWakeupMask, IN PHANDLE_DATA HandleData, IN PCOMMAND_HISTORY CommandHistory, IN PCSR_API_MSG Message OPTIONAL, IN HANDLE HandleIndex, IN USHORT ExeNameLength, IN PWCHAR ExeName, IN BOOLEAN Unicode)
ULONG SrvReadConsole (IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus)
VOID MakeCursorVisible (IN PSCREEN_INFORMATION ScreenInfo, IN COORD CursorPosition)
DWORD FastStreamWrite (IN PWCHAR lpString, IN DWORD NumChars)
VOID UnblockWriteConsole (IN PCONSOLE_INFORMATION Console, IN DWORD Reason)
ULONG SrvWriteConsole (IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus)
ULONG SrvDuplicateHandle (IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus)
ULONG SrvGetHandleInformation (IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus)
ULONG SrvSetHandleInformation (IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus)
NTSTATUS CloseInputHandle (IN PCONSOLE_PER_PROCESS_DATA ProcessData, IN PCONSOLE_INFORMATION Console, IN PHANDLE_DATA HandleData, IN HANDLE Handle)
NTSTATUS CloseOutputHandle (IN PCONSOLE_PER_PROCESS_DATA ProcessData, IN PCONSOLE_INFORMATION Console, IN PHANDLE_DATA HandleData, IN HANDLE Handle, IN BOOLEAN FreeHandle)
ULONG SrvCloseHandle (IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus)
NTSTATUS WriteCharsFromInput (IN PSCREEN_INFORMATION ScreenInfo, IN PWCHAR lpBufferBackupLimit, IN PWCHAR lpBuffer, IN PWCHAR lpString, IN OUT PDWORD NumBytes, OUT PLONG NumSpaces OPTIONAL, IN SHORT OriginalXPosition, IN DWORD dwFlags, OUT PSHORT ScrollY OPTIONAL)

Variables

DWORD ConsKbdState []


Define Documentation

#define CONSOLE_CTRL_2   0x0
 

Definition at line 29 of file server/stream.c.

#define EITHER_ALT_PRESSED   (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)
 

Definition at line 215 of file server/stream.c.

#define EITHER_CTRL_PRESSED   (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
 

Definition at line 214 of file server/stream.c.

#define IS_CONTROL_CHAR wch   )     ((wch) < L' ')
 

Definition at line 24 of file server/stream.c.

Referenced by RetrieveNumberOfSpaces(), RetrieveTotalNumberOfSpaces(), and WWSB_WriteChars().

#define IS_GLYPH_CHAR wch   )     (((wch) < L' ') || ((wch) == 0x007F))
 

Definition at line 25 of file server/stream.c.

Referenced by WWSB_WriteChars().

#define KEYEVENTSTATE_EQUAL_WINMODS Event,
WinMods   ) 
 

Value:

((Event.Event.KeyEvent.dwControlKeyState & ConsKbdState[WinMods]) && \ !(Event.Event.KeyEvent.dwControlKeyState & MOD_PRESSED & ~ConsKbdState[WinMods]))

Definition at line 229 of file server/stream.c.

Referenced by GetChar().

#define LINE_INPUT_BUFFER_SIZE   (256 * sizeof(WCHAR))
 

Definition at line 27 of file server/stream.c.

Referenced by ReadChars().

#define MOD_PRESSED   (SHIFT_PRESSED | EITHER_CTRL_PRESSED | EITHER_ALT_PRESSED)
 

Definition at line 216 of file server/stream.c.

#define WRITE_CR   1
 

Definition at line 2382 of file server/stream.c.

Referenced by FastStreamWrite(), WWSB_DoSrvWriteConsole(), and WWSB_DoWriteConsole().

#define WRITE_CR_LF   2
 

Definition at line 2383 of file server/stream.c.

Referenced by FastStreamWrite(), WWSB_DoSrvWriteConsole(), and WWSB_DoWriteConsole().

#define WRITE_NO_CR_LF   0
 

Definition at line 2381 of file server/stream.c.

Referenced by FastStreamWrite(), WWSB_DoSrvWriteConsole(), and WWSB_DoWriteConsole().

#define WRITE_SPECIAL_CHARS   4
 

Definition at line 2384 of file server/stream.c.

Referenced by FastStreamWrite(), WWSB_DoSrvWriteConsole(), and WWSB_DoWriteConsole().

#define WRITE_UNICODE_CRLF   0x000a000d
 

Definition at line 2385 of file server/stream.c.

Referenced by FastStreamWrite().


Function Documentation

NTSTATUS CloseInputHandle IN PCONSOLE_PER_PROCESS_DATA  ProcessData,
IN PCONSOLE_INFORMATION  Console,
IN PHANDLE_DATA  HandleData,
IN HANDLE  Handle
 

Definition at line 2844 of file server/stream.c.

References ASSERT, ConsoleHeapFree, ConsoleRemoveShare(), FALSE, FreeIoHandle(), Handle, HANDLE_CLOSING, HANDLE_INPUT_PENDING, LockReadCount, NULL, ReinitializeInputBuffer(), TRUE, and UnlockReadCount.

Referenced by RemoveConsole(), SrvCloseHandle(), and SrvDuplicateHandle().

02853 : 02854 02855 This routine closes an input handle. It decrements the input buffer's 02856 reference count. If it goes to zero, the buffer is reinitialized. 02857 Otherwise, the handle is removed from sharing. 02858 02859 Arguments: 02860 02861 ProcessData - Pointer to per process data. 02862 02863 HandleData - Pointer to handle data structure. 02864 02865 Handle - Handle to close. 02866 02867 Return Value: 02868 02869 Note: 02870 02871 The console lock must be held when calling this routine. 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 // see if there are any reads waiting for data via this handle. if 02886 // there are, wake them up. there aren't any other outstanding i/o 02887 // operations via this handle because the console lock is held. 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 // #334370 under stress, WaitQueue may already hold the satisfied waits 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 }

NTSTATUS CloseOutputHandle IN PCONSOLE_PER_PROCESS_DATA  ProcessData,
IN PCONSOLE_INFORMATION  Console,
IN PHANDLE_DATA  HandleData,
IN HANDLE  Handle,
IN BOOLEAN  FreeHandle
 

Definition at line 2929 of file server/stream.c.

References ASSERT, ConsoleRemoveShare(), FreeIoHandle(), FreeScreenBuffer(), Handle, NTSTATUS(), NULL, RemoveScreenBuffer(), SetActiveScreenBuffer(), and Status.

Referenced by CookedRead(), CookedReadWaitRoutine(), ProcessCommandListInput(), ReadChars(), RemoveConsole(), SrvCloseHandle(), and SrvDuplicateHandle().

02939 : 02940 02941 This routine closes an output handle. It decrements the screen buffer's 02942 reference count. If it goes to zero, the buffer is freed. Otherwise, 02943 the handle is removed from sharing. 02944 02945 Arguments: 02946 02947 ProcessData - Pointer to per process data. 02948 02949 Console - Pointer to console information structure. 02950 02951 HandleData - Pointer to handle data structure. 02952 02953 Handle - Handle to close. 02954 02955 FreeHandle - if TRUE, free handle. used by ReadChars in echo mode 02956 and by process cleanup. 02957 02958 Return Value: 02959 02960 Note: 02961 02962 The console lock must be held when calling this routine. 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 }

NTSTATUS CookedRead IN PCOOKED_READ_DATA  CookedReadData,
IN PCSR_API_MSG  WaitReplyMessage,
IN PCSR_THREAD  WaitingThread,
IN BOOLEAN  WaitRoutine
 

Definition at line 1237 of file server/stream.c.

References AddCommand(), ASSERT, BOOL, _HANDLE_DATA::Buffer, _INPUT_READ_HANDLE_DATA::BufPtr, _INPUT_READ_HANDLE_DATA::BytesAvailable, CloseOutputHandle(), CONSOLE_FROMTHREADPERPROCESSDATA, CONSOLE_HISTORY_NODUP, CONSOLE_IGNORE_NEXT_KEYUP, CONSOLE_STATUS_READ_COMPLETE, CONSOLE_STATUS_WAIT, CONSOLE_STATUS_WAIT_NO_BLOCK, ConsoleHeapAlloc, ConsoleHeapFree, _CONSOLE_READCONSOLE_MSG::ControlKeyState, ConvertToOem(), CookedReadWaitRoutine(), _INPUT_READ_HANDLE_DATA::CurrentBufPtr, DereferenceIoHandleNoCheck(), DWORD, FALSE, GetChar(), HANDLE_INPUT_PENDING, HANDLE_MULTI_LINE_INPUT, _INPUT_READ_HANDLE_DATA::InputHandleFlags, _HANDLE_DATA::InputReadData, MAKE_TAG, MatchandCopyAlias(), NT_SUCCESS, NTSTATUS(), NULL, _CONSOLE_READCONSOLE_MSG::NumBytes, PBYTE, ProcessCommandLine(), ProcessCookedReadInput(), PUSHORT, Status, StringLength(), TMP_TAG, TranslateUnicodeToOem(), TRUE, _CONSOLE_READCONSOLE_MSG::Unicode, UNICODE_CARRIAGERETURN, UNICODE_LINEFEED, USHORT, and WaitForMoreToRead().

Referenced by CookedReadWaitRoutine(), and ReadChars().

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 // this call to GetChar may block. 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 // we should probably set these up in GetChars, but we set them 01292 // up here because the debugger is multi-threaded and calls 01293 // read before outputting the prompt. 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 // we have no wait block, so create one. 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 // if the read was completed (status != wait), free the cooked read 01340 // data. also, close the temporary output handle that was opened to 01341 // echo the characters read. 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 // figure out where real string ends (at carriage return 01353 // or end of buffer) 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 // add to command line recall list 01369 // 01370 01371 AddCommand(CookedReadData->CommandHistory,CookedReadData->BackupLimit,(USHORT)StringLength,CookedReadData->Console->Flags & CONSOLE_HISTORY_NODUP); 01372 01373 // 01374 // check for alias 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 // at this point, a->NumBytes contains the number of bytes in 01402 // the UNICODE string read. UserBufferSize contains the converted 01403 // size of the app's buffer. 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 // if ansi, translate string. 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 }

BOOLEAN CookedReadWaitRoutine IN PLIST_ENTRY  WaitQueue,
IN PCSR_THREAD  WaitingThread,
IN PCSR_API_MSG  WaitReplyMessage,
IN PVOID  WaitParameter,
IN PVOID  SatisfyParameter1,
IN PVOID  SatisfyParameter2,
IN ULONG  WaitFlags
 

Definition at line 1541 of file server/stream.c.

References ASSERT, _COOKED_READ_DATA::BackupLimit, _CONSOLE_READCONSOLE_MSG::Buffer, BUFFER_SIZE, _COOKED_READ_DATA::BytesRead, _CONSOLE_READCONSOLE_MSG::CaptureBufferSize, CLE_NO_POPUPS, CLE_POPUP, CleanUpPopups(), CloseOutputHandle(), _COOKED_READ_DATA::CommandHistory, _COOKED_READ_DATA::Console, CONSOLE_CTRL_BREAK_SEEN, CONSOLE_CTRL_C_SEEN, CONSOLE_FROMTHREADPERPROCESSDATA, CONSOLE_STATUS_READ_COMPLETE, CONSOLE_STATUS_WAIT, CONSOLE_STATUS_WAIT_NO_BLOCK, ConsoleHeapFree, ConsoleLocked, CookedRead(), DereferenceIoHandleNoCheck(), _COOKED_READ_DATA::Echo, _COOKED_READ_DATA::ExeName, FALSE, HANDLE_CLOSING, HANDLE_INPUT_PENDING, _COOKED_READ_DATA::HandleIndex, _INPUT_READ_HANDLE_DATA::InputHandleFlags, _HANDLE_DATA::InputReadData, LockReadCount, NT_SUCCESS, NTSTATUS(), NULL, PCLE_POPUP, _CLE_POPUP::PopupInputRoutine, _COMMAND_HISTORY::PopupList, _COOKED_READ_DATA::ProcessData, _INPUT_READ_HANDLE_DATA::ReadCount, Status, _COOKED_READ_DATA::TempHandle, TRUE, UnlockReadCount, and _COOKED_READ_DATA::UserBuffer.

Referenced by CookedRead(), ProcessCommandListInput(), ProcessCommandNumberInput(), ProcessCopyFromCharInput(), and ProcessCopyToCharInput().

01553 : 01554 01555 This routine is called to complete a cooked read that blocked in 01556 ReadInputBuffer. The context of the read was saved in the CookedReadData 01557 structure. This routine is called when events have been written to 01558 the input buffer. It is called in the context of the writing thread. 01559 It may be called more than once. 01560 01561 Arguments: 01562 01563 WaitQueue - pointer to queue containing wait block 01564 01565 WaitingThread - pointer to waiting thread 01566 01567 WaitReplyMessage - pointer to reply message 01568 01569 CookedReadData - pointer to data saved in ReadChars 01570 01571 SatisfyParameter1 - if this routine was called (indirectly) by 01572 CloseInputHandle, this argument contains a HandleData pointer of 01573 the dying handle. otherwise, it contains NULL. 01574 01575 SatisfyParameter2 - if this routine is called because a ctrl-c or 01576 ctrl-break was seen, this argument contains CONSOLE_CTRL_SEEN. 01577 otherwise it contains NULL. 01578 01579 WaitFlags - Flags indicating status of wait. 01580 01581 Return Value: 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 // see if this routine was called by CloseInputHandle. if it 01605 // was, see if this wait block corresponds to the dying handle. 01606 // if it doesn't, just return. 01607 // 01608 01609 if (SatisfyParameter1 != NULL && 01610 SatisfyParameter1 != HandleData) { 01611 //DbgPrint("CookedReadWaitRoutine exit 1\n"); 01612 return FALSE; 01613 } 01614 01615 Console = CookedReadData->Console; 01616 01617 // 01618 // this routine should be called by a thread owning the same 01619 // lock on the same console as we're reading from. 01620 // 01621 01622 LockReadCount(HandleData); 01623 ASSERT(HandleData->InputReadData->ReadCount); 01624 HandleData->InputReadData->ReadCount -= 1; 01625 UnlockReadCount(HandleData); 01626 01627 // 01628 // if ctrl-c or ctrl-break was seen, terminate read. 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 //DbgPrint("CookedReadWaitRoutine exit 2\n"); 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 // see if called by CsrDestroyProcess or CsrDestroyThread 01653 // via CsrNotifyWaitBlock. if so, just decrement the ReadCount 01654 // and return. 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 //DbgPrint("CookedReadWaitRoutine exit 3\n"); 01667 WaitReplyMessage->ReturnValue = (ULONG)STATUS_THREAD_IS_TERMINATING; 01668 01669 // 01670 // clean up popup data structures 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 // We must see if we were woken up because the handle is being 01685 // closed. if so, we decrement the read count. if it goes to 01686 // zero, we wake up the close thread. otherwise, we wake up any 01687 // other thread waiting for data. 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 //DbgPrint("CookedReadWaitRoutine exit 4\n"); 01701 WaitReplyMessage->ReturnValue = STATUS_ALERTED; 01702 01703 // 01704 // clean up popup data structures 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 // if we get to here, this routine was called either by the input 01719 // thread or a write routine. both of these callers grab the 01720 // current console lock. 01721 // 01722 01723 // 01724 // this routine should be called by a thread owning the same 01725 // lock on the same console as we're reading from. 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 // satisfy the unreferenced parameter warnings. 01770 // 01771 01772 UNREFERENCED_PARAMETER(WaitQueue); 01773 UNREFERENCED_PARAMETER(SatisfyParameter2); 01774 }

DWORD FastStreamWrite IN PWCHAR  lpString,
IN DWORD  NumChars
 

Definition at line 2388 of file server/stream.c.

References DWORD, UNICODE_SPACE, WRITE_CR, WRITE_CR_LF, WRITE_NO_CR_LF, WRITE_SPECIAL_CHARS, and WRITE_UNICODE_CRLF.

Referenced by WWSB_DoWriteConsole().

02395 : 02396 02397 This routine determines whether the text string contains characters 02398 that require special processing. If it doesn't, 02399 unicode characters. The string is also copied to the input buffer, if 02400 the output mode is line mode. 02401 02402 Arguments: 02403 02404 lpString - Pointer to string to write. 02405 02406 NumChars - Number of chars in buffer. 02407 02408 Return Value: 02409 02410 WRITE_SPECIAL_CHARS - string contains characters requiring special processing 02411 02412 WRITE_NO_CR_LF - string contains no special chars and no CRLF 02413 02414 WRITE_CR_LF - string contains no special chars and is terminated by CRLF 02415 02416 WRITE_CR - string contains no special chars and is terminated by CR 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 }

HANDLE FindActiveScreenBufferHandle IN PCONSOLE_PER_PROCESS_DATA  ProcessData,
IN PCONSOLE_INFORMATION  Console
 

Definition at line 53 of file server/stream.c.

References ASSERT, _HANDLE_DATA::Buffer, CONSOLE_GRAPHICS_OUTPUT_HANDLE, CONSOLE_OUTPUT_HANDLE, DereferenceIoHandleNoCheck(), _HANDLE_DATA::HandleType, INVALID_HANDLE_VALUE, NT_SUCCESS, NTSTATUS(), and Status.

Referenced by ReadChars().

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 }

NTSTATUS GetChar IN PINPUT_INFORMATION  InputInfo,
OUT PWCHAR  Char,
IN BOOLEAN  Wait,
IN PCONSOLE_INFORMATION  Console,
IN PHANDLE_DATA  HandleData,
IN PCSR_API_MSG Message  OPTIONAL,
IN CSR_WAIT_ROUTINE WaitRoutine  OPTIONAL,
IN PVOID WaitParameter  OPTIONAL,
IN ULONG WaitParameterLength  OPTIONAL,
IN BOOLEAN WaitBlockExists  OPTIONAL,
OUT PBOOLEAN CommandLineEditingKeys  OPTIONAL,
OUT PBOOLEAN CommandLinePopupKeys  OPTIONAL,
OUT PBOOLEAN EnableScrollMode  OPTIONAL,
OUT PDWORD KeyState  OPTIONAL
 

Definition at line 263 of file server/stream.c.

References ASSERT, BOOL, CHAR, CharToWchar(), Event(), FALSE, HIBYTE, IsCommandLineEditingKey(), IsCommandLinePopupKey(), IsDbcsExemptionForHighAnsi(), KEYEVENTSTATE_EQUAL_WINMODS, LOBYTE, NT_SUCCESS, NTSTATUS(), ReadInputBuffer(), SHORT, Status, TRUE, UINT, and VkKeyScan().

Referenced by CommonMenuDisplay(), CookedRead(), ProcessCommandListInput(), ProcessCommandNumberInput(), ProcessCopyFromCharInput(), ProcessCopyToCharInput(), RawReadWaitRoutine(), and ReadChars().

00282 : 00283 00284 This routine is used in stream input. It gets input and filters it 00285 for unicode characters. 00286 00287 Arguments: 00288 00289 InputInfo - Pointer to input buffer information. 00290 00291 Char - Unicode char input. 00292 00293 Wait - TRUE if the routine shouldn't wait for input. 00294 00295 Console - Pointer to console buffer information. 00296 00297 HandleData - Pointer to handle data structure. 00298 00299 Message - csr api message. 00300 00301 WaitRoutine - Routine to call when wait is woken up. 00302 00303 WaitParameter - Parameter to pass to wait routine. 00304 00305 WaitParameterLength - Length of wait parameter. 00306 00307 WaitBlockExists - TRUE if wait block has already been created. 00308 00309 CommandLineEditingKeys - if present, arrow keys will be returned. on 00310 output, if TRUE, Char contains virtual key code for arrow key. 00311 00312 CommandLinePopupKeys - if present, arrow keys will be returned. on 00313 output, if TRUE, Char contains virtual key code for arrow key. 00314 00315 Return Value: 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 // Always return keystate if caller asked for it. 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 // chars that are generated using alt+numpad 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 // Because USER doesn't know our codepage, it gives us the 00404 // raw OEM char and we convert it to a Unicode character. 00405 char chT = LOBYTE(Event.Event.KeyEvent.uChar.UnicodeChar); 00406 UINT uCodePage = Console->CP; 00407 00408 // 00409 // FarEast hack for High ANSI OEM characters. 00410 // 00411 if (CONSOLE_IS_DBCS_CP(Console)) { 00412 if (IsDbcsExemptionForHighAnsi(uCodePage, chT)) { 00413 /* 00414 * FarEast hack: 00415 * treat characters in High ANSI area as if they are 00416 * the ones of Codepage 1252. 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 // Ignore Escape and Newline chars 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 * This really is the character 0x0000 00461 */ 00462 *Char = Event.Event.KeyEvent.uChar.UnicodeChar; 00463 return STATUS_SUCCESS; 00464 } 00465 } 00466 } 00467 } 00468 }

BOOL IsDbcsExemptionForHighAnsi UINT  wCodePage,
WORD  wNumpadChar
 

Definition at line 233 of file server/stream.c.

References BOOL, CP_JAPANESE, FALSE, HIBYTE, IS_JPN_1BYTE_KATAKANA, and TRUE.

00236 { 00237 UserAssert(HIBYTE(wNumpadChar) == 0); 00238 00239 if (wCodePage == CP_JAPANESE && IS_JPN_1BYTE_KATAKANA(wNumpadChar)) { 00240 /* 00241 * If hkl is JAPANESE and NumpadChar is in KANA range, 00242 * NumpadChar should be handled by the input locale. 00243 */ 00244 return FALSE; 00245 } 00246 else if (wNumpadChar >= 0x80 && wNumpadChar <= 0xff) { 00247 /* 00248 * Otherwise if NumpadChar is in High ANSI range, 00249 * use 1252 for conversion. 00250 */ 00251 return TRUE; 00252 } 00253 00254 /* 00255 * None of the above. 00256 * This case includes the compound Leading Byte and Trailing Byte, 00257 * which is larger than 0xff. 00258 */ 00259 return FALSE; 00260 }

VOID MakeCursorVisible IN PSCREEN_INFORMATION  ScreenInfo,
IN COORD  CursorPosition
 

Definition at line 2348 of file server/stream.c.

References FALSE, NT_SUCCESS, NTSTATUS(), SetWindowOrigin(), and Status.

Referenced by ExtendSelection(), HandleKeyEvent(), and WWSB_AdjustCursorPosition().

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 }

BOOL ProcessCookedReadInput IN PCOOKED_READ_DATA  CookedReadData,
IN WCHAR  Char,
IN DWORD  KeyState,
OUT PNTSTATUS  Status
 

Definition at line 876 of file server/stream.c.

References AdjustCursorPosition, ASSERT, AT_EOL, BOOL, DeleteCommandLine(), DWORD, FALSE, gExtendedEditKey, INSERT_MODE, IS_WORD_DELIM, L, NT_SUCCESS, NULL, PBYTE, ProcessCommandLine(), RetrieveNumberOfSpaces(), SHORT, Status, TRUE, UNICODE_BACKSPACE, UNICODE_BACKSPACE2, UNICODE_CARRIAGERETURN, UNICODE_LINEFEED, WC_DESTRUCTIVE_BACKSPACE, WC_ECHO, WC_KEEP_CURSOR_VISIBLE, and WriteCharsFromInput().

Referenced by CookedRead(), and ProcessCommandListInput().

00885 : 00886 00887 TRUE if read is completed 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 // if at end of line, processing is relatively simple. just store the 00923 // character and write it to the screen. 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 // Repeat until it hits the word boundary 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 // processing in the middle of the line is more complex: 00982 // 00983 // 00984 // calculate new cursor position 00985 // store new char 00986 // clear the current command line from the screen 00987 // write the new command line to the screen 00988 // update the cursor position 00989 // 00990 00991 if (Char == UNICODE_BACKSPACE && CookedReadData->Processed) { 00992 00993 // 00994 // for backspace, use writechars to calculate the new cursor position. 00995 // this call also sets the cursor to the right position for the 00996 // second call to writechars. 00997 // 00998 if (CookedReadData->BufPtr != CookedReadData->BackupLimit) { 00999 01000 fStartFromDelim = gExtendedEditKey && IS_WORD_DELIM(CookedReadData->BufPtr[-1]); 01001 01002 bs_repeat: 01003 01004 // 01005 // we call writechar here so that cursor position gets updated 01006 // correctly. we also call it later if we're not at eol so 01007 // that the remainder of the string can be updated correctly. 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 // Repeat until it hits the word boundary 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 // store the char 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 // calculate new cursor position 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 // save cursor position 01120 // 01121 01122 CursorPosition = CookedReadData->ScreenInfo->BufferInfo.TextInfo.CursorPosition; 01123 CursorPosition.X = (SHORT)(CursorPosition.X+NumSpaces); 01124 01125 // 01126 // clear the current command line from the screen 01127 // 01128 01129 DeleteCommandLine(CookedReadData, 01130 FALSE); 01131 01132 // 01133 // write the new command line to the screen 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 // update cursor position 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 // adjust cursor position for WriteChars 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 // in cooked mode, enter (carriage return) is converted to 01192 // carriage return linefeed (0xda). carriage return is always 01193 // stored at the end of the buffer. 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 // reset the cursor back to 25% if necessary 01224 // 01225 if (CookedReadData->Line) { 01226 if (CookedReadData->InsertMode != CookedReadData->Console->InsertMode) { 01227 ProcessCommandLine(CookedReadData,VK_INSERT,0,NULL,NULL,FALSE); // make cursor small 01228 } 01229 *Status = STATUS_SUCCESS; 01230 return TRUE; 01231 } 01232 } 01233 return FALSE; 01234 }

BOOLEAN RawReadWaitRoutine IN PLIST_ENTRY  WaitQueue,
IN PCSR_THREAD  WaitingThread,
IN PCSR_API_MSG  WaitReplyMessage,
IN PVOID  WaitParameter,
IN PVOID  SatisfyParameter1,
IN PVOID  SatisfyParameter2,
IN ULONG  WaitFlags
 

Definition at line 471 of file server/stream.c.

References ASSERT, BOOL, _HANDLE_DATA::Buffer, _CONSOLE_READCONSOLE_MSG::Buffer, BUFFER_SIZE, _RAW_READ_DATA::BufferSize, _RAW_READ_DATA::BufPtr, _CONSOLE_READCONSOLE_MSG::CaptureBufferSize, _RAW_READ_DATA::Console, CONSOLE_CTRL_BREAK_SEEN, CONSOLE_CTRL_C_SEEN, CONSOLE_STATUS_WAIT, ConsoleHeapAlloc, ConsoleHeapFree, ConsoleLocked, ConvertToOem(), _CONSOLE_INFORMATION::CP, DereferenceIoHandleNoCheck(), DWORD, FALSE, GetChar(), HANDLE_CLOSING, _RAW_READ_DATA::HandleIndex, _CONSOLE_INFORMATION::hDC, _INPUT_READ_HANDLE_DATA::InputHandleFlags, _RAW_READ_DATA::InputInfo, _HANDLE_DATA::InputReadData, LockReadCount, MAKE_TAG, NT_SUCCESS, NTSTATUS(), NULL, _CONSOLE_READCONSOLE_MSG::NumBytes, PRAW_READ_DATA, _RAW_READ_DATA::ProcessData, RawReadWaitRoutine(), _INPUT_READ_HANDLE_DATA::ReadCount, Status, TMP_TAG, TranslateUnicodeToOem(), TRUE, _CONSOLE_READCONSOLE_MSG::Unicode, and UnlockReadCount.

Referenced by RawReadWaitRoutine(), and ReadChars().

00483 : 00484 00485 This routine is called to complete a raw read that blocked in 00486 ReadInputBuffer. The context of the read was saved in the RawReadData 00487 structure. This routine is called when events have been written to 00488 the input buffer. It is called in the context of the writing thread. 00489 ?It will be called at most once per read.? 00490 00491 Arguments: 00492 00493 WaitQueue - pointer to queue containing wait block 00494 00495 WaitingThread - pointer to waiting thread 00496 00497 WaitReplyMessage - Pointer to reply message to return to dll when 00498 read is completed. 00499 00500 RawReadData - pointer to data saved in ReadChars 00501 00502 SatisfyParameter1 - not used 00503 00504 SatisfyParameter2 - not used 00505 00506 WaitFlags - Flags indicating status of wait. 00507 00508 Return Value: 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 // see if this routine was called by CloseInputHandle. if it 00536 // was, see if this wait block corresponds to the dying handle. 00537 // if it doesn't, just return. 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 // this routine should be called by a thread owning the same 00552 // lock on the same console as we're reading from. 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 // if a ctrl-c is seen, don't terminate read. if ctrl-break is seen, 00567 // terminate read. 00568 // 00569 00570 if ((ULONG_PTR)SatisfyParameter2 & CONSOLE_CTRL_BREAK_SEEN) { 00571 WaitReplyMessage->ReturnValue = STATUS_ALERTED; 00572 leave; 00573 } 00574 00575 // 00576 // see if called by CsrDestroyProcess or CsrDestroyThread 00577 // via CsrNotifyWaitBlock. if so, just decrement the ReadCount 00578 // and return. 00579 // 00580 00581 if (WaitFlags & CSR_PROCESS_TERMINATING) { 00582 Status = STATUS_THREAD_IS_TERMINATING; 00583 leave; 00584 } 00585 00586 // 00587 // We must see if we were woken up because the handle is being 00588 // closed. if so, we decrement the read count. if it goes to 00589 // zero, we wake up the close thread. otherwise, we wake up any 00590 // other thread waiting for data. 00591 // 00592 00593 if (HandleData->InputReadData->InputHandleFlags & HANDLE_CLOSING) { 00594 ASSERT (SatisfyParameter1 == HandleData); 00595 Status = STATUS_ALERTED; 00596 leave; 00597 } 00598 00599 // 00600 // if we get to here, this routine was called either by the input 00601 // thread or a write routine. both of these callers grab the 00602 // current console lock. 00603 // 00604 00605 // 00606 // this routine should be called by a thread owning the same 00607 // lock on the same console as we're reading from. 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 // this call to GetChar may block. 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 // this call to GetChar won't block. 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 // if the read was completed (status != wait), free the raw read 00706 // data. 00707 // 00708 00709 if (Status != CONSOLE_STATUS_WAIT) { 00710 if (!a->Unicode) { 00711 00712 // 00713 // if ansi, translate string. 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 // satisfy the unreferenced parameter warnings. 00767 // 00768 00769 UNREFERENCED_PARAMETER(WaitQueue); 00770 UNREFERENCED_PARAMETER(WaitingThread); 00771 }

NTSTATUS ReadChars IN PINPUT_INFORMATION  InputInfo,
IN PCONSOLE_INFORMATION  Console,
IN PCONSOLE_PER_PROCESS_DATA  ProcessData,
IN PSCREEN_INFORMATION  ScreenInfo,
IN OUT PWCHAR  lpBuffer,
IN OUT PDWORD  NumBytes,
IN DWORD  InitialNumBytes,
IN DWORD  CtrlWakeupMask,
IN PHANDLE_DATA  HandleData,
IN PCOMMAND_HISTORY  CommandHistory,
IN PCSR_API_MSG Message  OPTIONAL,
IN HANDLE  HandleIndex,
IN USHORT  ExeNameLength,
IN PWCHAR  ExeName,
IN BOOLEAN  Unicode
 

Definition at line 1778 of file server/stream.c.

References _COOKED_READ_DATA::BackupLimit, BOOL, _HANDLE_DATA::Buffer, _RAW_READ_DATA::BufferSize, _COOKED_READ_DATA::BufferSize, BufferSize, _RAW_READ_DATA::BufPtr, _COOKED_READ_DATA::BufPtr, _COOKED_READ_DATA::BytesRead, CloseOutputHandle(), _COOKED_READ_DATA::CommandHistory, _RAW_READ_DATA::Console, _COOKED_READ_DATA::Console, CONSOLE_OUTPUT_HANDLE, CONSOLE_STATUS_WAIT, ConsoleAddShare(), ConsoleHeapAlloc, ConsoleHeapFree, ConvertToOem(), COOKED_READ_DATA, CookedRead(), _COOKED_READ_DATA::CtrlWakeupMask, _COOKED_READ_DATA::CurrentPosition, DWORD, _COOKED_READ_DATA::Echo, Echo(), _COOKED_READ_DATA::ExeName, _COOKED_READ_DATA::ExeNameLength, ExeNameLength, FALSE, FindActiveScreenBufferHandle(), GetChar(), HANDLE_INPUT_PENDING, HANDLE_MULTI_LINE_INPUT, _RAW_READ_DATA::HandleIndex, _COOKED_READ_DATA::HandleIndex, _HANDLE_DATA::HandleType, HISTORY_TAG, _RAW_READ_DATA::InputInfo, _COOKED_READ_DATA::InputInfo, _COOKED_READ_DATA::InsertMode, INVALID_HANDLE_VALUE, _COOKED_READ_DATA::Line, LINE_INPUT_BUFFER_SIZE, MAKE_TAG, NT_SUCCESS, NTSTATUS(), NULL, _COOKED_READ_DATA::NumberOfVisibleChars, _COOKED_READ_DATA::OriginalCursorPosition, PBYTE, _RAW_READ_DATA::ProcessData, _COOKED_READ_DATA::ProcessData, _COOKED_READ_DATA::Processed, RAW_READ_DATA, RawReadWaitRoutine(), _COOKED_READ_DATA::ScreenInfo, SHORT, Status, _COOKED_READ_DATA::TempHandle, TMP_TAG, TranslateUnicodeToOem(), TRUE, Unicode, UNICODE_LINEFEED, _COOKED_READ_DATA::UserBuffer, and _COOKED_READ_DATA::UserBufferSize.

Referenced by SrvReadConsole().

01798 : 01799 01800 This routine reads in characters for stream input and does the 01801 required processing based on the input mode (line,char,echo). 01802 This routine returns UNICODE characters. 01803 01804 Arguments: 01805 01806 InputInfo - Pointer to input buffer information. 01807 01808 Console - Pointer to console buffer information. 01809 01810 ScreenInfo - Pointer to screen buffer information. 01811 01812 lpBuffer - Pointer to buffer to read into. 01813 01814 NumBytes - On input, size of buffer. On output, number of bytes 01815 read. 01816 01817 HandleData - Pointer to handle data structure. 01818 01819 Return Value: 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 // if we have leftover input, copy as much fits into the user's 01842 // buffer and return. we may have multi line input, if a macro 01843 // has been defined that contains the $T character. 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 // if ansi, translate string. we allocated the capture buffer large 01922 // enough to handle the translated string. 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 // we need to create a temporary handle to the current screen buffer 01968 // if echo is on. 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 // read in characters until the buffer is full or return is read. 01998 // since we may wait inside this loop, store all important variables 01999 // in the read data structure. if we do wait, a read data structure 02000 // will be allocated from the heap and its pointer will be stored 02001 // in the wait block. the CookedReadData will be copied into the 02002 // structure. the data is freed when the read is completed. 02003 // 02004 02005 COOKED_READ_DATA CookedReadData; 02006 ULONG i; 02007 PWCHAR TempBuffer; 02008 ULONG TempBufferSize; 02009 02010 // 02011 // to emulate OS/2 KbdStringIn, we read into our own big buffer 02012 // (256 bytes) until the user types enter. then return as many 02013 // chars as will fit in the user's buffer. 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 // initialize the user's buffer to spaces. this is done so that 02032 // moving in the buffer via cursor doesn't do strange things. 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 // character (raw) mode 02101 // 02102 02103 else { 02104 02105 // 02106 // read at least one character in. after one character has been 02107 // read, get any more available characters and return. the first 02108 // call to GetChar may wait. if we do wait, a read data structure 02109 // will be allocated from the heap and its pointer will be stored 02110 // in the wait block. the RawReadData will be copied into the 02111 // structure. the data is freed when the read is completed. 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 // if ansi, translate string. we allocated the capture buffer large 02218 // enough to handle the translated string. 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 }

ULONG RetrieveNumberOfSpaces IN SHORT  OriginalCursorPositionX,
IN PWCHAR  Buffer,
IN ULONG  CurrentPosition
 

Definition at line 818 of file server/stream.c.

References Buffer, IS_CONTROL_CHAR, NUMBER_OF_SPACES_IN_TAB, SHORT, and UNICODE_TAB.

Referenced by ProcessCommandLine(), ProcessCookedReadInput(), and WWSB_WriteChars().

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 }

ULONG RetrieveTotalNumberOfSpaces IN SHORT  OriginalCursorPositionX,
IN PWCHAR  Buffer,
IN ULONG  CurrentPosition
 

Definition at line 774 of file server/stream.c.

References Buffer, IS_CONTROL_CHAR, NUMBER_OF_SPACES_IN_TAB, SHORT, and UNICODE_TAB.

Referenced by ProcessCommandLine(), and RedrawCommandLine().

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 }

ULONG SrvCloseHandle IN OUT PCSR_API_MSG  m,
IN OUT PCSR_REPLY_STATUS  ReplyStatus
 

Definition at line 2997 of file server/stream.c.

References ApiPreamble(), CloseInputHandle(), CloseOutputHandle(), CONSOLE_INPUT_HANDLE, CONSOLE_PERPROCESSDATA, _CONSOLE_CLOSEHANDLE_MSG::ConsoleHandle, DereferenceIoHandleNoCheck(), _CONSOLE_CLOSEHANDLE_MSG::Handle, HANDLE_TO_INDEX, _HANDLE_DATA::HandleType, NT_SUCCESS, NTSTATUS(), Status, TRUE, and UnlockConsole().

03004 : 03005 03006 This routine closes an input or output handle. 03007 03008 Arguments: 03009 03010 ApiMessageData - Points to parameter structure. 03011 03012 Return Value: 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); // get rid of unreferenced parameter warning message 03044 }

ULONG SrvDuplicateHandle IN OUT PCSR_API_MSG  m,
IN OUT PCSR_REPLY_STATUS  ReplyStatus
 

Definition at line 2603 of file server/stream.c.

References _HANDLE_DATA::Access, AllocateIoHandle(), ApiPreamble(), ASSERT, _HANDLE_DATA::Buffer, CloseInputHandle(), CloseOutputHandle(), CONSOLE_INHERITABLE, CONSOLE_INPUT_HANDLE, CONSOLE_PERPROCESSDATA, ConsoleDupShare(), _CONSOLE_DUPHANDLE_MSG::ConsoleHandle, DereferenceIoHandleNoCheck(), _CONSOLE_DUPHANDLE_MSG::DesiredAccess, exit, FreeIoHandle(), HANDLE_TO_INDEX, _HANDLE_DATA::HandleType, INDEX_TO_HANDLE, _CONSOLE_DUPHANDLE_MSG::InheritHandle, InitializeInputHandle(), InitializeOutputHandle(), NT_SUCCESS, NTSTATUS(), _CONSOLE_DUPHANDLE_MSG::Options, _HANDLE_DATA::ShareAccess, _CONSOLE_DUPHANDLE_MSG::SourceHandle, Status, _CONSOLE_DUPHANDLE_MSG::TargetHandle, TRUE, and UnlockConsole().

02610 : 02611 02612 This routine duplicates an input or output handle. 02613 02614 Arguments: 02615 02616 ApiMessageData - Points to parameter structure. 02617 02618 Return Value: 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 // make sure that requested access is a subset of source handle's access 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 // it's possible that AllocateIoHandle realloced the handle table, 02666 // so deference SourceHandle again. 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 // grab input lock 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 // grab output lock 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); // get rid of unreferenced parameter warning message 02744 }

ULONG SrvGetHandleInformation IN OUT PCSR_API_MSG  m,
IN OUT PCSR_REPLY_STATUS  ReplyStatus
 

Definition at line 2747 of file server/stream.c.

References ApiPreamble(), CONSOLE_INHERITABLE, CONSOLE_PERPROCESSDATA, _CONSOLE_GETHANDLEINFORMATION_MSG::ConsoleHandle, DereferenceIoHandleNoCheck(), _CONSOLE_GETHANDLEINFORMATION_MSG::Flags, _CONSOLE_GETHANDLEINFORMATION_MSG::Handle, HANDLE_TO_INDEX, _HANDLE_DATA::HandleType, NT_SUCCESS, NTSTATUS(), Status, and UnlockConsole().

02754 : 02755 02756 This gets information about an input or output handle. 02757 02758 Arguments: 02759 02760 ApiMessageData - Points to parameter structure. 02761 02762 Return Value: 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); // get rid of unreferenced parameter warning message 02791 }

ULONG SrvOpenConsole IN OUT PCSR_API_MSG  m,
IN OUT PCSR_REPLY_STATUS  ReplyStatus
 

Definition at line 80 of file server/stream.c.

References AllocateIoHandle(), ApiPreamble(), ASSERT, _HANDLE_DATA::Buffer, CONSOLE_INHERITABLE, CONSOLE_INPUT_HANDLE, CONSOLE_OUTPUT_HANDLE, CONSOLE_PERPROCESSDATA, ConsoleAddShare(), _CONSOLE_OPENCONSOLE_MSG::ConsoleHandle, _CONSOLE_INFORMATION::CurrentScreenBuffer, DereferenceIoHandleNoCheck(), _CONSOLE_OPENCONSOLE_MSG::DesiredAccess, FreeIoHandle(), _CONSOLE_OPENCONSOLE_MSG::Handle, Handle, _HANDLE_DATA::HandleType, _CONSOLE_OPENCONSOLE_MSG::HandleType, INDEX_TO_HANDLE, _CONSOLE_OPENCONSOLE_MSG::InheritHandle, InitializeInputHandle(), InitializeOutputHandle(), _CONSOLE_INFORMATION::InputBuffer, NT_SUCCESS, NTSTATUS(), NULL, _CONSOLE_OPENCONSOLE_MSG::ShareMode, Status, and UnlockConsole().

00087 : 00088 00089 This routine returns a handle to the input buffer or active screen buffer. 00090 00091 Arguments: 00092 00093 ApiMessageData - Points to parameter structure. 00094 00095 Return Value: 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 // open a handle to the active screen buffer. 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); // get rid of unreferenced parameter warning message 00209 }

ULONG SrvReadConsole IN OUT PCSR_API_MSG  m,
IN OUT PCSR_REPLY_STATUS  ReplyStatus
 

Definition at line 2263 of file server/stream.c.

References ApiPreamble(), _HANDLE_DATA::Buffer, _CONSOLE_READCONSOLE_MSG::Buffer, Buffer, BUFFER_SIZE, _CONSOLE_READCONSOLE_MSG::BufPtr, BYTE, _CONSOLE_READCONSOLE_MSG::CaptureBufferSize, CONSOLE_CLIENTPROCESSHANDLE, CONSOLE_INPUT_HANDLE, CONSOLE_PERPROCESSDATA, CONSOLE_STATUS_WAIT, _CONSOLE_READCONSOLE_MSG::ConsoleHandle, _CONSOLE_READCONSOLE_MSG::CtrlWakeupMask, _CONSOLE_INFORMATION::CurrentScreenBuffer, DereferenceIoHandle(), _CONSOLE_READCONSOLE_MSG::ExeNameLength, FindCommandHistory(), HANDLE_TO_INDEX, _CONSOLE_READCONSOLE_MSG::InitialNumBytes, _CONSOLE_READCONSOLE_MSG::InputHandle, NT_SUCCESS, NTSTATUS(), _CONSOLE_READCONSOLE_MSG::NumBytes, ReadChars(), Status, _CONSOLE_READCONSOLE_MSG::Unicode, and UnlockConsole().

02270 : 02271 02272 This routine reads characters from the input stream. 02273 02274 Arguments: 02275 02276 ApiMessageData - Points to parameter structure. 02277 02278 Return Value: 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 }

ULONG SrvSetHandleInformation IN OUT PCSR_API_MSG  m,
IN OUT PCSR_REPLY_STATUS  ReplyStatus
 

Definition at line 2794 of file server/stream.c.

References ApiPreamble(), CONSOLE_INHERITABLE, CONSOLE_PERPROCESSDATA, _CONSOLE_SETHANDLEINFORMATION_MSG::ConsoleHandle, DereferenceIoHandleNoCheck(), _CONSOLE_SETHANDLEINFORMATION_MSG::Flags, _CONSOLE_SETHANDLEINFORMATION_MSG::Handle, HANDLE_TO_INDEX, _HANDLE_DATA::HandleType, _CONSOLE_SETHANDLEINFORMATION_MSG::Mask, NT_SUCCESS, NTSTATUS(), Status, and UnlockConsole().

02801 : 02802 02803 This sets information about an input or output handle. 02804 02805 Arguments: 02806 02807 ApiMessageData - Points to parameter structure. 02808 02809 Return Value: 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); // get rid of unreferenced parameter warning message 02841 }

ULONG SrvWriteConsole IN OUT PCSR_API_MSG  m,
IN OUT PCSR_REPLY_STATUS  ReplyStatus
 

Definition at line 2463 of file server/stream.c.

References ApiPreamble(), _CONSOLE_WRITECONSOLE_MSG::Buffer, _CONSOLE_WRITECONSOLE_MSG::BufferInMessage, _CONSOLE_WRITECONSOLE_MSG::BufPtr, BYTE, CONSOLE_OUTPUT_HANDLE, CONSOLE_PERPROCESSDATA, _CONSOLE_WRITECONSOLE_MSG::ConsoleHandle, DereferenceIoHandle(), DoSrvWriteConsole, NT_SUCCESS, NTSTATUS(), _CONSOLE_WRITECONSOLE_MSG::NumBytes, _CONSOLE_WRITECONSOLE_MSG::OutputHandle, Status, and UnlockConsole().

02470 : 02471 02472 This routine writes characters to the output stream. 02473 02474 Arguments: 02475 02476 ApiMessageData - Points to parameter structure. 02477 02478 Return Value: 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 // Make sure we have a valid screen buffer. 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 }

VOID UnblockWriteConsole IN PCONSOLE_INFORMATION  Console,
IN DWORD  Reason
 

Definition at line 2442 of file server/stream.c.

References ASSERT, CONSOLE_SCROLLBAR_TRACKING, CONSOLE_SELECTING, CONSOLE_SUSPENDED, NULL, TRUE, and VOID().

Referenced by ClearSelection(), PreprocessInput(), and VerticalScroll().

02445 { 02446 Console->Flags &= ~Reason; 02447 02448 if ((Console->Flags & (CONSOLE_SUSPENDED | CONSOLE_SELECTING | CONSOLE_SCROLLBAR_TRACKING)) == 0) { 02449 /* 02450 * no remain reason to suspend output, so unblock it. 02451 */ 02452 if (CsrNotifyWait(&Console->OutputQueue, TRUE, NULL, NULL)) { 02453 // #334370 under stress, WaitQueue may already hold the satisfied waits 02454 ASSERT ((Console->WaitQueue == NULL) || 02455 (Console->WaitQueue == &Console->OutputQueue)); 02456 Console->WaitQueue = &Console->OutputQueue; 02457 } 02458 } 02459 }

NTSTATUS WaitForMoreToRead IN PINPUT_INFORMATION  InputInformation,
IN PCSR_API_MSG Message  OPTIONAL,
IN CSR_WAIT_ROUTINE WaitRoutine  OPTIONAL,
IN PVOID WaitParameter  OPTIONAL,
IN ULONG WaitParameterLength  OPTIONAL,
IN BOOLEAN WaitBlockExists  OPTIONAL
 

Definition at line 248 of file ntcon/server/input.c.

References CONSOLE_STATUS_WAIT, ConsoleHeapAlloc, ConsoleHeapFree, MAKE_TAG, NULL, and WAIT_TAG.

Referenced by CookedRead(), and ReadInputBuffer().

00259 : 00260 00261 This routine waits for a writer to add data to the buffer. 00262 00263 Arguments: 00264 00265 InputInformation - buffer to wait for 00266 00267 Console - Pointer to console buffer information. 00268 00269 Message - if called from dll (not InputThread), points to api 00270 message. this parameter is used for wait block processing. 00271 00272 WaitRoutine - Routine to call when wait is woken up. 00273 00274 WaitParameter - Parameter to pass to wait routine. 00275 00276 WaitParameterLength - Length of wait parameter. 00277 00278 WaitBlockExists - TRUE if wait block has already been created. 00279 00280 Return Value: 00281 00282 STATUS_WAIT - call was from client and wait block has been created. 00283 00284 STATUS_SUCCESS - call was from server and wait has been satisfied. 00285 00286 --*/ 00287 00288 { 00289 PVOID WaitParameterBuffer; 00290 00291 if (!WaitBlockExists) { 00292 WaitParameterBuffer = (PVOID)ConsoleHeapAlloc(MAKE_TAG( WAIT_TAG ),WaitParameterLength); 00293 if (WaitParameterBuffer == NULL) { 00294 return STATUS_NO_MEMORY; 00295 } 00296 RtlCopyMemory(WaitParameterBuffer,WaitParameter,WaitParameterLength); 00297 #if defined(FE_SB) 00298 if (WaitParameterLength == sizeof(COOKED_READ_DATA) && 00299 InputInformation->Console->lpCookedReadData == WaitParameter) { 00300 InputInformation->Console->lpCookedReadData = WaitParameterBuffer; 00301 } 00302 #endif 00303 if (!CsrCreateWait(&InputInformation->ReadWaitQueue, 00304 WaitRoutine, 00305 CSR_SERVER_QUERYCLIENTTHREAD(), 00306 Message, 00307 WaitParameterBuffer, 00308 NULL 00309 )) { 00310 ConsoleHeapFree(WaitParameterBuffer); 00311 #if defined(FE_SB) 00312 InputInformation->Console->lpCookedReadData = NULL; 00313 #endif 00314 return STATUS_NO_MEMORY; 00315 } 00316 } 00317 return CONSOLE_STATUS_WAIT; 00318 }

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

Definition at line 3047 of file server/stream.c.

References CONSOLE_GRAPHICS_BUFFER, CONSOLE_OEMFONT_DISPLAY, dwFlags, DWORD, WC_FALSIFY_UNICODE, and WriteChars.

Referenced by ProcessCommandLine(), ProcessCommandNumberInput(), ProcessCookedReadInput(), ProcessCopyFromCharInput(), ProcessCopyToCharInput(), RedrawCommandLine(), and SetCurrentCommandLine().

03061 : 03062 03063 This routine converts chars from their true unicode representation 03064 to the Unicode representation (UnicodeAnsi) that will generate 03065 the correct glyph given an OEM font and an ANSI translation by GDI. 03066 It then calls WriteChars. 03067 03068 Arguments: 03069 03070 ScreenInfo - Pointer to screen buffer information structure. 03071 03072 lpBufferBackupLimit - Pointer to beginning of buffer. 03073 03074 lpBuffer - Pointer to buffer to copy string to. assumed to be at least 03075 as long as lpString. This pointer is updated to point to the next 03076 position in the buffer. 03077 03078 lpString - Pointer to string to write. 03079 03080 NumBytes - On input, number of bytes to write. On output, number of 03081 bytes written. 03082 03083 NumSpaces - On output, the number of spaces consumed by the written characters. 03084 03085 dwFlags - 03086 WC_DESTRUCTIVE_BACKSPACE backspace overwrites characters. 03087 WC_KEEP_CURSOR_VISIBLE change window origin desirable when hit rt. edge 03088 WC_ECHO if called by Read (echoing characters) 03089 WC_FALSIFY_UNICODE if RealUnicodeToFalseUnicode need be called. 03090 03091 Return Value: 03092 03093 Note: 03094 03095 This routine does not process tabs and backspace properly. That code 03096 will be implemented as part of the line editing services. 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 }

BOOLEAN WriteConsoleWaitRoutine IN PLIST_ENTRY  WaitQueue,
IN PCSR_THREAD  WaitingThread,
IN PCSR_API_MSG  WaitReplyMessage,
IN PVOID  WaitParameter,
IN PVOID  SatisfyParameter1,
IN PVOID  SatisfyParameter2,
IN ULONG  WaitFlags
 

Definition at line 2529 of file server/stream.c.

References ASSERT, _CONSOLE_WRITECONSOLE_MSG::Buffer, _CONSOLE_WRITECONSOLE_MSG::BufferInMessage, CONSOLE_STATUS_WAIT, _CONSOLE_WRITECONSOLE_MSG::ConsoleHandle, ConsoleHeapFree, ConsoleLocked, DereferenceConsoleHandle(), DoWriteConsole, FALSE, LockConsoleHandleTable, NT_SUCCESS, NTSTATUS(), _CONSOLE_WRITECONSOLE_MSG::NumBytes, Status, _CONSOLE_WRITECONSOLE_MSG::TransBuffer, TRUE, _CONSOLE_WRITECONSOLE_MSG::Unicode, and UnlockConsoleHandleTable.

Referenced by WWSB_DoWriteConsole().

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 // if we get to here, this routine was called by the input 02556 // thread, which grabs the current console lock. 02557 // 02558 02559 // 02560 // this routine should be called by a thread owning the same 02561 // lock on the same console as we're reading from. 02562 // 02563 02564 ASSERT (ConsoleLocked(Console)); 02565 02566 // 02567 // if we're unicode, the string may still be in the message buffer. 02568 // since the message was reallocated and copied when the wait was 02569 // created, we need to fix up a->TransBuffer here. 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 }


Variable Documentation

DWORD ConsKbdState[]
 

Initial value:

Definition at line 218 of file server/stream.c.


Generated on Sat May 15 19:45:41 2004 for test by doxygen 1.3.7