* FILE: win32ss/user/winsrv/consrv/lineinput.c
* PURPOSE: Console line input functions
* PROGRAMMERS: Jeffrey Morlan
- *
- * NOTE: It's something frontend-related... (--> read my mind... ;) )
*/
/* INCLUDES *******************************************************************/
UINT Position;
UINT MaxEntries;
UINT NumEntries;
- PUNICODE_STRING Entries;
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
}
static PHISTORY_BUFFER
-HistoryFindBuffer(PCONSOLE Console, PUNICODE_STRING ExeName)
+HistoryFindBuffer(PCONSOLE Console,
+ PVOID ExeName,
+ USHORT ExeLength,
+ BOOLEAN UnicodeExe)
{
- PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
+ 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 */
- PHISTORY_BUFFER Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
- if (RtlPrefixUnicodeString(ExeName, &Hist->ExeName, TRUE))
+ if (RtlPrefixUnicodeString(&ExeNameU, &Hist->ExeName, TRUE))
+ {
+ if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
return Hist;
+ }
+
Entry = Entry->Flink;
}
+
+ if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
return NULL;
}
ConsoleFreeHeap(Hist);
}
-VOID FASTCALL
+VOID
HistoryDeleteBuffers(PCONSOLE Console)
{
PLIST_ENTRY CurrentEntry;
}
static VOID
-LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion)
+LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, PWCHAR Insertion)
{
PTEXTMODE_SCREEN_BUFFER ActiveBuffer;
UINT Pos = Console->LinePos;
Hist->Entries[Hist->Position].Buffer);
}
-VOID FASTCALL
+VOID
LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
{
UINT Pos = Console->LinePos;
CSR_API(SrvGetConsoleCommandHistory)
{
+ NTSTATUS Status;
PCONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryRequest;
- PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE Console;
- NTSTATUS Status;
+ ULONG BytesWritten = 0;
PHISTORY_BUFFER Hist;
- PBYTE Buffer = (PBYTE)GetCommandHistoryRequest->History;
- ULONG BufferSize = GetCommandHistoryRequest->Length;
- UINT i;
+
+ DPRINT1("SrvGetConsoleCommandHistory entered\n");
if ( !CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&GetCommandHistoryRequest->History,
- GetCommandHistoryRequest->Length,
+ GetCommandHistoryRequest->HistoryLength,
sizeof(BYTE)) ||
!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&GetCommandHistoryRequest->ExeName.Buffer,
- GetCommandHistoryRequest->ExeName.Length,
+ (PVOID*)&GetCommandHistoryRequest->ExeName,
+ GetCommandHistoryRequest->ExeLength,
sizeof(BYTE)) )
{
return STATUS_INVALID_PARAMETER;
}
- Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
- if (NT_SUCCESS(Status))
+ Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ Hist = HistoryFindBuffer(Console,
+ GetCommandHistoryRequest->ExeName,
+ GetCommandHistoryRequest->ExeLength,
+ GetCommandHistoryRequest->Unicode2);
+ if (Hist)
{
- Hist = HistoryFindBuffer(Console, &GetCommandHistoryRequest->ExeName);
- 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
{
- for (i = 0; i < Hist->NumEntries; i++)
+ TargetBufferA = GetCommandHistoryRequest->History;
+ }
+
+ for (i = 0; i < Hist->NumEntries; i++)
+ {
+ SourceLength = Hist->Entries[i].Length / sizeof(WCHAR);
+ if (Offset + SourceLength + 1 > BufferSize)
{
- if (BufferSize < (Hist->Entries[i].Length + sizeof(WCHAR)))
- {
- Status = STATUS_BUFFER_OVERFLOW;
- break;
- }
- memcpy(Buffer, Hist->Entries[i].Buffer, Hist->Entries[i].Length);
- Buffer += Hist->Entries[i].Length;
- *(PWCHAR)Buffer = L'\0';
- Buffer += sizeof(WCHAR);
+ 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';
}
}
- GetCommandHistoryRequest->Length = Buffer - (PBYTE)GetCommandHistoryRequest->History;
- ConSrvReleaseConsole(Console, TRUE);
+
+ 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;
- PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE Console;
- NTSTATUS Status;
PHISTORY_BUFFER Hist;
ULONG Length = 0;
UINT i;
if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&GetCommandHistoryLengthRequest->ExeName.Buffer,
- GetCommandHistoryLengthRequest->ExeName.Length,
+ (PVOID*)&GetCommandHistoryLengthRequest->ExeName,
+ GetCommandHistoryLengthRequest->ExeLength,
sizeof(BYTE)))
{
return STATUS_INVALID_PARAMETER;
}
- Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
- if (NT_SUCCESS(Status))
+ Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ Hist = HistoryFindBuffer(Console,
+ GetCommandHistoryLengthRequest->ExeName,
+ GetCommandHistoryLengthRequest->ExeLength,
+ GetCommandHistoryLengthRequest->Unicode2);
+ if (Hist)
{
- Hist = HistoryFindBuffer(Console, &GetCommandHistoryLengthRequest->ExeName);
- if (Hist)
- {
- for (i = 0; i < Hist->NumEntries; i++)
- Length += Hist->Entries[i].Length + sizeof(WCHAR);
- }
- GetCommandHistoryLengthRequest->Length = Length;
- ConSrvReleaseConsole(Console, TRUE);
+ 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;
- PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE Console;
PHISTORY_BUFFER Hist;
- NTSTATUS Status;
if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&ExpungeCommandHistoryRequest->ExeName.Buffer,
- ExpungeCommandHistoryRequest->ExeName.Length,
+ (PVOID*)&ExpungeCommandHistoryRequest->ExeName,
+ ExpungeCommandHistoryRequest->ExeLength,
sizeof(BYTE)))
{
return STATUS_INVALID_PARAMETER;
}
- Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
- if (NT_SUCCESS(Status))
- {
- Hist = HistoryFindBuffer(Console, &ExpungeCommandHistoryRequest->ExeName);
- HistoryDeleteBuffer(Hist);
- ConSrvReleaseConsole(Console, TRUE);
- }
+ 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;
- PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE Console;
PHISTORY_BUFFER Hist;
- NTSTATUS Status;
- UINT MaxEntries = SetHistoryNumberCommandsRequest->NumCommands;
- PUNICODE_STRING OldEntryList, NewEntryList;
if (!CsrValidateMessageBuffer(ApiMessage,
- (PVOID*)&SetHistoryNumberCommandsRequest->ExeName.Buffer,
- SetHistoryNumberCommandsRequest->ExeName.Length,
+ (PVOID*)&SetHistoryNumberCommandsRequest->ExeName,
+ SetHistoryNumberCommandsRequest->ExeLength,
sizeof(BYTE)))
{
return STATUS_INVALID_PARAMETER;
}
- Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
- if (NT_SUCCESS(Status))
+ Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ Hist = HistoryFindBuffer(Console,
+ SetHistoryNumberCommandsRequest->ExeName,
+ SetHistoryNumberCommandsRequest->ExeLength,
+ SetHistoryNumberCommandsRequest->Unicode2);
+ if (Hist)
{
- Hist = HistoryFindBuffer(Console, &SetHistoryNumberCommandsRequest->ExeName);
- if (Hist)
+ UINT MaxEntries = SetHistoryNumberCommandsRequest->NumCommands;
+ PUNICODE_STRING OldEntryList = Hist->Entries;
+ PUNICODE_STRING NewEntryList = ConsoleAllocHeap(0, MaxEntries * sizeof(UNICODE_STRING));
+ if (!NewEntryList)
{
- OldEntryList = Hist->Entries;
- 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--)
{
- Status = STATUS_NO_MEMORY;
+ RtlFreeUnicodeString(Hist->Entries++);
+ Hist->Position += (Hist->Position == 0);
}
- 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);
- }
+ Hist->MaxEntries = MaxEntries;
+ Hist->Entries = memcpy(NewEntryList, Hist->Entries,
+ Hist->NumEntries * sizeof(UNICODE_STRING));
+ ConsoleFreeHeap(OldEntryList);
}
- ConSrvReleaseConsole(Console, TRUE);
}
+
+ ConSrvReleaseConsole(Console, TRUE);
return Status;
}
CSR_API(SrvGetConsoleHistory)
{
+#if 0 // Vista+
PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
PCONSOLE Console;
NTSTATUS Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
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;
PCONSOLE Console;
NTSTATUS Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
ConSrvReleaseConsole(Console, TRUE);
}
return Status;
+#else
+ DPRINT1("%s not yet implemented\n", __FUNCTION__);
+ return STATUS_NOT_IMPLEMENTED;
+#endif
}
CSR_API(SrvSetConsoleCommandHistoryMode)
{
- DPRINT1("%s not yet implemented\n", __FUNCTION__);
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PCONSOLE_SETHISTORYMODE SetHistoryModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryModeRequest;
+ PCONSOLE 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 */