Author: hbelusca
Date: Fri Aug 29 19:45:45 2014
New Revision: 63978
URL:
http://svn.reactos.org/svn/reactos?rev=63978&view=rev
Log:
[CONSRV]
Commit my work that I've done during my trip from Albi back to Paris (part 1/2):
- QuickEdit and InsertMode are input modes that are related to CONSRV terminal(s),
therefore remove them from CONDRV that needs to be agnostic about terminal specificities.
- Separate history helper functions from the line discipline functions to different
files.
Added:
branches/condrv_restructure/win32ss/user/winsrv/consrv/history.c (with props)
branches/condrv_restructure/win32ss/user/winsrv/consrv/history.h (with props)
Modified:
branches/condrv_restructure/win32ss/user/winsrv/consrv.cmake
branches/condrv_restructure/win32ss/user/winsrv/consrv/alias.c
branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/console.c
branches/condrv_restructure/win32ss/user/winsrv/consrv/console.c
branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h
branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio_winsrv.h
branches/condrv_restructure/win32ss/user/winsrv/consrv/lineinput.c
branches/condrv_restructure/win32ss/user/winsrv/consrv/lineinput.h
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv.cmake
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv.cmake [iso-8859-1] (original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv.cmake [iso-8859-1] Fri Aug 29
19:45:45 2014
@@ -11,6 +11,7 @@
consrv/console.c
consrv/frontendctl.c
consrv/handle.c
+ consrv/history.c
consrv/init.c
consrv/lineinput.c
consrv/settings.c
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/alias.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/alias.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/alias.c [iso-8859-1] Fri Aug 29
19:45:45 2014
@@ -18,16 +18,16 @@
typedef struct _ALIAS_ENTRY
{
+ struct _ALIAS_ENTRY* Next;
UNICODE_STRING Source;
UNICODE_STRING Target;
- struct _ALIAS_ENTRY* Next;
} ALIAS_ENTRY, *PALIAS_ENTRY;
typedef struct _ALIAS_HEADER
{
+ struct _ALIAS_HEADER* Next;
UNICODE_STRING ExeName;
PALIAS_ENTRY Data;
- struct _ALIAS_HEADER* Next;
} ALIAS_HEADER, *PALIAS_HEADER;
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/console.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/console.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/console.c [iso-8859-1]
Fri Aug 29 19:45:45 2014
@@ -257,13 +257,6 @@
Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT;
- Console->InsertMode = ConsoleInfo->InsertMode;
- Console->LineBuffer = NULL;
- Console->LinePos = Console->LineMaxSize = Console->LineSize = 0;
- Console->LineComplete = Console->LineUpPressed = FALSE;
- Console->LineInsertToggle = Console->InsertMode;
- // LineWakeupMask
-
/* Set-up the code page */
Console->InputCodePage = Console->OutputCodePage = ConsoleInfo->CodePage;
@@ -518,17 +511,7 @@
if (INPUT_BUFFER == Object->Type)
{
PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
-
*ConsoleMode = InputBuffer->Mode;
-
- if (Console->QuickEdit || Console->InsertMode)
- {
- // Windows does this, even if it's not documented on MSDN
- *ConsoleMode |= ENABLE_EXTENDED_FLAGS;
-
- if (Console->QuickEdit ) *ConsoleMode |= ENABLE_QUICK_EDIT_MODE;
- if (Console->InsertMode) *ConsoleMode |= ENABLE_INSERT_MODE;
- }
}
else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
{
@@ -548,8 +531,6 @@
IN PCONSOLE_IO_OBJECT Object,
IN ULONG ConsoleMode)
{
-#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS | \
- ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE )
#define CONSOLE_VALID_INPUT_MODES ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \
ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \
ENABLE_MOUSE_INPUT )
@@ -567,48 +548,24 @@
{
PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
- DPRINT("SetConsoleMode(Input, %d)\n", ConsoleMode);
-
- /*
- * 1. Only the presence of valid mode flags is allowed.
- */
- if (ConsoleMode & ~(CONSOLE_VALID_INPUT_MODES |
CONSOLE_VALID_CONTROL_MODES))
+ /* Only the presence of valid mode flags is allowed */
+ if (ConsoleMode & ~CONSOLE_VALID_INPUT_MODES)
{
Status = STATUS_INVALID_PARAMETER;
- goto Quit;
- }
-
- /*
- * 2. If we use control mode flags without ENABLE_EXTENDED_FLAGS,
- * then consider the flags invalid.
- *
- if ( (ConsoleMode & CONSOLE_VALID_CONTROL_MODES) &&
- (ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0 )
+ }
+ else
+ {
+ InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES);
+ }
+ }
+ else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
+ {
+ PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object;
+
+ /* Only the presence of valid mode flags is allowed */
+ if (ConsoleMode & ~CONSOLE_VALID_OUTPUT_MODES)
{
Status = STATUS_INVALID_PARAMETER;
- goto Quit;
- }
- */
-
- /*
- * 3. Now we can continue.
- */
- if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES)
- {
- Console->QuickEdit = !!(ConsoleMode & ENABLE_QUICK_EDIT_MODE);
- Console->InsertMode = !!(ConsoleMode & ENABLE_INSERT_MODE);
- }
- InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES);
- }
- else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
- {
- PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object;
-
- DPRINT("SetConsoleMode(Output, %d)\n", ConsoleMode);
-
- if (ConsoleMode & ~CONSOLE_VALID_OUTPUT_MODES)
- {
- Status = STATUS_INVALID_PARAMETER;
}
else
{
@@ -620,7 +577,6 @@
Status = STATUS_INVALID_HANDLE;
}
-Quit:
return Status;
}
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/console.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/console.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/console.c [iso-8859-1] Fri Aug
29 19:45:45 2014
@@ -15,6 +15,7 @@
#include <ndk/psfuncs.h>
#include <alias.h>
+#include <history.h>
#include "procinit.h"
#define NDEBUG
@@ -427,7 +428,14 @@
Console->NumberOfHistoryBuffers = ConsoleInfo.NumberOfHistoryBuffers;
Console->HistoryNoDup = ConsoleInfo.HistoryNoDup;
- Console->QuickEdit = ConsoleInfo.QuickEdit;
+ /* Initialize the Input Line Discipline */
+ Console->LineBuffer = NULL;
+ Console->LinePos = Console->LineMaxSize = Console->LineSize = 0;
+ Console->LineComplete = Console->LineUpPressed = FALSE;
+ // LineWakeupMask
+ Console->LineInsertToggle =
+ Console->InsertMode = ConsoleInfo.InsertMode;
+ Console->QuickEdit = ConsoleInfo.QuickEdit;
/* Colour table */
memcpy(Console->Colors, ConsoleInfo.Colors, sizeof(ConsoleInfo.Colors));
@@ -755,13 +763,34 @@
PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
PCONSOLE_IO_OBJECT Object;
+ PULONG ConsoleMode = &ConsoleModeRequest->Mode;
+
Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
ConsoleModeRequest->Handle,
&Object, NULL, GENERIC_READ, TRUE, 0);
if (!NT_SUCCESS(Status)) return Status;
+ /* Get the standard console modes */
Status = ConDrvGetConsoleMode(Object->Console, Object,
- &ConsoleModeRequest->Mode);
+ ConsoleMode);
+ if (NT_SUCCESS(Status))
+ {
+ /*
+ * If getting the console modes succeeds, then retrieve
+ * the extended CONSRV-specific input modes.
+ */
+ if (INPUT_BUFFER == Object->Type)
+ {
+ if (Object->Console->InsertMode || Object->Console->QuickEdit)
+ {
+ /* Windows does this, even if it is not documented on MSDN */
+ *ConsoleMode |= ENABLE_EXTENDED_FLAGS;
+
+ if (Object->Console->InsertMode) *ConsoleMode |=
ENABLE_INSERT_MODE;
+ if (Object->Console->QuickEdit ) *ConsoleMode |=
ENABLE_QUICK_EDIT_MODE;
+ }
+ }
+ }
ConSrvReleaseObject(Object, TRUE);
return Status;
@@ -773,17 +802,52 @@
IN ULONG ConsoleMode);
CSR_API(SrvSetConsoleMode)
{
+#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS | \
+ ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE )
+
NTSTATUS Status;
PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
PCONSOLE_IO_OBJECT Object;
+
+ ULONG ConsoleMode = ConsoleModeRequest->Mode;
Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
ConsoleModeRequest->Handle,
&Object, NULL, GENERIC_WRITE, TRUE, 0);
if (!NT_SUCCESS(Status)) return Status;
+ /* Set the standard console modes (without the CONSRV-specific input modes) */
+ ConsoleMode &= ~CONSOLE_VALID_CONTROL_MODES; // Remove CONSRV-specific input
modes.
Status = ConDrvSetConsoleMode(Object->Console, Object,
- ConsoleModeRequest->Mode);
+ ConsoleMode);
+ if (NT_SUCCESS(Status))
+ {
+ /*
+ * If setting the console modes succeeds, then set
+ * the extended CONSRV-specific input modes.
+ */
+ if (INPUT_BUFFER == Object->Type)
+ {
+ ConsoleMode = ConsoleModeRequest->Mode;
+
+ if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES)
+ {
+ /*
+ * If we use control mode flags without ENABLE_EXTENDED_FLAGS,
+ * then consider the flags invalid.
+ */
+ if ((ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ Object->Console->InsertMode = !!(ConsoleMode &
ENABLE_INSERT_MODE);
+ Object->Console->QuickEdit = !!(ConsoleMode &
ENABLE_QUICK_EDIT_MODE);
+ }
+ }
+ }
+ }
ConSrvReleaseObject(Object, TRUE);
return Status;
Added: branches/condrv_restructure/win32ss/user/winsrv/consrv/history.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/history.c (added)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/history.c [iso-8859-1] Fri Aug
29 19:45:45 2014
@@ -0,0 +1,561 @@
+/*
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Console Server DLL
+ * FILE: win32ss/user/winsrv/consrv/history.c
+ * PURPOSE: Console line input functions
+ * PROGRAMMERS: Jeffrey Morlan
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "consrv.h"
+
+#define NDEBUG
+#include <debug.h>
+
+typedef struct _HISTORY_BUFFER
+{
+ LIST_ENTRY ListEntry;
+ ULONG Position;
+ ULONG MaxEntries;
+ ULONG NumEntries;
+ UNICODE_STRING ExeName;
+ PUNICODE_STRING Entries;
+} HISTORY_BUFFER, *PHISTORY_BUFFER;
+
+
+BOOLEAN
+ConvertInputAnsiToUnicode(PCONSOLE Console,
+ PVOID Source,
+ USHORT SourceLength,
+ // BOOLEAN IsUnicode,
+ PWCHAR* Target,
+ PUSHORT TargetLength);
+BOOLEAN
+ConvertInputUnicodeToAnsi(PCONSOLE Console,
+ PVOID Source,
+ USHORT SourceLength,
+ // BOOLEAN IsAnsi,
+ PCHAR/* * */ Target,
+ /*P*/USHORT TargetLength);
+
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+static PHISTORY_BUFFER
+HistoryCurrentBuffer(PCONSRV_CONSOLE Console,
+ PUNICODE_STRING ExeName)
+{
+ PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
+ PHISTORY_BUFFER Hist;
+
+ for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink)
+ {
+ Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
+ if (RtlEqualUnicodeString(ExeName, &Hist->ExeName, FALSE))
+ return Hist;
+ }
+
+ /* Couldn't find the buffer, create a new one */
+ Hist = ConsoleAllocHeap(0, sizeof(HISTORY_BUFFER) + ExeName->Length);
+ if (!Hist) return NULL;
+ Hist->MaxEntries = Console->HistoryBufferSize;
+ Hist->NumEntries = 0;
+ Hist->Entries = ConsoleAllocHeap(0, Hist->MaxEntries *
sizeof(UNICODE_STRING));
+ if (!Hist->Entries)
+ {
+ ConsoleFreeHeap(Hist);
+ return NULL;
+ }
+ Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName->Length;
+ Hist->ExeName.Buffer = (PWCHAR)(Hist + 1);
+ memcpy(Hist->ExeName.Buffer, ExeName->Buffer, ExeName->Length);
+ InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry);
+ return Hist;
+}
+
+static PHISTORY_BUFFER
+HistoryFindBuffer(PCONSRV_CONSOLE Console,
+ PVOID ExeName,
+ USHORT ExeLength,
+ BOOLEAN UnicodeExe)
+{
+ UNICODE_STRING ExeNameU;
+
+ PLIST_ENTRY Entry;
+ PHISTORY_BUFFER Hist = NULL;
+
+ if (ExeName == NULL) return NULL;
+
+ if (UnicodeExe)
+ {
+ ExeNameU.Buffer = ExeName;
+ /* Length is in bytes */
+ ExeNameU.MaximumLength = ExeLength;
+ }
+ else
+ {
+ if (!ConvertInputAnsiToUnicode(Console,
+ ExeName, ExeLength,
+ &ExeNameU.Buffer,
&ExeNameU.MaximumLength))
+ {
+ return NULL;
+ }
+ }
+ ExeNameU.Length = ExeNameU.MaximumLength;
+
+ Entry = Console->HistoryBuffers.Flink;
+ while (Entry != &Console->HistoryBuffers)
+ {
+ Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
+
+ /* For the history APIs, the caller is allowed to give only part of the name */
+ if (RtlPrefixUnicodeString(&ExeNameU, &Hist->ExeName, TRUE))
+ {
+ if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
+ return Hist;
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
+ return NULL;
+}
+
+static VOID
+HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
+{
+ if (!Hist) return;
+
+ while (Hist->NumEntries != 0)
+ RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]);
+
+ ConsoleFreeHeap(Hist->Entries);
+ RemoveEntryList(&Hist->ListEntry);
+ ConsoleFreeHeap(Hist);
+}
+
+VOID
+HistoryAddEntry(PCONSRV_CONSOLE Console,
+ PUNICODE_STRING ExeName,
+ PUNICODE_STRING Entry)
+{
+ // UNICODE_STRING NewEntry;
+ PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
+
+ if (!Hist) return;
+
+ // NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR);
+ // NewEntry.Buffer = Console->LineBuffer;
+
+ /* Don't add blank or duplicate entries */
+ if (Entry->Length == 0 || Hist->MaxEntries == 0 ||
+ (Hist->NumEntries > 0 &&
+ RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1], Entry,
FALSE)))
+ {
+ return;
+ }
+
+ if (Console->HistoryNoDup)
+ {
+ INT i;
+
+ /* Check if this line has been entered before */
+ for (i = Hist->NumEntries - 1; i >= 0; i--)
+ {
+ if (RtlEqualUnicodeString(&Hist->Entries[i], Entry, FALSE))
+ {
+ UNICODE_STRING NewEntry;
+
+ /* Just rotate the list to bring this entry to the end */
+ NewEntry = Hist->Entries[i];
+ memmove(&Hist->Entries[i], &Hist->Entries[i + 1],
+ (Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING));
+ Hist->Entries[Hist->NumEntries - 1] = NewEntry;
+ Hist->Position = Hist->NumEntries - 1;
+ return;
+ }
+ }
+ }
+
+ if (Hist->NumEntries == Hist->MaxEntries)
+ {
+ /* List is full, remove oldest entry */
+ RtlFreeUnicodeString(&Hist->Entries[0]);
+ memmove(&Hist->Entries[0], &Hist->Entries[1],
+ --Hist->NumEntries * sizeof(UNICODE_STRING));
+ }
+
+ if (NT_SUCCESS(RtlDuplicateUnicodeString(0, Entry,
&Hist->Entries[Hist->NumEntries])))
+ Hist->NumEntries++;
+ Hist->Position = Hist->NumEntries - 1;
+}
+
+VOID
+HistoryGetCurrentEntry(PCONSRV_CONSOLE Console,
+ PUNICODE_STRING ExeName,
+ PUNICODE_STRING Entry)
+{
+ PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
+
+ if (!Hist || Hist->NumEntries == 0)
+ Entry->Length = 0;
+ else
+ *Entry = Hist->Entries[Hist->Position];
+}
+
+BOOL
+HistoryRecallHistory(PCONSRV_CONSOLE Console,
+ PUNICODE_STRING ExeName,
+ INT Offset,
+ PUNICODE_STRING Entry)
+{
+ PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
+ ULONG Position = 0;
+
+ if (!Hist || Hist->NumEntries == 0) return FALSE;
+
+ Position = Hist->Position + Offset;
+ Position = min(max(Position, 0), Hist->NumEntries - 1);
+ Hist->Position = Position;
+
+ *Entry = Hist->Entries[Hist->Position];
+ return TRUE;
+}
+
+BOOL
+HistoryFindEntryByPrefix(PCONSRV_CONSOLE Console,
+ PUNICODE_STRING ExeName,
+ PUNICODE_STRING Prefix,
+ PUNICODE_STRING Entry)
+{
+ INT HistPos;
+
+ /* Search for history entries starting with input. */
+ PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
+ if (!Hist || Hist->NumEntries == 0) return FALSE;
+
+ /*
+ * Like Up/F5, on first time start from current (usually last) entry,
+ * but on subsequent times start at previous entry.
+ */
+ if (Console->LineUpPressed)
+ Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries)
- 1;
+ Console->LineUpPressed = TRUE;
+
+ // Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
+ // Entry.Buffer = Console->LineBuffer;
+
+ /*
+ * Keep going backwards, even wrapping around to the end,
+ * until we get back to starting point.
+ */
+ HistPos = Hist->Position;
+ do
+ {
+ if (RtlPrefixUnicodeString(Prefix, &Hist->Entries[HistPos], FALSE))
+ {
+ Hist->Position = HistPos;
+ *Entry = Hist->Entries[HistPos];
+ return TRUE;
+ }
+ if (--HistPos < 0) HistPos += Hist->NumEntries;
+ } while (HistPos != Hist->Position);
+
+ return FALSE;
+}
+
+VOID
+HistoryDeleteCurrentBuffer(PCONSRV_CONSOLE Console,
+ PVOID ExeName)
+{
+ HistoryDeleteBuffer(HistoryCurrentBuffer(Console, ExeName));
+}
+
+VOID
+HistoryDeleteBuffers(PCONSRV_CONSOLE Console)
+{
+ PLIST_ENTRY CurrentEntry;
+ PHISTORY_BUFFER HistoryBuffer;
+
+ while (!IsListEmpty(&Console->HistoryBuffers))
+ {
+ CurrentEntry = RemoveHeadList(&Console->HistoryBuffers);
+ HistoryBuffer = CONTAINING_RECORD(CurrentEntry, HISTORY_BUFFER, ListEntry);
+ HistoryDeleteBuffer(HistoryBuffer);
+ }
+}
+
+
+/* PUBLIC SERVER APIS *********************************************************/
+
+CSR_API(SrvGetConsoleCommandHistory)
+{
+ NTSTATUS Status;
+ PCONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryRequest;
+ PCONSRV_CONSOLE Console;
+ ULONG BytesWritten = 0;
+ PHISTORY_BUFFER Hist;
+
+ DPRINT1("SrvGetConsoleCommandHistory entered\n");
+
+ if ( !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&GetCommandHistoryRequest->History,
+ GetCommandHistoryRequest->HistoryLength,
+ sizeof(BYTE)) ||
+ !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&GetCommandHistoryRequest->ExeName,
+ GetCommandHistoryRequest->ExeLength,
+ sizeof(BYTE)) )
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ Hist = HistoryFindBuffer(Console,
+ GetCommandHistoryRequest->ExeName,
+ GetCommandHistoryRequest->ExeLength,
+ GetCommandHistoryRequest->Unicode2);
+ if (Hist)
+ {
+ ULONG i;
+
+ LPSTR TargetBufferA;
+ LPWSTR TargetBufferW;
+ ULONG BufferSize = GetCommandHistoryRequest->HistoryLength;
+
+ ULONG Offset = 0;
+ ULONG SourceLength;
+
+ if (GetCommandHistoryRequest->Unicode)
+ {
+ TargetBufferW = GetCommandHistoryRequest->History;
+ BufferSize /= sizeof(WCHAR);
+ }
+ else
+ {
+ TargetBufferA = GetCommandHistoryRequest->History;
+ }
+
+ for (i = 0; i < Hist->NumEntries; i++)
+ {
+ SourceLength = Hist->Entries[i].Length / sizeof(WCHAR);
+ if (Offset + SourceLength + 1 > BufferSize)
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ break;
+ }
+
+ if (GetCommandHistoryRequest->Unicode)
+ {
+ RtlCopyMemory(&TargetBufferW[Offset], Hist->Entries[i].Buffer,
SourceLength * sizeof(WCHAR));
+ Offset += SourceLength;
+ TargetBufferW[Offset++] = L'\0';
+ }
+ else
+ {
+ ConvertInputUnicodeToAnsi(Console,
+ Hist->Entries[i].Buffer, SourceLength *
sizeof(WCHAR),
+ &TargetBufferA[Offset], SourceLength);
+ Offset += SourceLength;
+ TargetBufferA[Offset++] = '\0';
+ }
+ }
+
+ if (GetCommandHistoryRequest->Unicode)
+ BytesWritten = Offset * sizeof(WCHAR);
+ else
+ BytesWritten = Offset;
+ }
+
+ // GetCommandHistoryRequest->HistoryLength = TargetBuffer -
(PBYTE)GetCommandHistoryRequest->History;
+ GetCommandHistoryRequest->HistoryLength = BytesWritten;
+
+ ConSrvReleaseConsole(Console, TRUE);
+ return Status;
+}
+
+CSR_API(SrvGetConsoleCommandHistoryLength)
+{
+ NTSTATUS Status;
+ PCONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryLengthRequest;
+ PCONSRV_CONSOLE Console;
+ PHISTORY_BUFFER Hist;
+ ULONG Length = 0;
+
+ if (!CsrValidateMessageBuffer(ApiMessage,
+
(PVOID*)&GetCommandHistoryLengthRequest->ExeName,
+ GetCommandHistoryLengthRequest->ExeLength,
+ sizeof(BYTE)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ Hist = HistoryFindBuffer(Console,
+ GetCommandHistoryLengthRequest->ExeName,
+ GetCommandHistoryLengthRequest->ExeLength,
+ GetCommandHistoryLengthRequest->Unicode2);
+ if (Hist)
+ {
+ ULONG i;
+ for (i = 0; i < Hist->NumEntries; i++)
+ Length += Hist->Entries[i].Length + sizeof(WCHAR); // Each entry is
returned NULL-terminated
+ }
+ /*
+ * Quick and dirty way of getting the number of bytes of the
+ * corresponding ANSI string from the one in UNICODE.
+ */
+ if (!GetCommandHistoryLengthRequest->Unicode)
+ Length /= sizeof(WCHAR);
+
+ GetCommandHistoryLengthRequest->HistoryLength = Length;
+
+ ConSrvReleaseConsole(Console, TRUE);
+ return Status;
+}
+
+CSR_API(SrvExpungeConsoleCommandHistory)
+{
+ NTSTATUS Status;
+ PCONSOLE_EXPUNGECOMMANDHISTORY ExpungeCommandHistoryRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ExpungeCommandHistoryRequest;
+ PCONSRV_CONSOLE Console;
+ PHISTORY_BUFFER Hist;
+
+ if (!CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&ExpungeCommandHistoryRequest->ExeName,
+ ExpungeCommandHistoryRequest->ExeLength,
+ sizeof(BYTE)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ Hist = HistoryFindBuffer(Console,
+ ExpungeCommandHistoryRequest->ExeName,
+ ExpungeCommandHistoryRequest->ExeLength,
+ ExpungeCommandHistoryRequest->Unicode2);
+ HistoryDeleteBuffer(Hist);
+
+ ConSrvReleaseConsole(Console, TRUE);
+ return Status;
+}
+
+CSR_API(SrvSetConsoleNumberOfCommands)
+{
+ NTSTATUS Status;
+ PCONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryNumberCommandsRequest;
+ PCONSRV_CONSOLE Console;
+ PHISTORY_BUFFER Hist;
+
+ if (!CsrValidateMessageBuffer(ApiMessage,
+
(PVOID*)&SetHistoryNumberCommandsRequest->ExeName,
+ SetHistoryNumberCommandsRequest->ExeLength,
+ sizeof(BYTE)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ Hist = HistoryFindBuffer(Console,
+ SetHistoryNumberCommandsRequest->ExeName,
+ SetHistoryNumberCommandsRequest->ExeLength,
+ SetHistoryNumberCommandsRequest->Unicode2);
+ if (Hist)
+ {
+ ULONG MaxEntries = SetHistoryNumberCommandsRequest->NumCommands;
+ PUNICODE_STRING OldEntryList = Hist->Entries;
+ PUNICODE_STRING NewEntryList = ConsoleAllocHeap(0, MaxEntries *
sizeof(UNICODE_STRING));
+ if (!NewEntryList)
+ {
+ Status = STATUS_NO_MEMORY;
+ }
+ else
+ {
+ /* If necessary, shrink by removing oldest entries */
+ for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--)
+ {
+ RtlFreeUnicodeString(Hist->Entries++);
+ Hist->Position += (Hist->Position == 0);
+ }
+
+ Hist->MaxEntries = MaxEntries;
+ Hist->Entries = memcpy(NewEntryList, Hist->Entries,
+ Hist->NumEntries * sizeof(UNICODE_STRING));
+ ConsoleFreeHeap(OldEntryList);
+ }
+ }
+
+ ConSrvReleaseConsole(Console, TRUE);
+ return Status;
+}
+
+CSR_API(SrvGetConsoleHistory)
+{
+#if 0 // Vista+
+ PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
+ PCONSRV_CONSOLE Console;
+ NTSTATUS Status =
ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console,
TRUE);
+ if (NT_SUCCESS(Status))
+ {
+ HistoryInfoRequest->HistoryBufferSize = Console->HistoryBufferSize;
+ HistoryInfoRequest->NumberOfHistoryBuffers =
Console->NumberOfHistoryBuffers;
+ HistoryInfoRequest->dwFlags = Console->HistoryNoDup;
+ ConSrvReleaseConsole(Console, TRUE);
+ }
+ return Status;
+#else
+ DPRINT1("%s not yet implemented\n", __FUNCTION__);
+ return STATUS_NOT_IMPLEMENTED;
+#endif
+}
+
+CSR_API(SrvSetConsoleHistory)
+{
+#if 0 // Vista+
+ PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
+ PCONSRV_CONSOLE Console;
+ NTSTATUS Status =
ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console,
TRUE);
+ if (NT_SUCCESS(Status))
+ {
+ Console->HistoryBufferSize = HistoryInfoRequest->HistoryBufferSize;
+ Console->NumberOfHistoryBuffers =
HistoryInfoRequest->NumberOfHistoryBuffers;
+ Console->HistoryNoDup = HistoryInfoRequest->dwFlags &
HISTORY_NO_DUP_FLAG;
+ ConSrvReleaseConsole(Console, TRUE);
+ }
+ return Status;
+#else
+ DPRINT1("%s not yet implemented\n", __FUNCTION__);
+ return STATUS_NOT_IMPLEMENTED;
+#endif
+}
+
+CSR_API(SrvSetConsoleCommandHistoryMode)
+{
+ NTSTATUS Status;
+ PCONSOLE_SETHISTORYMODE SetHistoryModeRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryModeRequest;
+ PCONSRV_CONSOLE Console;
+
+ DPRINT1("SrvSetConsoleCommandHistoryMode(Mode = %d) is not yet
implemented\n",
+ SetHistoryModeRequest->Mode);
+
+ Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* This API is not yet implemented */
+ Status = STATUS_NOT_IMPLEMENTED;
+
+ ConSrvReleaseConsole(Console, TRUE);
+ return Status;
+}
+
+/* EOF */
Propchange: branches/condrv_restructure/win32ss/user/winsrv/consrv/history.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/condrv_restructure/win32ss/user/winsrv/consrv/history.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/history.h (added)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/history.h [iso-8859-1] Fri Aug
29 19:45:45 2014
@@ -0,0 +1,11 @@
+/*
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Console Server DLL
+ * FILE: win32ss/user/winsrv/consrv/history.h
+ * PURPOSE: Console line input functions
+ * PROGRAMMERS: Jeffrey Morlan
+ */
+
+#pragma once
+
+VOID HistoryDeleteBuffers(PCONSRV_CONSOLE Console);
Propchange: branches/condrv_restructure/win32ss/user/winsrv/consrv/history.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h [iso-8859-1]
Fri Aug 29 19:45:45 2014
@@ -279,23 +279,11 @@
ULONG ConsoleID; /* The ID of the console */
LIST_ENTRY ListEntry; /* Entry in the list of consoles */
-/**************************** Input buffer and data ***************************/
+ HANDLE UnpauseEvent; /* When != NULL, event for pausing the
console */
+
+/******************************** Input buffer ********************************/
CONSOLE_INPUT_BUFFER InputBuffer; /* Input buffer of the console */
UINT InputCodePage;
-
- /** Put those things in CONSOLE_INPUT_BUFFER in PWINSRV_CONSOLE ?? **/
- PWCHAR LineBuffer; /* Current line being input, in line buffered
mode */
- ULONG LineMaxSize; /* Maximum size of line in characters
(including CR+LF) */
- ULONG LineSize; /* Current size of line */
- ULONG LinePos; /* Current position within line */
- BOOLEAN LineComplete; /* User pressed enter, ready to send back to
client */
- BOOLEAN LineUpPressed;
- BOOLEAN LineInsertToggle; /* Replace character over cursor instead of
inserting */
- ULONG LineWakeupMask; /* Bitmap of which control characters will
end line input */
-
- /** In PWINSRV_CONSOLE ?? **/
- BOOLEAN InsertMode;
- /*************************************************/
/******************************* Screen buffers *******************************/
LIST_ENTRY BufferList; /* List of all screen buffers for this
console */
@@ -305,8 +293,6 @@
/****************************** Other properties ******************************/
UNICODE_STRING OriginalTitle; /* Original title of console, the one defined
when the console leader is launched; it never changes. Always NULL-terminated */
UNICODE_STRING Title; /* Title of console. Always NULL-terminated
*/
-
- HANDLE UnpauseEvent; /* When != NULL, event for pausing the
console */
COORD ConsoleSize; /* The current size of the console, for
text-mode only */
BOOLEAN FixedSize; /* TRUE if the console is of fixed size */
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio_winsrv.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
---
branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio_winsrv.h [iso-8859-1]
(original)
+++
branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio_winsrv.h [iso-8859-1]
Fri Aug 29 19:45:45 2014
@@ -131,8 +131,6 @@
PCONSOLE_PROCESS_DATA NotifiedLastCloseProcess; /* Pointer to the unique process that
needs to be notified when the console leader process is killed */
BOOLEAN NotifyLastClose; /* TRUE if the console should send a control event
when the console leader process is killed */
- BOOLEAN QuickEdit;
-
/******************************* Pausing support ******************************/
BYTE PauseFlags;
LIST_ENTRY ReadWaitQueue; /* List head for the queue of unique input buffer
read wait blocks */
@@ -144,6 +142,19 @@
ULONG HistoryBufferSize; /* Size for newly created history buffers */
ULONG NumberOfHistoryBuffers; /* Maximum number of history buffers allowed
*/
BOOLEAN HistoryNoDup; /* Remove old duplicate history entries */
+
+/**************************** Input Line Discipline ***************************/
+ PWCHAR LineBuffer; /* Current line being input, in line buffered
mode */
+ ULONG LineMaxSize; /* Maximum size of line in characters
(including CR+LF) */
+ ULONG LineSize; /* Current size of line */
+ ULONG LinePos; /* Current position within line */
+ BOOLEAN LineComplete; /* User pressed enter, ready to send back to
client */
+ BOOLEAN LineUpPressed;
+ BOOLEAN LineInsertToggle; /* Replace character over cursor instead of
inserting */
+ ULONG LineWakeupMask; /* Bitmap of which control characters will
end line input */
+
+ BOOLEAN InsertMode;
+ BOOLEAN QuickEdit;
/************************ Virtual DOS Machine support *************************/
COORD VDMBufferSize; /* Real size of the VDM buffer, in units of ???
*/
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/lineinput.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/lineinput.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/lineinput.c [iso-8859-1] Fri
Aug 29 19:45:45 2014
@@ -12,16 +12,6 @@
#define NDEBUG
#include <debug.h>
-
-typedef struct _HISTORY_BUFFER
-{
- LIST_ENTRY ListEntry;
- UINT Position;
- UINT MaxEntries;
- UINT NumEntries;
- UNICODE_STRING ExeName;
- PUNICODE_STRING Entries;
-} HISTORY_BUFFER, *PHISTORY_BUFFER;
BOOLEAN
@@ -40,183 +30,35 @@
/*P*/USHORT TargetLength);
-/* PRIVATE FUNCTIONS **********************************************************/
-
-static PHISTORY_BUFFER
-HistoryCurrentBuffer(PCONSRV_CONSOLE Console,
- PUNICODE_STRING ExeName)
-{
- PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
- PHISTORY_BUFFER Hist;
-
- for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink)
- {
- Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
- if (RtlEqualUnicodeString(ExeName, &Hist->ExeName, FALSE))
- return Hist;
- }
-
- /* Couldn't find the buffer, create a new one */
- Hist = ConsoleAllocHeap(0, sizeof(HISTORY_BUFFER) + ExeName->Length);
- if (!Hist) return NULL;
- Hist->MaxEntries = Console->HistoryBufferSize;
- Hist->NumEntries = 0;
- Hist->Entries = ConsoleAllocHeap(0, Hist->MaxEntries *
sizeof(UNICODE_STRING));
- if (!Hist->Entries)
- {
- ConsoleFreeHeap(Hist);
- return NULL;
- }
- Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName->Length;
- Hist->ExeName.Buffer = (PWCHAR)(Hist + 1);
- memcpy(Hist->ExeName.Buffer, ExeName->Buffer, ExeName->Length);
- InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry);
- return Hist;
-}
-
-static VOID
+VOID
HistoryAddEntry(PCONSRV_CONSOLE Console,
- PUNICODE_STRING ExeName)
-{
- UNICODE_STRING NewEntry;
- PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
- INT i;
-
- if (!Hist) return;
-
- NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR);
- NewEntry.Buffer = Console->LineBuffer;
-
- /* Don't add blank or duplicate entries */
- if (NewEntry.Length == 0 || Hist->MaxEntries == 0 ||
- (Hist->NumEntries > 0 &&
- RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1],
&NewEntry, FALSE)))
- {
- return;
- }
-
- if (Console->HistoryNoDup)
- {
- /* Check if this line has been entered before */
- for (i = Hist->NumEntries - 1; i >= 0; i--)
- {
- if (RtlEqualUnicodeString(&Hist->Entries[i], &NewEntry, FALSE))
- {
- /* Just rotate the list to bring this entry to the end */
- NewEntry = Hist->Entries[i];
- memmove(&Hist->Entries[i], &Hist->Entries[i + 1],
- (Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING));
- Hist->Entries[Hist->NumEntries - 1] = NewEntry;
- Hist->Position = Hist->NumEntries - 1;
- return;
- }
- }
- }
-
- if (Hist->NumEntries == Hist->MaxEntries)
- {
- /* List is full, remove oldest entry */
- RtlFreeUnicodeString(&Hist->Entries[0]);
- memmove(&Hist->Entries[0], &Hist->Entries[1],
- --Hist->NumEntries * sizeof(UNICODE_STRING));
- }
-
- if (NT_SUCCESS(RtlDuplicateUnicodeString(0, &NewEntry,
&Hist->Entries[Hist->NumEntries])))
- Hist->NumEntries++;
- Hist->Position = Hist->NumEntries - 1;
-}
-
-static VOID
+ PUNICODE_STRING ExeName,
+ PUNICODE_STRING Entry);
+BOOL
+HistoryRecallHistory(PCONSRV_CONSOLE Console,
+ PUNICODE_STRING ExeName,
+ INT Offset,
+ PUNICODE_STRING Entry);
+VOID
HistoryGetCurrentEntry(PCONSRV_CONSOLE Console,
PUNICODE_STRING ExeName,
- PUNICODE_STRING Entry)
-{
- PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
-
- if (!Hist || Hist->NumEntries == 0)
- Entry->Length = 0;
- else
- *Entry = Hist->Entries[Hist->Position];
-}
-
-static PHISTORY_BUFFER
-HistoryFindBuffer(PCONSRV_CONSOLE Console,
- PVOID ExeName,
- USHORT ExeLength,
- BOOLEAN UnicodeExe)
-{
- UNICODE_STRING ExeNameU;
-
- PLIST_ENTRY Entry;
- PHISTORY_BUFFER Hist = NULL;
-
- if (ExeName == NULL) return NULL;
-
- if (UnicodeExe)
- {
- ExeNameU.Buffer = ExeName;
- /* Length is in bytes */
- ExeNameU.MaximumLength = ExeLength;
- }
- else
- {
- if (!ConvertInputAnsiToUnicode(Console,
- ExeName, ExeLength,
- &ExeNameU.Buffer,
&ExeNameU.MaximumLength))
- {
- return NULL;
- }
- }
- ExeNameU.Length = ExeNameU.MaximumLength;
-
- Entry = Console->HistoryBuffers.Flink;
- while (Entry != &Console->HistoryBuffers)
- {
- Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
-
- /* For the history APIs, the caller is allowed to give only part of the name */
- if (RtlPrefixUnicodeString(&ExeNameU, &Hist->ExeName, TRUE))
- {
- if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
- return Hist;
- }
-
- Entry = Entry->Flink;
- }
-
- if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
- return NULL;
-}
+ PUNICODE_STRING Entry);
+VOID
+HistoryDeleteCurrentBuffer(PCONSRV_CONSOLE Console,
+ PVOID ExeName);
+BOOL
+HistoryFindEntryByPrefix(PCONSRV_CONSOLE Console,
+ PUNICODE_STRING ExeName,
+ PUNICODE_STRING Prefix,
+ PUNICODE_STRING Entry);
+
+
+
+/* PRIVATE FUNCTIONS **********************************************************/
static VOID
-HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
-{
- if (!Hist) return;
-
- while (Hist->NumEntries != 0)
- RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]);
-
- ConsoleFreeHeap(Hist->Entries);
- RemoveEntryList(&Hist->ListEntry);
- ConsoleFreeHeap(Hist);
-}
-
-VOID
-HistoryDeleteBuffers(PCONSRV_CONSOLE Console)
-{
- PLIST_ENTRY CurrentEntry;
- PHISTORY_BUFFER HistoryBuffer;
-
- while (!IsListEmpty(&Console->HistoryBuffers))
- {
- CurrentEntry = RemoveHeadList(&Console->HistoryBuffers);
- HistoryBuffer = CONTAINING_RECORD(CurrentEntry, HISTORY_BUFFER, ListEntry);
- HistoryDeleteBuffer(HistoryBuffer);
- }
-}
-
-static VOID
-LineInputSetPos(PCONSRV_CONSOLE Console, UINT Pos)
+LineInputSetPos(PCONSRV_CONSOLE Console,
+ UINT Pos)
{
if (Pos != Console->LinePos && Console->InputBuffer.Mode &
ENABLE_ECHO_INPUT)
{
@@ -240,7 +82,10 @@
}
static VOID
-LineInputEdit(PCONSRV_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, PWCHAR
Insertion)
+LineInputEdit(PCONSRV_CONSOLE Console,
+ UINT NumToDelete,
+ UINT NumToInsert,
+ PWCHAR Insertion)
{
PTEXTMODE_SCREEN_BUFFER ActiveBuffer;
UINT Pos = Console->LinePos;
@@ -276,6 +121,7 @@
LineInputSetPos(Console, Pos + NumToInsert);
}
+#if 0
static VOID
LineInputRecallHistory(PCONSRV_CONSOLE Console,
PUNICODE_STRING ExeName,
@@ -295,6 +141,22 @@
Hist->Entries[Hist->Position].Length / sizeof(WCHAR),
Hist->Entries[Hist->Position].Buffer);
}
+#else
+static VOID
+LineInputRecallHistory(PCONSRV_CONSOLE Console,
+ PUNICODE_STRING ExeName,
+ INT Offset)
+{
+ UNICODE_STRING Entry;
+
+ if (!HistoryRecallHistory(Console, ExeName, Offset, &Entry)) return;
+
+ LineInputSetPos(Console, 0);
+ LineInputEdit(Console, Console->LineSize,
+ Entry.Length / sizeof(WCHAR),
+ Entry.Buffer);
+}
+#endif
VOID
LineInputKeyDown(PCONSRV_CONSOLE Console,
@@ -302,9 +164,12 @@
KEY_EVENT_RECORD *KeyEvent)
{
UINT Pos = Console->LinePos;
- PHISTORY_BUFFER Hist;
UNICODE_STRING Entry;
- INT HistPos;
+ // INT HistPos;
+
+ /*
+ * First, deal with control keys...
+ */
switch (KeyEvent->wVirtualKeyCode)
{
@@ -314,20 +179,20 @@
LineInputEdit(Console, Console->LineSize, 0, NULL);
return;
case VK_HOME:
- /* Move to start of line. With ctrl, erase everything left of cursor */
+ /* Move to start of line. With CTRL, erase everything left of cursor */
LineInputSetPos(Console, 0);
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED |
RIGHT_CTRL_PRESSED))
LineInputEdit(Console, Pos, 0, NULL);
return;
case VK_END:
- /* Move to end of line. With ctrl, erase everything right of cursor */
+ /* Move to end of line. With CTRL, erase everything right of cursor */
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED |
RIGHT_CTRL_PRESSED))
LineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
else
LineInputSetPos(Console, Console->LineSize);
return;
case VK_LEFT:
- /* Move left. With ctrl, move to beginning of previous word */
+ /* Move left. With CTRL, move to beginning of previous word */
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED |
RIGHT_CTRL_PRESSED))
{
while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ')
Pos--;
@@ -341,13 +206,12 @@
return;
case VK_RIGHT:
case VK_F1:
- /* Move right. With ctrl, move to beginning of next word */
+ /* Move right. With CTRL, move to beginning of next word */
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED |
RIGHT_CTRL_PRESSED))
{
while (Pos < Console->LineSize && Console->LineBuffer[Pos]
!= L' ') Pos++;
while (Pos < Console->LineSize && Console->LineBuffer[Pos]
== L' ') Pos++;
LineInputSetPos(Console, Pos);
- return;
}
else
{
@@ -379,8 +243,10 @@
return;
case VK_UP:
case VK_F5:
- /* Recall previous history entry. On first time, actually recall the
- * current (usually last) entry; on subsequent times go back. */
+ /*
+ * Recall previous history entry. On first time, actually recall the
+ * current (usually last) entry; on subsequent times go back.
+ */
LineInputRecallHistory(Console, ExeName, Console->LineUpPressed ? -1 : 0);
Console->LineUpPressed = TRUE;
return;
@@ -404,24 +270,47 @@
break;
case VK_F7:
if (KeyEvent->dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
- HistoryDeleteBuffer(HistoryCurrentBuffer(Console, ExeName));
+ HistoryDeleteCurrentBuffer(Console, ExeName);
return;
case VK_F8:
+
+ {
+ UNICODE_STRING EntryFound;
+
+ Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
+ Entry.Buffer = Console->LineBuffer;
+
+ if (HistoryFindEntryByPrefix(Console, ExeName, &Entry, &EntryFound))
+ {
+ LineInputEdit(Console, Console->LineSize - Pos,
+ EntryFound.Length / sizeof(WCHAR) - Pos,
+ &EntryFound.Buffer[Pos]);
+ /* Cursor stays where it was */
+ LineInputSetPos(Console, Pos);
+ }
+ }
+#if 0
+ PHISTORY_BUFFER Hist;
+
/* Search for history entries starting with input. */
Hist = HistoryCurrentBuffer(Console, ExeName);
if (!Hist || Hist->NumEntries == 0) return;
- /* Like Up/F5, on first time start from current (usually last) entry,
- * but on subsequent times start at previous entry. */
+ /*
+ * Like Up/F5, on first time start from current (usually last) entry,
+ * but on subsequent times start at previous entry.
+ */
if (Console->LineUpPressed)
Hist->Position = (Hist->Position ? Hist->Position :
Hist->NumEntries) - 1;
Console->LineUpPressed = TRUE;
- Entry.Length = Console->LinePos * sizeof(WCHAR);
+ Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
Entry.Buffer = Console->LineBuffer;
- /* Keep going backwards, even wrapping around to the end,
- * until we get back to starting point */
+ /*
+ * Keep going backwards, even wrapping around to the end,
+ * until we get back to starting point.
+ */
HistPos = Hist->Position;
do
{
@@ -437,8 +326,15 @@
}
if (--HistPos < 0) HistPos += Hist->NumEntries;
} while (HistPos != Hist->Position);
- return;
- }
+#endif
+
+ return;
+ }
+
+
+ /*
+ * OK, we can continue...
+ */
if (KeyEvent->uChar.UnicodeChar == L'\b' &&
Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT)
{
@@ -452,9 +348,12 @@
}
else if (KeyEvent->uChar.UnicodeChar == L'\r')
{
- HistoryAddEntry(Console, ExeName);
+ Entry.Length = Entry.MaximumLength = Console->LineSize * sizeof(WCHAR);
+ Entry.Buffer = Console->LineBuffer;
+ HistoryAddEntry(Console, ExeName, &Entry);
/* TODO: Expand aliases */
+ DPRINT1("TODO: Expand aliases\n");
LineInputSetPos(Console, Console->LineSize);
Console->LineBuffer[Console->LineSize++] = L'\r';
@@ -466,9 +365,11 @@
}
}
- /* Add \n if processed input. There should usually be room for it,
+ /*
+ * Add \n if processed input. There should usually be room for it,
* but an exception to the rule exists: the buffer could have been
- * pre-filled with LineMaxSize - 1 characters. */
+ * pre-filled with LineMaxSize - 1 characters.
+ */
if (Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
Console->LineSize < Console->LineMaxSize)
{
@@ -507,272 +408,4 @@
/* PUBLIC SERVER APIS *********************************************************/
-CSR_API(SrvGetConsoleCommandHistory)
-{
- NTSTATUS Status;
- PCONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryRequest;
- PCONSRV_CONSOLE Console;
- ULONG BytesWritten = 0;
- PHISTORY_BUFFER Hist;
-
- DPRINT1("SrvGetConsoleCommandHistory entered\n");
-
- if ( !CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&GetCommandHistoryRequest->History,
- GetCommandHistoryRequest->HistoryLength,
- sizeof(BYTE)) ||
- !CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&GetCommandHistoryRequest->ExeName,
- GetCommandHistoryRequest->ExeLength,
- sizeof(BYTE)) )
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- Hist = HistoryFindBuffer(Console,
- GetCommandHistoryRequest->ExeName,
- GetCommandHistoryRequest->ExeLength,
- GetCommandHistoryRequest->Unicode2);
- if (Hist)
- {
- UINT i;
-
- LPSTR TargetBufferA;
- LPWSTR TargetBufferW;
- ULONG BufferSize = GetCommandHistoryRequest->HistoryLength;
-
- UINT Offset = 0;
- UINT SourceLength;
-
- if (GetCommandHistoryRequest->Unicode)
- {
- TargetBufferW = GetCommandHistoryRequest->History;
- BufferSize /= sizeof(WCHAR);
- }
- else
- {
- TargetBufferA = GetCommandHistoryRequest->History;
- }
-
- for (i = 0; i < Hist->NumEntries; i++)
- {
- SourceLength = Hist->Entries[i].Length / sizeof(WCHAR);
- if (Offset + SourceLength + 1 > BufferSize)
- {
- Status = STATUS_BUFFER_OVERFLOW;
- break;
- }
-
- if (GetCommandHistoryRequest->Unicode)
- {
- RtlCopyMemory(&TargetBufferW[Offset], Hist->Entries[i].Buffer,
SourceLength * sizeof(WCHAR));
- Offset += SourceLength;
- TargetBufferW[Offset++] = L'\0';
- }
- else
- {
- ConvertInputUnicodeToAnsi(Console,
- Hist->Entries[i].Buffer, SourceLength *
sizeof(WCHAR),
- &TargetBufferA[Offset], SourceLength);
- Offset += SourceLength;
- TargetBufferA[Offset++] = '\0';
- }
- }
-
- if (GetCommandHistoryRequest->Unicode)
- BytesWritten = Offset * sizeof(WCHAR);
- else
- BytesWritten = Offset;
- }
-
- // GetCommandHistoryRequest->HistoryLength = TargetBuffer -
(PBYTE)GetCommandHistoryRequest->History;
- GetCommandHistoryRequest->HistoryLength = BytesWritten;
-
- ConSrvReleaseConsole(Console, TRUE);
- return Status;
-}
-
-CSR_API(SrvGetConsoleCommandHistoryLength)
-{
- NTSTATUS Status;
- PCONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryLengthRequest;
- PCONSRV_CONSOLE Console;
- PHISTORY_BUFFER Hist;
- ULONG Length = 0;
- UINT i;
-
- if (!CsrValidateMessageBuffer(ApiMessage,
-
(PVOID*)&GetCommandHistoryLengthRequest->ExeName,
- GetCommandHistoryLengthRequest->ExeLength,
- sizeof(BYTE)))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- Hist = HistoryFindBuffer(Console,
- GetCommandHistoryLengthRequest->ExeName,
- GetCommandHistoryLengthRequest->ExeLength,
- GetCommandHistoryLengthRequest->Unicode2);
- if (Hist)
- {
- for (i = 0; i < Hist->NumEntries; i++)
- Length += Hist->Entries[i].Length + sizeof(WCHAR); // Each entry is
returned NULL-terminated
- }
- /*
- * Quick and dirty way of getting the number of bytes of the
- * corresponding ANSI string from the one in UNICODE.
- */
- if (!GetCommandHistoryLengthRequest->Unicode)
- Length /= sizeof(WCHAR);
-
- GetCommandHistoryLengthRequest->HistoryLength = Length;
-
- ConSrvReleaseConsole(Console, TRUE);
- return Status;
-}
-
-CSR_API(SrvExpungeConsoleCommandHistory)
-{
- NTSTATUS Status;
- PCONSOLE_EXPUNGECOMMANDHISTORY ExpungeCommandHistoryRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ExpungeCommandHistoryRequest;
- PCONSRV_CONSOLE Console;
- PHISTORY_BUFFER Hist;
-
- if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&ExpungeCommandHistoryRequest->ExeName,
- ExpungeCommandHistoryRequest->ExeLength,
- sizeof(BYTE)))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- Hist = HistoryFindBuffer(Console,
- ExpungeCommandHistoryRequest->ExeName,
- ExpungeCommandHistoryRequest->ExeLength,
- ExpungeCommandHistoryRequest->Unicode2);
- HistoryDeleteBuffer(Hist);
-
- ConSrvReleaseConsole(Console, TRUE);
- return Status;
-}
-
-CSR_API(SrvSetConsoleNumberOfCommands)
-{
- NTSTATUS Status;
- PCONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryNumberCommandsRequest;
- PCONSRV_CONSOLE Console;
- PHISTORY_BUFFER Hist;
-
- if (!CsrValidateMessageBuffer(ApiMessage,
-
(PVOID*)&SetHistoryNumberCommandsRequest->ExeName,
- SetHistoryNumberCommandsRequest->ExeLength,
- sizeof(BYTE)))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- Hist = HistoryFindBuffer(Console,
- SetHistoryNumberCommandsRequest->ExeName,
- SetHistoryNumberCommandsRequest->ExeLength,
- SetHistoryNumberCommandsRequest->Unicode2);
- if (Hist)
- {
- UINT MaxEntries = SetHistoryNumberCommandsRequest->NumCommands;
- PUNICODE_STRING OldEntryList = Hist->Entries;
- PUNICODE_STRING NewEntryList = ConsoleAllocHeap(0, MaxEntries *
sizeof(UNICODE_STRING));
- if (!NewEntryList)
- {
- Status = STATUS_NO_MEMORY;
- }
- else
- {
- /* If necessary, shrink by removing oldest entries */
- for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--)
- {
- RtlFreeUnicodeString(Hist->Entries++);
- Hist->Position += (Hist->Position == 0);
- }
-
- Hist->MaxEntries = MaxEntries;
- Hist->Entries = memcpy(NewEntryList, Hist->Entries,
- Hist->NumEntries * sizeof(UNICODE_STRING));
- ConsoleFreeHeap(OldEntryList);
- }
- }
-
- ConSrvReleaseConsole(Console, TRUE);
- return Status;
-}
-
-CSR_API(SrvGetConsoleHistory)
-{
-#if 0 // Vista+
- PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
- PCONSRV_CONSOLE Console;
- NTSTATUS Status =
ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console,
TRUE);
- if (NT_SUCCESS(Status))
- {
- HistoryInfoRequest->HistoryBufferSize = Console->HistoryBufferSize;
- HistoryInfoRequest->NumberOfHistoryBuffers =
Console->NumberOfHistoryBuffers;
- HistoryInfoRequest->dwFlags = Console->HistoryNoDup;
- ConSrvReleaseConsole(Console, TRUE);
- }
- return Status;
-#else
- DPRINT1("%s not yet implemented\n", __FUNCTION__);
- return STATUS_NOT_IMPLEMENTED;
-#endif
-}
-
-CSR_API(SrvSetConsoleHistory)
-{
-#if 0 // Vista+
- PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
- PCONSRV_CONSOLE Console;
- NTSTATUS Status =
ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console,
TRUE);
- if (NT_SUCCESS(Status))
- {
- Console->HistoryBufferSize = HistoryInfoRequest->HistoryBufferSize;
- Console->NumberOfHistoryBuffers =
HistoryInfoRequest->NumberOfHistoryBuffers;
- Console->HistoryNoDup = HistoryInfoRequest->dwFlags &
HISTORY_NO_DUP_FLAG;
- ConSrvReleaseConsole(Console, TRUE);
- }
- return Status;
-#else
- DPRINT1("%s not yet implemented\n", __FUNCTION__);
- return STATUS_NOT_IMPLEMENTED;
-#endif
-}
-
-CSR_API(SrvSetConsoleCommandHistoryMode)
-{
- NTSTATUS Status;
- PCONSOLE_SETHISTORYMODE SetHistoryModeRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryModeRequest;
- PCONSRV_CONSOLE Console;
-
- DPRINT1("SrvSetConsoleCommandHistoryMode(Mode = %d) is not yet
implemented\n",
- SetHistoryModeRequest->Mode);
-
- Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* This API is not yet implemented */
- Status = STATUS_NOT_IMPLEMENTED;
-
- ConSrvReleaseConsole(Console, TRUE);
- return Status;
-}
-
/* EOF */
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/lineinput.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/lineinput.h [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/lineinput.h [iso-8859-1] Fri
Aug 29 19:45:45 2014
@@ -1,15 +1,13 @@
/*
* LICENSE: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
- * FILE: win32ss/user/winsrv/consrv/lineinput.c
+ * FILE: win32ss/user/winsrv/consrv/lineinput.h
* PURPOSE: Console line input functions
* PROGRAMMERS: Jeffrey Morlan
*/
#pragma once
-VOID HistoryDeleteBuffers(PCONSRV_CONSOLE Console);
-
VOID
LineInputKeyDown(PCONSRV_CONSOLE Console,
PUNICODE_STRING ExeName,