[KERNEL32], [WIN32CSR]
authorJeffrey Morlan <mrnobo1024@yahoo.com>
Sat, 5 Jun 2010 00:45:08 +0000 (00:45 +0000)
committerJeffrey Morlan <mrnobo1024@yahoo.com>
Sat, 5 Jun 2010 00:45:08 +0000 (00:45 +0000)
- Implement console history (note: not too useful yet without any way to recall it)
- Implement APIs GetConsoleCommandHistoryLength, GetConsoleCommandHistory, ExpungeConsoleCommandHistory, SetConsoleNumberOfCommands, GetConsoleHistoryInfo, SetConsoleHistoryInfo.
- Remove stub of obsolete function SetConsoleCommandHistoryMode, which no longer exists in Windows.

svn path=/trunk/; revision=47580

reactos/dll/win32/kernel32/kernel32.pspec
reactos/dll/win32/kernel32/misc/console.c
reactos/include/reactos/subsys/csrss/csrss.h
reactos/subsystems/win32/csrss/win32csr/coninput.c
reactos/subsystems/win32/csrss/win32csr/conio.h
reactos/subsystems/win32/csrss/win32csr/console.c
reactos/subsystems/win32/csrss/win32csr/dllmain.c
reactos/subsystems/win32/csrss/win32csr/guiconsole.c
reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild

index cba32d9..3c09b07 100644 (file)
 @ stdcall GetConsoleFontInfo(long long long ptr)
 @ stdcall GetConsoleFontSize(long long)
 @ stdcall GetConsoleHardwareState(long long ptr)
+@ stdcall GetConsoleHistoryInfo(ptr)
 @ stdcall GetConsoleInputExeNameA(long ptr)
 @ stdcall GetConsoleInputExeNameW(long ptr)
 @ stdcall GetConsoleInputWaitHandle()
 @ stdcall SetComputerNameW(wstr)
 @ stdcall SetConsoleActiveScreenBuffer(long)
 @ stdcall SetConsoleCP(long)
-@ stdcall SetConsoleCommandHistoryMode(long)
 @ stdcall SetConsoleCtrlHandler(ptr long)
 @ stdcall SetConsoleCursor(long long)
 @ stdcall SetConsoleCursorInfo(long ptr)
 @ stdcall SetConsoleDisplayMode(long long ptr)
 @ stdcall SetConsoleFont(long long)
 @ stdcall SetConsoleHardwareState(long long long)
+@ stdcall SetConsoleHistoryInfo(ptr)
 @ stdcall SetConsoleIcon(ptr)
 @ stdcall SetConsoleInputExeNameA(ptr)
 @ stdcall SetConsoleInputExeNameW(ptr)
index 905a673..34b1e84 100644 (file)
@@ -178,6 +178,37 @@ ConsoleControlDispatcher(DWORD CodeAndFlag)
     ExitThread(nExitCode);
 }
 
+/* Get the size needed to copy a string to a capture buffer, including alignment */
+static ULONG
+IntStringSize(LPCVOID String,
+              BOOL Unicode)
+{
+    ULONG Size = (Unicode ? wcslen(String) : strlen(String)) * sizeof(WCHAR);
+    return (Size + 3) & -4;
+}
+
+/* Copy a string to a capture buffer */
+static VOID
+IntCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer,
+                        LPCVOID String,
+                        BOOL Unicode,
+                        PUNICODE_STRING RequestString)
+{
+    ULONG Size;
+    if (Unicode)
+    {
+        Size = wcslen(String) * sizeof(WCHAR);
+        CsrCaptureMessageBuffer(CaptureBuffer, (PVOID)String, Size, (PVOID *)&RequestString->Buffer);
+    }
+    else
+    {
+        Size = strlen(String);
+        CsrAllocateMessagePointer(CaptureBuffer, Size * sizeof(WCHAR), (PVOID *)&RequestString->Buffer);
+        Size = MultiByteToWideChar(CP_ACP, 0, String, Size, RequestString->Buffer, Size * sizeof(WCHAR))
+               * sizeof(WCHAR);
+    }
+    RequestString->Length = RequestString->MaximumLength = Size;
+}
 
 /* FUNCTIONS *****************************************************************/
 
@@ -336,29 +367,56 @@ DuplicateConsoleHandle(HANDLE hConsole,
 }
 
 
+static BOOL
+IntExpungeConsoleCommandHistory(LPCVOID lpExeName, BOOL bUnicode)
+{
+    CSR_API_MESSAGE Request;
+    PCSR_CAPTURE_BUFFER CaptureBuffer;
+    ULONG CsrRequest = MAKE_CSR_API(EXPUNGE_COMMAND_HISTORY, CSR_CONSOLE);
+    NTSTATUS Status;
+
+    if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
+    if (!CaptureBuffer)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+    IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
+                            &Request.Data.ExpungeCommandHistory.ExeName);
+    Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
+    CsrFreeCaptureBuffer(CaptureBuffer);
+    if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+    {
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+    return TRUE;
+}
+
 /*
- * @unimplemented (Undocumented)
+ * @implemented (Undocumented)
  */
-DWORD
+BOOL
 WINAPI
-ExpungeConsoleCommandHistoryW(DWORD Unknown0)
+ExpungeConsoleCommandHistoryW(LPCWSTR lpExeName)
 {
-    DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return 0;
+    return IntExpungeConsoleCommandHistory(lpExeName, TRUE);
 }
 
-
 /*
- * @unimplemented (Undocumented)
+ * @implemented (Undocumented)
  */
-DWORD
+BOOL
 WINAPI
-ExpungeConsoleCommandHistoryA (DWORD Unknown0)
+ExpungeConsoleCommandHistoryA(LPCSTR lpExeName)
 {
-    DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return 0;
+    return IntExpungeConsoleCommandHistory(lpExeName, FALSE);
 }
 
 
@@ -772,61 +830,139 @@ GetConsoleAliasesLengthA(LPSTR lpExeName)
 }
 
 
+static DWORD
+IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName, BOOL bUnicode)
+{
+    CSR_API_MESSAGE Request;
+    PCSR_CAPTURE_BUFFER CaptureBuffer;
+    ULONG CsrRequest = MAKE_CSR_API(GET_COMMAND_HISTORY, CSR_CONSOLE);
+    NTSTATUS Status;
+    DWORD HistoryLength = cbHistory * (bUnicode ? 1 : sizeof(WCHAR));
+
+    if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+
+    CaptureBuffer = CsrAllocateCaptureBuffer(2, IntStringSize(lpExeName, bUnicode) +
+                                                HistoryLength);
+    if (!CaptureBuffer)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return 0;
+    }
+    IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
+                            &Request.Data.GetCommandHistory.ExeName);
+    Request.Data.GetCommandHistory.Length = HistoryLength;
+    CsrAllocateMessagePointer(CaptureBuffer, HistoryLength,
+                              (PVOID*)&Request.Data.GetCommandHistory.History);
+
+    Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
+    if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+    {
+        CsrFreeCaptureBuffer(CaptureBuffer);
+        SetLastErrorByStatus(Status);
+        return 0;
+    }
+
+    if (bUnicode)
+    {
+        memcpy(lpHistory,
+               Request.Data.GetCommandHistory.History,
+               Request.Data.GetCommandHistory.Length);
+    }
+    else
+    {
+        WideCharToMultiByte(CP_ACP, 0,
+                            Request.Data.GetCommandHistory.History,
+                            Request.Data.GetCommandHistory.Length / sizeof(WCHAR),
+                            lpHistory,
+                            cbHistory,
+                            NULL, NULL);
+    }
+    CsrFreeCaptureBuffer(CaptureBuffer);
+    return Request.Data.GetCommandHistory.Length;
+}
+
 /*
- * @unimplemented (Undocumented)
+ * @implemented (Undocumented)
  */
 DWORD
 WINAPI
-GetConsoleCommandHistoryW(DWORD Unknown0,
-                          DWORD Unknown1,
-                          DWORD Unknown2)
+GetConsoleCommandHistoryW(LPWSTR lpHistory,
+                          DWORD cbHistory,
+                          LPCWSTR lpExeName)
 {
-    DPRINT1("GetConsoleCommandHistoryW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return 0;
+    return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, TRUE);
 }
 
-
 /*
- * @unimplemented (Undocumented)
+ * @implemented (Undocumented)
  */
 DWORD
 WINAPI
-GetConsoleCommandHistoryA(DWORD Unknown0,
-                          DWORD Unknown1,
-                          DWORD Unknown2)
+GetConsoleCommandHistoryA(LPSTR lpHistory,
+                          DWORD cbHistory,
+                          LPCSTR lpExeName)
 {
-    DPRINT1("GetConsoleCommandHistoryA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return 0;
+    return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, FALSE);
 }
 
 
+static DWORD
+IntGetConsoleCommandHistoryLength(LPCVOID lpExeName, BOOL bUnicode)
+{
+    CSR_API_MESSAGE Request;
+    PCSR_CAPTURE_BUFFER CaptureBuffer;
+    ULONG CsrRequest = MAKE_CSR_API(GET_COMMAND_HISTORY_LENGTH, CSR_CONSOLE);
+    NTSTATUS Status;
+
+    if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+
+    CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
+    if (!CaptureBuffer)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return 0;
+    }
+    IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
+                            &Request.Data.GetCommandHistoryLength.ExeName);
+    Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
+    CsrFreeCaptureBuffer(CaptureBuffer);
+    if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+    {
+        SetLastErrorByStatus(Status);
+        return 0;
+    }
+    return Request.Data.GetCommandHistoryLength.Length;
+}
+
 /*
- * @unimplemented (Undocumented)
+ * @implemented (Undocumented)
  */
 DWORD
 WINAPI
-GetConsoleCommandHistoryLengthW(DWORD Unknown0)
+GetConsoleCommandHistoryLengthW(LPCWSTR lpExeName)
 {
-    DPRINT1("GetConsoleCommandHistoryLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return 0;
+    return IntGetConsoleCommandHistoryLength(lpExeName, TRUE);
 }
 
-
 /*
- * @unimplemented (Undocumented)
+ * @implemented (Undocumented)
  */
 DWORD
 WINAPI
-GetConsoleCommandHistoryLengthA(DWORD Unknown0)
+GetConsoleCommandHistoryLengthA(LPCSTR lpExeName)
 {
-    DPRINT1("GetConsoleCommandHistoryLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return 0;
+    return IntGetConsoleCommandHistoryLength(lpExeName, FALSE) / sizeof(WCHAR);
 }
 
+
 /*
  * @unimplemented
  */
@@ -1038,19 +1174,6 @@ OpenConsoleW(LPCWSTR wsName,
 }
 
 
-/*
- * @unimplemented (Undocumented)
- */
-BOOL
-WINAPI
-SetConsoleCommandHistoryMode(DWORD dwMode)
-{
-    DPRINT1("SetConsoleCommandHistoryMode(0x%x) UNIMPLEMENTED!\n", dwMode);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
-}
-
-
 /*
  * @unimplemented (Undocumented)
  */
@@ -1176,31 +1299,61 @@ SetConsoleMenuClose(DWORD Unknown0)
 }
 
 
+static BOOL
+IntSetConsoleNumberOfCommands(DWORD dwNumCommands,
+                              LPCVOID lpExeName,
+                              BOOL bUnicode)
+{
+    CSR_API_MESSAGE Request;
+    PCSR_CAPTURE_BUFFER CaptureBuffer;
+    ULONG CsrRequest = MAKE_CSR_API(SET_HISTORY_NUMBER_COMMANDS, CSR_CONSOLE);
+    NTSTATUS Status;
+
+    if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
+    if (!CaptureBuffer)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+    IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
+                            &Request.Data.SetHistoryNumberCommands.ExeName);
+    Request.Data.SetHistoryNumberCommands.NumCommands = dwNumCommands;
+    Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
+    CsrFreeCaptureBuffer(CaptureBuffer);
+    if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+    {
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+    return TRUE;
+}
+
 /*
- * @unimplemented (Undocumented)
+ * @implemented (Undocumented)
  */
 BOOL
 WINAPI
-SetConsoleNumberOfCommandsA(DWORD Unknown0,
-                            DWORD Unknown1)
+SetConsoleNumberOfCommandsA(DWORD dwNumCommands,
+                            LPCWSTR lpExeName)
 {
-    DPRINT1("SetConsoleNumberOfCommandsA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, FALSE);
 }
 
-
 /*
- * @unimplemented (Undocumented)
+ * @implemented (Undocumented)
  */
 BOOL
 WINAPI
-SetConsoleNumberOfCommandsW(DWORD Unknown0,
-                            DWORD Unknown1)
+SetConsoleNumberOfCommandsW(DWORD dwNumCommands,
+                            LPCSTR lpExeName)
 {
-    DPRINT1("SetConsoleNumberOfCommandsW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, TRUE);
 }
 
 
@@ -4027,30 +4180,60 @@ GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
 /*--------------------------------------------------------------
  *  GetConsoleHistoryInfo
  *
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
 GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
 {
-    DPRINT1("GetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    CSR_API_MESSAGE Request;
+    ULONG CsrRequest = MAKE_CSR_API(GET_HISTORY_INFO, CSR_CONSOLE);
+    NTSTATUS Status;
+    if (lpConsoleHistoryInfo->cbSize != sizeof(CONSOLE_HISTORY_INFO))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
+    if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+    {
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+    lpConsoleHistoryInfo->HistoryBufferSize      = Request.Data.GetHistoryInfo.HistoryBufferSize;
+    lpConsoleHistoryInfo->NumberOfHistoryBuffers = Request.Data.GetHistoryInfo.NumberOfHistoryBuffers;
+    lpConsoleHistoryInfo->dwFlags                = Request.Data.GetHistoryInfo.dwFlags;
+    return TRUE;
 }
 
 
 /*--------------------------------------------------------------
  *  SetConsoleHistoryInfo
  *
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
 SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
 {
-    DPRINT1("SetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    CSR_API_MESSAGE Request;
+    ULONG CsrRequest = MAKE_CSR_API(GET_HISTORY_INFO, CSR_CONSOLE);
+    NTSTATUS Status;
+    if (lpConsoleHistoryInfo->cbSize != sizeof(CONSOLE_HISTORY_INFO))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    Request.Data.SetHistoryInfo.HistoryBufferSize      = lpConsoleHistoryInfo->HistoryBufferSize;
+    Request.Data.SetHistoryInfo.NumberOfHistoryBuffers = lpConsoleHistoryInfo->NumberOfHistoryBuffers;
+    Request.Data.SetHistoryInfo.dwFlags                = lpConsoleHistoryInfo->dwFlags;
+    Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
+    if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+    {
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+    return TRUE;
 }
 
 
index 8119392..1f8628e 100644 (file)
@@ -479,6 +479,37 @@ typedef struct
   CONSOLE_SELECTION_INFO Info;
 } CSRSS_GET_CONSOLE_SELECTION_INFO, *PCSRSS_GET_CONSOLE_SELECTION_INFO;
 
+typedef struct
+{
+  UNICODE_STRING ExeName;
+  DWORD Length;
+} CSRSS_GET_COMMAND_HISTORY_LENGTH, *PCSRSS_GET_COMMAND_HISTORY_LENGTH;
+
+typedef struct
+{
+  UNICODE_STRING ExeName;
+  PWCHAR History;
+  DWORD Length;
+} CSRSS_GET_COMMAND_HISTORY, *PCSRSS_GET_COMMAND_HISTORY;
+
+typedef struct
+{
+  UNICODE_STRING ExeName;
+} CSRSS_EXPUNGE_COMMAND_HISTORY, *PCSRSS_EXPUNGE_COMMAND_HISTORY;
+
+typedef struct
+{
+  UNICODE_STRING ExeName;
+  DWORD NumCommands;
+} CSRSS_SET_HISTORY_NUMBER_COMMANDS, *PCSRSS_SET_HISTORY_NUMBER_COMMANDS;
+
+typedef struct
+{
+  DWORD HistoryBufferSize;
+  DWORD NumberOfHistoryBuffers;
+  DWORD dwFlags;
+} CSRSS_GET_HISTORY_INFO, *PCSRSS_GET_HISTORY_INFO,
+  CSRSS_SET_HISTORY_INFO, *PCSRSS_SET_HISTORY_INFO;
 
 #define CSR_API_MESSAGE_HEADER_SIZE(Type)       (FIELD_OFFSET(CSR_API_MESSAGE, Data) + sizeof(Type))
 #define CSRSS_MAX_WRITE_CONSOLE                 (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE))
@@ -554,6 +585,12 @@ typedef struct
 #define CREATE_THREAD                 (0x3F)
 #define SET_SCREEN_BUFFER_SIZE        (0x40)
 #define GET_CONSOLE_SELECTION_INFO    (0x41)
+#define GET_COMMAND_HISTORY_LENGTH    (0x42)
+#define GET_COMMAND_HISTORY           (0x43)
+#define EXPUNGE_COMMAND_HISTORY       (0x44)
+#define SET_HISTORY_NUMBER_COMMANDS   (0x45)
+#define GET_HISTORY_INFO              (0x46)
+#define SET_HISTORY_INFO              (0x47)
 
 /* Keep in sync with definition below. */
 #define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS))
@@ -629,6 +666,12 @@ typedef struct _CSR_API_MESSAGE
         CSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent;
         CSRSS_SET_SCREEN_BUFFER_SIZE SetScreenBufferSize;
         CSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo;
+        CSRSS_GET_COMMAND_HISTORY_LENGTH GetCommandHistoryLength;
+        CSRSS_GET_COMMAND_HISTORY GetCommandHistory;
+        CSRSS_EXPUNGE_COMMAND_HISTORY ExpungeCommandHistory;
+        CSRSS_SET_HISTORY_NUMBER_COMMANDS SetHistoryNumberCommands;
+        CSRSS_GET_HISTORY_INFO GetHistoryInfo;
+        CSRSS_SET_HISTORY_INFO SetHistoryInfo;
     } Data;
 } CSR_API_MESSAGE, *PCSR_API_MESSAGE;
 
index a945e2e..9595589 100644 (file)
@@ -39,7 +39,7 @@ ConioLineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
     }
     else if (KeyEvent->uChar.UnicodeChar == L'\r')
     {
-        /* TODO: add line to history */
+        HistoryAddEntry(Console);
 
         Console->LineBuffer[Console->LineSize++] = L'\r';
         if (Console->Mode & ENABLE_ECHO_INPUT)
index 3ff3a19..5a60c21 100644 (file)
@@ -80,6 +80,10 @@ typedef struct tagCSRSS_CONSOLE
   WORD LineSize;                        /* current size of line */
   WORD LinePos;                         /* current position within line */
   BOOLEAN LineComplete;                 /* user pressed enter, ready to send back to client */
+  LIST_ENTRY HistoryBuffers;
+  WORD HistoryBufferSize;               /* size for newly created history buffers */
+  WORD NumberOfHistoryBuffers;          /* maximum number of history buffers allowed */
+  BOOLEAN HistoryNoDup;                 /* remove old duplicate history entries */
   LIST_ENTRY BufferList;                /* List of all screen buffers for this console */
   PCSRSS_SCREEN_BUFFER ActiveBuffer;    /* Pointer to currently active screen buffer */
   WORD Mode;                            /* Console mode flags */
@@ -110,6 +114,8 @@ typedef struct ConsoleInput_t
 #define CONSOLE_SELECTION_NOT_EMPTY   0x2
 #define CONSOLE_MOUSE_SELECTION       0x4
 #define CONSOLE_MOUSE_DOWN            0x8
+/* HistoryFlags values */
+#define HISTORY_NO_DUP_FLAG           0x1
 
 /* PauseFlags values (internal only) */
 #define PAUSED_FROM_KEYBOARD  0x1
@@ -214,4 +220,15 @@ CSR_API(CsrGetAllConsoleAliasesLength);
 CSR_API(CsrGetConsoleAliasesExes);
 CSR_API(CsrGetConsoleAliasesExesLength);
 
+/* history.c */
+struct tagHISTORY_BUFFER;
+VOID FASTCALL HistoryAddEntry(PCSRSS_CONSOLE Console);
+VOID FASTCALL HistoryDeleteBuffer(struct tagHISTORY_BUFFER *Hist);
+CSR_API(CsrGetCommandHistoryLength);
+CSR_API(CsrGetCommandHistory);
+CSR_API(CsrExpungeCommandHistory);
+CSR_API(CsrSetHistoryNumberCommands);
+CSR_API(CsrGetHistoryInfo);
+CSR_API(CsrSetHistoryInfo);
+
 /* EOF */
index 5ace9ab..6db2a2e 100644 (file)
@@ -88,6 +88,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console, BOOL Visible)
     InitializeListHead(&Console->BufferList);
     Console->ActiveBuffer = NULL;
     InitializeListHead(&Console->InputEvents);
+    InitializeListHead(&Console->HistoryBuffers);
     Console->CodePage = GetOEMCP();
     Console->OutputCodePage = GetOEMCP();
 
@@ -332,6 +333,9 @@ ConioDeleteConsole(Object_t *Object)
     ConioCleanupConsole(Console);
     if (Console->LineBuffer)
         RtlFreeHeap(Win32CsrApiHeap, 0, Console->LineBuffer);
+    while (!IsListEmpty(&Console->HistoryBuffers))
+        HistoryDeleteBuffer((struct tagHISTORY_BUFFER *)Console->HistoryBuffers.Flink);
+
     ConioDeleteScreenBuffer(Console->ActiveBuffer);
     if (!IsListEmpty(&Console->BufferList))
     {
index 009303e..0817883 100644 (file)
@@ -81,6 +81,12 @@ static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] =
     CSRSS_DEFINE_API(GENERATE_CTRL_EVENT,          CsrGenerateCtrlEvent),
     CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE,       CsrSetScreenBufferSize),
     CSRSS_DEFINE_API(GET_CONSOLE_SELECTION_INFO,   CsrGetConsoleSelectionInfo),
+    CSRSS_DEFINE_API(GET_COMMAND_HISTORY_LENGTH,   CsrGetCommandHistoryLength),
+    CSRSS_DEFINE_API(GET_COMMAND_HISTORY,          CsrGetCommandHistory),
+    CSRSS_DEFINE_API(EXPUNGE_COMMAND_HISTORY,      CsrExpungeCommandHistory),
+    CSRSS_DEFINE_API(SET_HISTORY_NUMBER_COMMANDS,  CsrSetHistoryNumberCommands),
+    CSRSS_DEFINE_API(GET_HISTORY_INFO,             CsrGetHistoryInfo),
+    CSRSS_DEFINE_API(SET_HISTORY_INFO,             CsrSetHistoryInfo),
     { 0, 0, NULL }
 };
 
index e274872..d46d9cb 100644 (file)
@@ -30,12 +30,9 @@ typedef struct GUI_CONSOLE_DATA_TAG
     WCHAR FontName[LF_FACESIZE];
     DWORD FontSize;
     DWORD FontWeight;
-    DWORD HistoryNoDup;
     DWORD FullScreen;
     DWORD QuickEdit;
     DWORD InsertMode;
-    DWORD NumberOfHistoryBuffers;
-    DWORD HistoryBufferSize;
     DWORD WindowPosition;
     DWORD UseRasterFonts;
     COLORREF ScreenText;
@@ -413,22 +410,24 @@ GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData)
         RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD));
     }
 
-    if (GuiData->NumberOfHistoryBuffers == 5)
+    if (Console->NumberOfHistoryBuffers == 5)
     {
         RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers");
     }
     else
     {
-        RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD));
+        DWORD Temp = Console->NumberOfHistoryBuffers;
+        RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD));
     }
 
-    if (GuiData->HistoryBufferSize == 50)
+    if (Console->HistoryBufferSize == 50)
     {
         RegDeleteKeyW(hKey, L"HistoryBufferSize");
     }
     else
     {
-        RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD));
+        DWORD Temp = Console->HistoryBufferSize;
+        RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD));
     }
 
     if (GuiData->FullScreen == FALSE)
@@ -458,13 +457,14 @@ GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData)
         RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD));
     }
 
-    if (GuiData->HistoryNoDup == FALSE)
+    if (Console->HistoryNoDup == FALSE)
     {
         RegDeleteKeyW(hKey, L"HistoryNoDup");
     }
     else
     {
-        RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD));
+        DWORD Temp = Console->HistoryNoDup;
+        RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD));
     }
 
     if (GuiData->ScreenText == RGB(192, 192, 192))
@@ -564,7 +564,7 @@ GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA
         }
         else if (!wcscmp(szValueName, L"HistoryNoDup"))
         {
-            GuiData->HistoryNoDup = Value;
+            Console->HistoryNoDup = Value;
         }
         else if (!wcscmp(szValueName, L"WindowSize"))
         {
@@ -603,12 +603,9 @@ GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_
     wcscpy(GuiData->FontName, L"DejaVu Sans Mono");
     GuiData->FontSize = 0x0008000C; // font is 8x12
     GuiData->FontWeight = FW_NORMAL;
-    GuiData->HistoryNoDup = FALSE;
     GuiData->FullScreen = FALSE;
     GuiData->QuickEdit = FALSE;
     GuiData->InsertMode = TRUE;
-    GuiData->HistoryBufferSize = 50;
-    GuiData->NumberOfHistoryBuffers = 5;
     GuiData->ScreenText = RGB(192, 192, 192);
     GuiData->ScreenBackground = RGB(0, 0, 0);
     GuiData->PopupText = RGB(128, 0, 128);
@@ -617,6 +614,9 @@ GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_
     GuiData->UseRasterFonts = TRUE;
     memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors));
 
+    Console->HistoryBufferSize = 50;
+    Console->NumberOfHistoryBuffers = 5;
+    Console->HistoryNoDup = FALSE;
     Console->Size.X = 80;
     Console->Size.Y = 25;
 
@@ -1437,8 +1437,8 @@ GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiD
 
     /* setup struct */
     SharedInfo.InsertMode = GuiData->InsertMode;
-    SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize;
-    SharedInfo.NumberOfHistoryBuffers = GuiData->NumberOfHistoryBuffers;
+    SharedInfo.HistoryBufferSize = Console->HistoryBufferSize;
+    SharedInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
     SharedInfo.ScreenText = GuiData->ScreenText;
     SharedInfo.ScreenBackground = GuiData->ScreenBackground;
     SharedInfo.PopupText = GuiData->PopupText;
@@ -1450,7 +1450,7 @@ GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiD
     SharedInfo.FontSize = (DWORD)GuiData->FontSize;
     SharedInfo.FontWeight = GuiData->FontWeight;
     SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
-    SharedInfo.HistoryNoDup = GuiData->HistoryNoDup;
+    SharedInfo.HistoryNoDup = Console->HistoryNoDup;
     SharedInfo.FullScreen = GuiData->FullScreen;
     SharedInfo.QuickEdit = GuiData->QuickEdit;
     memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors));
index 728bd6a..3cf0931 100644 (file)
@@ -26,6 +26,7 @@
        <file>guiconsole.c</file>
        <file>handle.c</file>
        <file>harderror.c</file>
+    <file>history.c</file>
        <file>tuiconsole.c</file>
        <file>appswitch.c</file>
        <file>win32csr.rc</file>