-/* $Id: conio.c,v 1.7 2004/02/27 17:35:42 hbirr Exp $
- *
+/*
* reactos/subsys/csrss/win32csr/conio.c
*
* Console I/O functions
#define ConioIsRectEmpty(Rect) \
(((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom))
+#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
+ WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
+
+#define ConsoleAnsiCharToUnicodeChar(Console, sWChar, dChar) \
+ MultiByteToWideChar((Console)->CodePage, 0, (dChar), 1, (sWChar), 1)
+
+#define ConsoleUnicodeToAnsiN(Console, dChar, sWChar, nChars) \
+ WideCharToMultiByte((Console)->CodePage, 0, (sWChar), (nChars), (dChar), (nChars) * sizeof(WCHAR), NULL, NULL)
+
/* FUNCTIONS *****************************************************************/
STATIC NTSTATUS FASTCALL
return STATUS_SUCCESS;
}
-STATIC VOID FASTCALL
-CsrConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData)
+VOID FASTCALL
+ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData)
{
HANDLE Process, Thread;
- DPRINT("CsrConsoleCtrlEvent Parent ProcessId = %x\n", ClientId.UniqueProcess);
+ DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ProcessId);
if (ProcessData->CtrlDispatcher)
{
return;
}
- DPRINT("CsrConsoleCtrlEvent Process Handle = %x\n", Process);
+ DPRINT("ConioConsoleCtrlEvent Process Handle = %x\n", Process);
Thread = CreateRemoteThread(Process, NULL, 0,
(LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher,
}
#define GET_CELL_BUFFER(b,o)\
-(b)->Buffer[(o)++];
+(b)->Buffer[(o)++]
#define SET_CELL_BUFFER(b,o,c,a)\
-(b)->Buffer[(o)++]=(c);\
-(b)->Buffer[(o)++]=(a);
+(b)->Buffer[(o)++]=(c),\
+(b)->Buffer[(o)++]=(a)
static VOID FASTCALL
ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff)
for (Pos = 0; Pos < Buff->MaxX; Pos++)
{
/* Fill the cell: Offset is incremented by the macro */
- SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib)
+ SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib);
}
}
{
return STATUS_INSUFFICIENT_RESOURCES;
}
- RtlInitializeCriticalSection(&Buffer->Header.Lock);
+ InitializeCriticalSection(&Buffer->Header.Lock);
ConioInitScreenBuffer(Console, Buffer);
/* initialize buffer to be empty with default attributes */
for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
InitializeListHead(&Console->InputEvents);
InitializeListHead(&Console->ProcessList);
+ Console->CodePage = GetOEMCP();
+ Console->OutputCodePage = GetOEMCP();
+
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
SecurityAttributes.lpSecurityDescriptor = NULL;
SecurityAttributes.bInheritHandle = TRUE;
- Console->ActiveEvent = CreateEventW(&SecurityAttributes, FALSE, FALSE, NULL);
+ Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
if (NULL == Console->ActiveEvent)
{
RtlFreeUnicodeString(&Console->Title);
return STATUS_UNSUCCESSFUL;
}
Console->PrivateData = NULL;
- RtlInitializeCriticalSection(&Console->Header.Lock);
+ InitializeCriticalSection(&Console->Header.Lock);
GuiMode = DtbgIsDesktopVisible();
if (! GuiMode)
{
if (! NT_SUCCESS(Status))
{
RtlFreeUnicodeString(&Console->Title);
- RtlDeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Header.Lock);
CloseHandle(Console->ActiveEvent);
return Status;
}
NewBuffer = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_SCREEN_BUFFER));
if (NULL == NewBuffer)
{
+ ConioCleanupConsole(Console);
RtlFreeUnicodeString(&Console->Title);
- RtlDeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Header.Lock);
CloseHandle(Console->ActiveEvent);
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
if (! NT_SUCCESS(Status))
{
+ ConioCleanupConsole(Console);
RtlFreeUnicodeString(&Console->Title);
- RtlDeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Header.Lock);
CloseHandle(Console->ActiveEvent);
HeapFree(Win32CsrApiHeap, 0, NewBuffer);
return Status;
DPRINT("CsrAllocConsole\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
if (ProcessData == NULL)
{
DPRINT("CsrFreeConsole\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
if (ProcessData == NULL || ProcessData->Console == NULL)
{
for (i = 0; i < Length; i++)
{
- switch(Buffer[i])
+ if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
{
/* --- LF --- */
- case '\n':
- Buff->CurrentX = 0;
- ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
- break;
-
+ if (Buffer[i] == '\n')
+ {
+ Buff->CurrentX = 0;
+ ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
+ continue;
+ }
/* --- BS --- */
- case '\b':
- /* Only handle BS if we're not on the first pos of the first line */
- if (0 != Buff->CurrentX || Buff->ShowY != Buff->CurrentY)
- {
- if (0 == Buff->CurrentX)
- {
- /* slide virtual position up */
- Buff->CurrentX = Buff->MaxX - 1;
- if (0 == Buff->CurrentY)
- {
- Buff->CurrentY = Buff->MaxY;
- }
- else
- {
- Buff->CurrentY--;
- }
- if ((0 == UpdateRect.top && UpdateRect.bottom < Buff->CurrentY)
- || (0 != UpdateRect.top && Buff->CurrentY < UpdateRect.top))
- {
- UpdateRect.top = Buff->CurrentY;
- }
- }
- else
- {
- Buff->CurrentX--;
- }
- Offset = 2 * ((Buff->CurrentY * Buff->MaxX) + Buff->CurrentX);
- SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib);
- UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
- UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
- }
- break;
-
+ else if (Buffer[i] == '\b')
+ {
+ /* Only handle BS if we're not on the first pos of the first line */
+ if (0 != Buff->CurrentX || Buff->ShowY != Buff->CurrentY)
+ {
+ if (0 == Buff->CurrentX)
+ {
+ /* slide virtual position up */
+ Buff->CurrentX = Buff->MaxX - 1;
+ if (0 == Buff->CurrentY)
+ {
+ Buff->CurrentY = Buff->MaxY;
+ }
+ else
+ {
+ Buff->CurrentY--;
+ }
+ if ((0 == UpdateRect.top && UpdateRect.bottom < Buff->CurrentY)
+ || (0 != UpdateRect.top && Buff->CurrentY < UpdateRect.top))
+ {
+ UpdateRect.top = Buff->CurrentY;
+ }
+ }
+ else
+ {
+ Buff->CurrentX--;
+ }
+ Offset = 2 * ((Buff->CurrentY * Buff->MaxX) + Buff->CurrentX);
+ SET_CELL_BUFFER(Buff, Offset, ' ', Buff->DefaultAttrib);
+ UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
+ UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
+ }
+ continue;
+ }
/* --- CR --- */
- case '\r':
- Buff->CurrentX = 0;
- UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
- UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
- break;
-
+ else if (Buffer[i] == '\r')
+ {
+ Buff->CurrentX = 0;
+ UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
+ UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
+ continue;
+ }
/* --- TAB --- */
- case '\t':
+ else if (Buffer[i] == '\t')
{
UINT EndX;
UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
- EndX = 8 * ((Buff->CurrentX + 8) / 8);
- if (Buff->MaxX < EndX)
+ EndX = (Buff->CurrentX + 8) & ~7;
+ if (EndX > Buff->MaxX)
{
EndX = Buff->MaxX;
}
UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX - 1);
if (Buff->CurrentX == Buff->MaxX)
{
- Buff->CurrentX = 0;
- ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
+ if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
+ {
+ Buff->CurrentX = 0;
+ ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
+ }
+ else
+ {
+ Buff->CurrentX--;
+ }
}
+ continue;
+ }
+ }
+ UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
+ UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
+ Offset = 2 * (((Buff->CurrentY * Buff->MaxX)) + Buff->CurrentX);
+ Buff->Buffer[Offset++] = Buffer[i];
+ if (Attrib)
+ {
+ Buff->Buffer[Offset] = Buff->DefaultAttrib;
+ }
+ Buff->CurrentX++;
+ if (Buff->CurrentX == Buff->MaxX)
+ {
+ if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
+ {
+ Buff->CurrentX = 0;
+ ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
+ }
+ else
+ {
+ Buff->CurrentX = CursorStartX;
}
- break;
-
- /* --- */
- default:
- UpdateRect.left = RtlRosMin(UpdateRect.left, Buff->CurrentX);
- UpdateRect.right = RtlRosMax(UpdateRect.right, (LONG) Buff->CurrentX);
- Offset = 2 * (((Buff->CurrentY * Buff->MaxX)) + Buff->CurrentX);
- Buff->Buffer[Offset++] = Buffer[i];
- if (Attrib)
- {
- Buff->Buffer[Offset] = Buff->DefaultAttrib;
- }
- Buff->CurrentX++;
- if (Buff->CurrentX == Buff->MaxX)
- {
- Buff->CurrentX = 0;
- ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
- }
- break;
}
}
{
PLIST_ENTRY CurrentEntry;
ConsoleInput *Input;
- PCHAR Buffer;
+ PUCHAR Buffer;
+ PWCHAR UnicodeBuffer;
int i;
- ULONG nNumberOfCharsToRead;
+ ULONG nNumberOfCharsToRead, CharSize;
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DPRINT("CsrReadConsole\n");
+
+ CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
/* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */
- nNumberOfCharsToRead = Request->Data.ReadConsoleRequest.NrCharactersToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : Request->Data.ReadConsoleRequest.NrCharactersToRead;
+ nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE_REQUEST / CharSize);
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = Reply->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
Buffer = Reply->Data.ReadConsoleReply.Buffer;
+ UnicodeBuffer = (PWCHAR)Buffer;
Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
&Console);
if (! NT_SUCCESS(Status))
{
/* remove input event from queue */
CurrentEntry = RemoveHeadList(&Console->InputEvents);
+ if (IsListEmpty(&Console->InputEvents))
+ {
+ CHECKPOINT;
+ ResetEvent(Console->ActiveEvent);
+ }
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
/* only pay attention to valid ascii chars, on key down */
if (KEY_EVENT == Input->InputEvent.EventType
&& Input->InputEvent.Event.KeyEvent.bKeyDown
- && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
+ && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0')
{
/* backspace handling */
if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar)
&& (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted))
{
ConioWriteConsole(Console, Console->ActiveBuffer,
- &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE);
+ &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE);
}
if (0 != i)
{
}
else
{ /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */
- Reply->Data.ReadConsoleReply.NrCharactersRead = 0;
- Reply->Status = STATUS_NOTIFY_CLEANUP;
Console->WaitingChars--;
- HeapFree(Win32CsrApiHeap, 0, Input);
ConioUnlockConsole(Console);
+ HeapFree(Win32CsrApiHeap, 0, Input);
+ Reply->Data.ReadConsoleReply.NrCharactersRead = 0;
+ Reply->Status = STATUS_NOTIFY_CLEANUP;
return STATUS_NOTIFY_CLEANUP;
}
Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--;
/* do not copy backspace to buffer */
else
{
- Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
+ if(Request->Data.ReadConsoleRequest.Unicode)
+ UnicodeBuffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; /* FIXME */
+ else
+ Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar;
}
/* echo to screen if enabled and we did not already echo the char */
if (0 != (Console->Mode & ENABLE_ECHO_INPUT)
}
else if (0 != (Console->Mode & ENABLE_LINE_INPUT))
{
- if (0 == Console->WaitingLines || '\n' != Buffer[i - 1])
+ if (0 == Console->WaitingLines ||
+ (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1])))
{
Reply->Status = STATUS_PENDING; /* line buffered, didn't get a complete line */
}
{
Console->EchoCount = 0; /* if the client is no longer waiting on input, do not echo */
}
- Reply->Header.MessageSize += i;
+ Reply->Header.MessageSize += i * CharSize;
ConioUnlockConsole(Console);
return Reply->Status;
}
STATIC VOID FASTCALL
-ConioFillRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer,
+ConioFillRegion(PCSRSS_CONSOLE Console,
+ PCSRSS_SCREEN_BUFFER ScreenBuffer,
RECT *Region,
- CHAR_INFO CharInfo)
+ CHAR_INFO *CharInfo,
+ BOOL bUnicode)
{
SHORT X, Y;
DWORD Offset;
DWORD Delta;
ULONG i;
+ CHAR Char;
+
+ if(bUnicode)
+ ConsoleUnicodeCharToAnsiChar(Console, &Char, &CharInfo->Char.UnicodeChar);
+ else
+ Char = CharInfo->Char.AsciiChar;
Y = (Region->top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY;
Offset = (Y * ScreenBuffer->MaxX + Region->left + ScreenBuffer->ShowX) * 2;
{
for (X = Region->left; X <= Region->right; X++)
{
- SET_CELL_BUFFER(ScreenBuffer, Offset, CharInfo.Char.AsciiChar, CharInfo.Attributes);
+ SET_CELL_BUFFER(ScreenBuffer, Offset, Char, CharInfo->Attributes);
}
if (++Y == ScreenBuffer->MaxY)
{
}
}
+STATIC VOID FASTCALL
+ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent)
+{
+ if (InputEvent->EventType == KEY_EVENT)
+ {
+ ConsoleUnicodeCharToAnsiChar(Console,
+ &InputEvent->Event.KeyEvent.uChar.AsciiChar,
+ &InputEvent->Event.KeyEvent.uChar.UnicodeChar);
+ }
+}
+
CSR_API(CsrWriteConsole)
{
NTSTATUS Status;
- BYTE *Buffer = Request->Data.WriteConsoleRequest.Buffer;
+ PCHAR Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer;
PCSRSS_SCREEN_BUFFER Buff;
PCSRSS_CONSOLE Console;
+ ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
DPRINT("CsrWriteConsole\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
- sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
if (Request->Header.DataSize
< sizeof(CSRSS_WRITE_CONSOLE_REQUEST) - 1
- + Request->Data.WriteConsoleRequest.NrCharactersToWrite)
+ + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize))
{
DPRINT1("Invalid request size\n");
return Reply->Status = STATUS_INVALID_PARAMETER;
return Reply->Status = Status;
}
+ if(Request->Data.WriteConsoleRequest.Unicode)
+ {
+ ConsoleUnicodeToAnsiN(Console, Buffer, (PWCHAR)Buffer, Request->Data.WriteConsoleRequest.NrCharactersToWrite);
+ }
+
Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff);
if (! NT_SUCCESS(Status))
{
return Reply->Status = Status;
}
- ConioWriteConsole(Console, Buff, Buffer,
- Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
+ Reply->Status = ConioWriteConsole(Console, Buff, Buffer,
+ Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE);
ConioUnlockScreenBuffer(Buff);
if (NULL != Console)
{
ConioUnlockConsole(Console);
}
+ if(NT_SUCCESS(Reply->Status))
+ {
+ Reply->Data.WriteConsoleReply.NrCharactersWritten = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
+ }
+ else
+ {
+ Reply->Data.WriteConsoleReply.NrCharactersWritten = 0; /* FIXME - return the actual number of characters written! */
+ }
+
return Reply->Status = STATUS_SUCCESS;
}
ConioDeleteScreenBuffer(Object_t *Object)
{
PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
- RtlDeleteCriticalSection(&Buffer->Header.Lock);
+ DeleteCriticalSection(&Buffer->Header.Lock);
HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
HeapFree(Win32CsrApiHeap, 0, Buffer);
}
ConioCleanupConsole(Console);
CloseHandle(Console->ActiveEvent);
- RtlDeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Header.Lock);
RtlFreeUnicodeString(&Console->Title);
HeapFree(Win32CsrApiHeap, 0, Console);
}
STATIC VOID FASTCALL
ConioProcessChar(PCSRSS_CONSOLE Console,
- ConsoleInput *KeyEventRecord)
+ ConsoleInput *KeyEventRecord)
{
BOOL updown;
BOOL bClientWake = FALSE;
{
current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
current_entry = current_entry->Flink;
- CsrConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
+ ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
}
HeapFree(Win32CsrApiHeap, 0, KeyEventRecord);
return;
if (0 == (Console->Mode & ENABLE_LINE_INPUT)
|| Console->EarlyReturn
|| ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar
- && ! KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown))
+ && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown))
{
if ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar)
{
{
ConioWriteConsole(Console, Console->ActiveBuffer,
&KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar,
- 1, TRUE);
+ 1, TRUE);
}
HeapFree(Win32CsrApiHeap, 0, TempInput);
RemoveEntryList(&KeyEventRecord->ListEntry);
STATIC DWORD FASTCALL
ConioGetShiftState(PBYTE KeyState)
{
- int i;
DWORD ssOut = 0;
- for (i = 0; i < 0x100; i++)
- {
- if (0 != (KeyState[i] & 0x80))
- {
- UINT vk = MapVirtualKeyExW(i, 3, 0) & 0xff;
- switch(vk)
- {
- case VK_CAPITAL:
- ssOut |= CAPSLOCK_ON;
- break;
+ if (KeyState[VK_CAPITAL] & 1)
+ ssOut |= CAPSLOCK_ON;
- case VK_NUMLOCK:
- ssOut |= NUMLOCK_ON;
- break;
+ if (KeyState[VK_NUMLOCK] & 1)
+ ssOut |= NUMLOCK_ON;
- case VK_SCROLL:
- ssOut |= SCROLLLOCK_ON;
- break;
- }
- }
- }
+ if (KeyState[VK_SCROLL] & 1)
+ ssOut |= SCROLLLOCK_ON;
- if (KeyState[VK_LSHIFT] & 0x80 || KeyState[VK_RSHIFT] & 0x80)
+ if (KeyState[VK_SHIFT] & 0x80)
ssOut |= SHIFT_PRESSED;
if (KeyState[VK_LCONTROL] & 0x80)
- ssOut |= RIGHT_CTRL_PRESSED;
- else if (KeyState[VK_RCONTROL] & 0x80)
ssOut |= LEFT_CTRL_PRESSED;
+ if (KeyState[VK_RCONTROL] & 0x80)
+ ssOut |= RIGHT_CTRL_PRESSED;
if (KeyState[VK_LMENU] & 0x80)
- ssOut |= RIGHT_ALT_PRESSED;
- else if (KeyState[VK_RMENU] & 0x80)
ssOut |= LEFT_ALT_PRESSED;
+ if (KeyState[VK_RMENU] & 0x80)
+ ssOut |= RIGHT_ALT_PRESSED;
return ssOut;
}
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
}
- if (UnicodeChar)
- {
- RtlUnicodeToOemN(&AsciiChar,
- 1,
- &ResultSize,
- &UnicodeChar,
- sizeof(WCHAR));
- }
if (0 == ResultSize)
{
AsciiChar = 0;
er.EventType = KEY_EVENT;
er.Event.KeyEvent.bKeyDown = Down;
er.Event.KeyEvent.wRepeatCount = RepeatCount;
- er.Event.KeyEvent.uChar.UnicodeChar = AsciiChar & 0xff;
+ er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
er.Event.KeyEvent.dwControlKeyState = ShiftState;
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
}
ConInRec->InputEvent = er;
- ConInRec->Fake = AsciiChar &&
+ ConInRec->Fake = UnicodeChar &&
(msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
if (! ConInRec->Fake || ! ConInRec->NotChar)
{
+ /* FIXME - convert to ascii */
ConioProcessChar(Console, ConInRec);
}
else
DPRINT("CsrGetScreenBufferInfo\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff);
if (! NT_SUCCESS(Status))
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
LONG OldCursorX, OldCursorY;
+ LONG NewCursorX, NewCursorY;
DPRINT("CsrSetCursor\n");
}
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff);
if (! NT_SUCCESS(Status))
return Reply->Status = Status;
}
+ NewCursorX = Request->Data.SetCursorRequest.Position.X;
+ NewCursorY = Request->Data.SetCursorRequest.Position.Y;
+ if (NewCursorX < 0 || NewCursorX >= Buff->MaxX ||
+ NewCursorY < 0 || NewCursorY >= Buff->MaxY)
+ {
+ ConioUnlockScreenBuffer(Buff);
+ return Reply->Status = STATUS_INVALID_PARAMETER;
+ }
ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY, &OldCursorX, &OldCursorY);
- Buff->CurrentX = Request->Data.SetCursorRequest.Position.X + Buff->ShowX;
- Buff->CurrentY = (Request->Data.SetCursorRequest.Position.Y + Buff->ShowY) % Buff->MaxY;
+ Buff->CurrentX = NewCursorX + Buff->ShowX;
+ Buff->CurrentY = (NewCursorY + Buff->ShowY) % Buff->MaxY;
if (NULL != Console && Buff == Console->ActiveBuffer)
{
if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
CSR_API(CsrWriteConsoleOutputChar)
{
NTSTATUS Status;
- PBYTE String = Request->Data.WriteConsoleOutputCharRequest.String;
+ PCHAR String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String;
PBYTE Buffer;
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
- DWORD X, Y, Length;
+ DWORD X, Y, Length, CharSize, Written = 0;
RECT UpdateRect;
DPRINT("CsrWriteConsoleOutputChar\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
- sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+
+ CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
if (Request->Header.DataSize
< sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REQUEST) - 1
- + Request->Data.WriteConsoleOutputCharRequest.Length)
+ + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize))
{
DPRINT1("Invalid request size\n");
return Reply->Status = STATUS_INVALID_PARAMETER;
return Reply->Status = Status;
}
+ if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
+ {
+ ConsoleUnicodeToAnsiN(Console, String, (PWCHAR)String, Request->Data.WriteConsoleOutputCharRequest.Length);
+ }
+
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
&Buff);
while (Length--)
{
*Buffer = *String++;
+ Written++;
Buffer += 2;
if (++X == Buff->MaxX)
{
ConioUnlockConsole(Console);
}
+ Reply->Data.WriteConsoleOutputCharReply.NrCharactersWritten = Written;
return Reply->Status = STATUS_SUCCESS;
}
NTSTATUS Status;
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
- DWORD X, Y, Length;
- BYTE Char;
+ DWORD X, Y, Length, Written = 0;
+ CHAR Char;
PBYTE Buffer;
RECT UpdateRect;
DPRINT("CsrFillOutputChar\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
X = Request->Data.FillOutputRequest.Position.X + Buff->ShowX;
Y = (Request->Data.FillOutputRequest.Position.Y + Buff->ShowY) % Buff->MaxY;
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)];
- Char = Request->Data.FillOutputRequest.Char;
+ if(Request->Data.FillOutputRequest.Unicode)
+ ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar);
+ else
+ Char = Request->Data.FillOutputRequest.Char.AsciiChar;
Length = Request->Data.FillOutputRequest.Length;
while (Length--)
{
*Buffer = Char;
Buffer += 2;
+ Written++;
if (++X == Buff->MaxX)
{
if (++Y == Buff->MaxY)
DPRINT("CsrReadInputEvent\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Reply->Data.ReadInputReply.Event = ProcessData->ConsoleEvent;
Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console);
}
/* only get input if there is any */
- while (Console->InputEvents.Flink != &Console->InputEvents && ! Done)
+ CurrentEntry = Console->InputEvents.Flink;
+ while (CurrentEntry != &Console->InputEvents)
{
- CurrentEntry = RemoveHeadList(&Console->InputEvents);
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
- Done = !Input->Fake;
- Reply->Data.ReadInputReply.Input = Input->InputEvent;
+ CurrentEntry = CurrentEntry->Flink;
+
+ if (Done && !Input->Fake)
+ {
+ Reply->Data.ReadInputReply.MoreEvents = TRUE;
+ break;
+ }
+
+ RemoveEntryList(&Input->ListEntry);
+
+ if (!Done && !Input->Fake)
+ {
+ Reply->Data.ReadInputReply.Input = Input->InputEvent;
+ if (Request->Data.ReadInputRequest.Unicode == FALSE)
+ {
+ ConioInputEventToAnsi(Console, &Reply->Data.ReadInputReply.Input);
+ }
+ Done = TRUE;
+ }
if (Input->InputEvent.EventType == KEY_EVENT)
{
Console->WaitingChars--;
}
HeapFree(Win32CsrApiHeap, 0, Input);
-
- Reply->Data.ReadInputReply.MoreEvents = (Console->InputEvents.Flink != &Console->InputEvents);
- Status = STATUS_SUCCESS;
- Console->EarlyReturn = FALSE; /* clear early return */
}
- if (! Done)
+ if (Done)
+ {
+ Status = STATUS_SUCCESS;
+ Console->EarlyReturn = FALSE;
+ }
+ else
{
Status = STATUS_PENDING;
Console->EarlyReturn = TRUE; /* mark for early return */
}
+ if (IsListEmpty(&Console->InputEvents))
+ {
+ ResetEvent(Console->ActiveEvent);
+ }
+
ConioUnlockConsole(Console);
return Reply->Status = Status;
DPRINT("CsrWriteConsoleOutputAttrib\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
- sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
if (Request->Header.DataSize
< sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REQUEST) - 1
Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY;
Length = Request->Data.WriteConsoleOutputAttribRequest.Length;
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1];
- Attribute = Request->Data.WriteConsoleOutputAttribRequest.String;
+ Attribute = (PUCHAR)Request->Data.WriteConsoleOutputAttribRequest.String;
while (Length--)
{
*Buffer = *Attribute++;
CSR_API(CsrFillOutputAttrib)
{
PCSRSS_SCREEN_BUFFER Buff;
- PCHAR Buffer;
+ PUCHAR Buffer;
NTSTATUS Status;
int X, Y, Length;
UCHAR Attr;
}
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff);
if (! NT_SUCCESS(Status))
{
DPRINT("CsrGetCursorInfo\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff);
if (! NT_SUCCESS(Status))
DPRINT("CsrSetCursorInfo\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
DPRINT("CsrSetConsoleMode\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = Win32CsrGetObject(ProcessData,
Request->Data.SetConsoleModeRequest.ConsoleHandle,
(Object_t **) &Console);
DPRINT("CsrGetConsoleMode\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
(Object_t **) &Console);
if (! NT_SUCCESS(Status))
}
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Buff = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_SCREEN_BUFFER));
if (NULL == Buff)
}
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff);
if (! NT_SUCCESS(Status))
DPRINT("CsrSetTitle\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
if (Request->Header.DataSize
< sizeof(CSRSS_SET_TITLE_REQUEST) - 1
DPRINT("CsrGetTitle\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockConsole(ProcessData,
Request->Data.GetTitleRequest.ConsoleHandle,
&Console);
}
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputRequest.ConsoleHandle,
&Buff);
Offset = (((Y + Buff->ShowY) % Buff->MaxY) * Buff->MaxX + WriteRegion.left) * 2;
for (X = WriteRegion.left; X <= WriteRegion.right; X++)
{
- SET_CELL_BUFFER(Buff, Offset, CurCharInfo->Char.AsciiChar, CurCharInfo->Attributes);
+ if (Request->Data.WriteConsoleOutputRequest.Unicode)
+ {
+ CHAR AsciiChar;
+ ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar);
+ SET_CELL_BUFFER(Buff, Offset, AsciiChar, CurCharInfo->Attributes);
+ }
+ else
+ {
+ SET_CELL_BUFFER(Buff, Offset, CurCharInfo->Char.AsciiChar, CurCharInfo->Attributes);
+ }
CurCharInfo++;
}
}
DPRINT("CsrFlushInputBuffer\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockConsole(ProcessData,
Request->Data.FlushInputBufferRequest.ConsoleInput,
&Console);
/* Destroy the event */
HeapFree(Win32CsrApiHeap, 0, Input);
}
+ ResetEvent(Console->ActiveEvent);
Console->WaitingChars=0;
ConioUnlockConsole(Console);
}
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff);
if (! NT_SUCCESS(Status))
{
/* FIXME: The subtracted rectangle is off by one line */
FillRegion.top += 1;
- ConioFillRegion(Buff, &FillRegion, Fill);
+ ConioFillRegion(Console, Buff, &FillRegion, &Fill, Request->Data.ScrollConsoleScreenBufferRequest.Unicode);
DoFill = TRUE;
}
CSR_API(CsrReadConsoleOutputChar)
{
NTSTATUS Status;
+ PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
DWORD Xpos, Ypos;
- BYTE* ReadBuffer;
+ PCHAR ReadBuffer;
DWORD i;
+ ULONG CharSize;
+ CHAR Char;
DPRINT("CsrReadConsoleOutputChar\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = Reply->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
ReadBuffer = Reply->Data.ReadConsoleOutputCharReply.String;
+
+ CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
+
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (! NT_SUCCESS(Status))
+ {
+ return Reply->Status = Status;
+ }
- Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, Buff);
+ Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff);
if (! NT_SUCCESS(Status))
{
return Reply->Status = Status;
for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i)
{
- *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
+ Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)];
+
+ if(Request->Data.ReadConsoleOutputCharRequest.Unicode)
+ {
+ ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char);
+ ReadBuffer += sizeof(WCHAR);
+ }
+ else
+ *(ReadBuffer++) = Char;
- ReadBuffer++;
Xpos++;
if (Xpos == Buff->MaxX)
Reply->Header.DataSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead;
ConioUnlockScreenBuffer(Buff);
+ if (NULL != Console)
+ {
+ ConioUnlockConsole(Console);
+ }
+
+ Reply->Data.ReadConsoleOutputCharReply.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Reply->Data.ReadConsoleOutputCharReply.String) / CharSize;
return Reply->Status;
}
DPRINT("CsrReadConsoleOutputAttrib\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = Reply->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
ReadBuffer = Reply->Data.ReadConsoleOutputAttribReply.String;
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff);
DPRINT("CsrGetNumberOfConsoleInputEvents\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = Reply->Header.MessageSize - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
if (! NT_SUCCESS(Status))
DPRINT("CsrPeekConsoleInput\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console);
if(! NT_SUCCESS(Status))
if (! IsListEmpty(&Console->InputEvents))
{
- CurrentItem = &Console->InputEvents;
+ CurrentItem = Console->InputEvents.Flink;
- while (NumItems < Length)
+ while (CurrentItem != &Console->InputEvents && NumItems < Length)
{
- ++NumItems;
Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
- *InputRecord++ = Item->InputEvent;
-
- if (CurrentItem->Flink == &Console->InputEvents)
+
+ if (Item->Fake)
{
- break;
+ CurrentItem = CurrentItem->Flink;
+ continue;
}
- else
+
+ ++NumItems;
+ *InputRecord = Item->InputEvent;
+
+ if (Request->Data.ReadInputRequest.Unicode == FALSE)
{
- CurrentItem = CurrentItem->Flink;
+ ConioInputEventToAnsi(Console, InputRecord);
}
+
+ InputRecord++;
+ CurrentItem = CurrentItem->Flink;
}
}
RECT ReadRegion;
RECT ScreenRect;
DWORD i, Y, X, Offset;
+ UINT CodePage;
DPRINT("CsrReadConsoleOutput\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff);
if (! NT_SUCCESS(Status))
BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord;
Length = BufferSize.X * BufferSize.Y;
Size = Length * sizeof(CHAR_INFO);
+
+ /* FIXME: Is this correct? */
+ CodePage = ProcessData->Console->OutputCodePage;
if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase)
|| (((PVOID)CharInfo + Size) > (ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize)))
Offset = (((Y + Buff->ShowY) % Buff->MaxY) * Buff->MaxX + ReadRegion.left) * 2;
for (X = ReadRegion.left; X < ReadRegion.right; ++X)
{
- CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(Buff, Offset);
+ if (Request->Data.ReadConsoleOutputRequest.Unicode)
+ {
+ MultiByteToWideChar(CodePage, 0,
+ (PCHAR)&GET_CELL_BUFFER(Buff, Offset), 1,
+ &CurCharInfo->Char.UnicodeChar, 1);
+ }
+ else
+ {
+ CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(Buff, Offset);
+ }
CurCharInfo->Attributes = GET_CELL_BUFFER(Buff, Offset);
++CurCharInfo;
}
DPRINT("CsrWriteConsoleInput\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console);
if (! NT_SUCCESS(Status))
Record->InputEvent = *InputRecord++;
if (KEY_EVENT == Record->InputEvent.EventType)
{
+ /* FIXME - convert from unicode to ascii!! */
ConioProcessChar(Console, Record);
}
}
DPRINT("CsrHardwareStateProperty\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
Status = ConioLockConsole(ProcessData,
Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
DPRINT("CsrGetConsoleWindow\n");
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
- Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
- Status = ConioLockConsole(ProcessData,
- Request->Data.ConsoleWindowRequest.ConsoleHandle,
- &Console);
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
return Reply->Status = Status;
}
- Reply->Data.ConsoleWindowReply.WindowHandle = Console->hWindow;
+ Reply->Data.GetConsoleWindowReply.WindowHandle = Console->hWindow;
ConioUnlockConsole(Console);
return Reply->Status = STATUS_SUCCESS;
}
+CSR_API(CsrSetConsoleIcon)
+{
+ PCSRSS_CONSOLE Console;
+ NTSTATUS Status;
+
+ DPRINT("CsrSetConsoleIcon\n");
+
+ Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (! NT_SUCCESS(Status))
+ {
+ return Reply->Status = Status;
+ }
+
+ Console->hWindowIcon = Request->Data.SetConsoleIconRequest.WindowIcon;
+ Reply->Status = (ConioChangeIcon(Console) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
+ ConioUnlockConsole(Console);
+
+ return Reply->Status;
+}
+
+CSR_API(CsrGetConsoleCodePage)
+{
+ PCSRSS_CONSOLE Console;
+ NTSTATUS Status;
+
+ DPRINT("CsrGetConsoleCodePage\n");
+
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (! NT_SUCCESS(Status))
+ {
+ return Reply->Status = Status;
+ }
+
+ Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+ Reply->Data.GetConsoleCodePage.CodePage = Console->CodePage;
+ ConioUnlockConsole(Console);
+ return Reply->Status = STATUS_SUCCESS;
+}
+
+CSR_API(CsrSetConsoleCodePage)
+{
+ PCSRSS_CONSOLE Console;
+ NTSTATUS Status;
+
+ DPRINT("CsrSetConsoleCodePage\n");
+
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (! NT_SUCCESS(Status))
+ {
+ return Reply->Status = Status;
+ }
+
+ Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+ if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage))
+ {
+ Console->CodePage = Request->Data.SetConsoleCodePage.CodePage;
+ ConioUnlockConsole(Console);
+ return Reply->Status = STATUS_SUCCESS;
+ }
+ ConioUnlockConsole(Console);
+ return Reply->Status = STATUS_UNSUCCESSFUL;
+}
+
+CSR_API(CsrGetConsoleOutputCodePage)
+{
+ PCSRSS_CONSOLE Console;
+ NTSTATUS Status;
+
+ DPRINT("CsrGetConsoleOutputCodePage\n");
+
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (! NT_SUCCESS(Status))
+ {
+ return Reply->Status = Status;
+ }
+
+ Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+ Reply->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage;
+ ConioUnlockConsole(Console);
+ return Reply->Status = STATUS_SUCCESS;
+}
+
+CSR_API(CsrSetConsoleOutputCodePage)
+{
+ PCSRSS_CONSOLE Console;
+ NTSTATUS Status;
+
+ DPRINT("CsrSetConsoleOutputCodePage\n");
+
+ Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ if (! NT_SUCCESS(Status))
+ {
+ return Reply->Status = Status;
+ }
+
+ Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
+ if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage))
+ {
+ Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage;
+ ConioUnlockConsole(Console);
+ return Reply->Status = STATUS_SUCCESS;
+ }
+ ConioUnlockConsole(Console);
+ return Reply->Status = STATUS_UNSUCCESSFUL;
+}
+
/* EOF */