1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS system libraries
4  * FILE:            dll/win32/kernel32/client/console/history.c
5  * PURPOSE:         Win32 Console Client history functions
6  * PROGRAMMERS:     Jeffrey Morlan
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <k32.h>
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 
17 /* PRIVATE FUNCTIONS **********************************************************/
18 
19 #if 0
20 /* Get the size needed to copy a string to a capture buffer, including alignment */
21 static ULONG
22 IntStringSize(LPCVOID String,
23               BOOL Unicode)
24 {
25     ULONG Size = (Unicode ? wcslen(String) : strlen(String)) * sizeof(WCHAR);
26     return (Size + 3) & ~3;
27 }
28 #endif
29 
30 static VOID
31 IntExpungeConsoleCommandHistory(LPCVOID lpExeName, BOOLEAN bUnicode)
32 {
33     CONSOLE_API_MESSAGE ApiMessage;
34     PCONSOLE_EXPUNGECOMMANDHISTORY ExpungeCommandHistoryRequest = &ApiMessage.Data.ExpungeCommandHistoryRequest;
35     PCSR_CAPTURE_BUFFER CaptureBuffer;
36 
37     USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
38 
39     if (lpExeName == NULL || NumChars == 0)
40     {
41         SetLastError(ERROR_INVALID_PARAMETER);
42         return;
43     }
44 
45     ExpungeCommandHistoryRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
46     ExpungeCommandHistoryRequest->ExeLength     = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
47     ExpungeCommandHistoryRequest->Unicode  =
48     ExpungeCommandHistoryRequest->Unicode2 = bUnicode;
49 
50     // CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
51     CaptureBuffer = CsrAllocateCaptureBuffer(1, ExpungeCommandHistoryRequest->ExeLength);
52     if (!CaptureBuffer)
53     {
54         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
55         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
56         return;
57     }
58 
59     CsrCaptureMessageBuffer(CaptureBuffer,
60                             (PVOID)lpExeName,
61                             ExpungeCommandHistoryRequest->ExeLength,
62                             (PVOID)&ExpungeCommandHistoryRequest->ExeName);
63 
64     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
65                         CaptureBuffer,
66                         CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepExpungeCommandHistory),
67                         sizeof(*ExpungeCommandHistoryRequest));
68 
69     CsrFreeCaptureBuffer(CaptureBuffer);
70 
71     if (!NT_SUCCESS(ApiMessage.Status))
72         BaseSetLastNTError(ApiMessage.Status);
73 }
74 
75 
76 static DWORD
77 IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName, BOOLEAN bUnicode)
78 {
79     CONSOLE_API_MESSAGE ApiMessage;
80     PCONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest = &ApiMessage.Data.GetCommandHistoryRequest;
81     PCSR_CAPTURE_BUFFER CaptureBuffer;
82 
83     USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
84 
85     if (lpExeName == NULL || NumChars == 0)
86     {
87         SetLastError(ERROR_INVALID_PARAMETER);
88         return 0;
89     }
90 
91     GetCommandHistoryRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
92     GetCommandHistoryRequest->HistoryLength = cbHistory;
93     GetCommandHistoryRequest->ExeLength     = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
94     GetCommandHistoryRequest->Unicode  =
95     GetCommandHistoryRequest->Unicode2 = bUnicode;
96 
97     // CaptureBuffer = CsrAllocateCaptureBuffer(2, IntStringSize(lpExeName, bUnicode) +
98     //                                             HistoryLength);
99     CaptureBuffer = CsrAllocateCaptureBuffer(2, GetCommandHistoryRequest->ExeLength +
100                                                 GetCommandHistoryRequest->HistoryLength);
101     if (!CaptureBuffer)
102     {
103         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
104         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
105         return 0;
106     }
107 
108     CsrCaptureMessageBuffer(CaptureBuffer,
109                             (PVOID)lpExeName,
110                             GetCommandHistoryRequest->ExeLength,
111                             (PVOID)&GetCommandHistoryRequest->ExeName);
112 
113     CsrAllocateMessagePointer(CaptureBuffer, GetCommandHistoryRequest->HistoryLength,
114                               (PVOID*)&GetCommandHistoryRequest->History);
115 
116     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
117                         CaptureBuffer,
118                         CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCommandHistory),
119                         sizeof(*GetCommandHistoryRequest));
120     if (!NT_SUCCESS(ApiMessage.Status))
121     {
122         CsrFreeCaptureBuffer(CaptureBuffer);
123         BaseSetLastNTError(ApiMessage.Status);
124         return 0;
125     }
126 
127     RtlCopyMemory(lpHistory,
128                   GetCommandHistoryRequest->History,
129                   GetCommandHistoryRequest->HistoryLength);
130 
131     CsrFreeCaptureBuffer(CaptureBuffer);
132 
133     return GetCommandHistoryRequest->HistoryLength;
134 }
135 
136 
137 static DWORD
138 IntGetConsoleCommandHistoryLength(LPCVOID lpExeName, BOOL bUnicode)
139 {
140     CONSOLE_API_MESSAGE ApiMessage;
141     PCONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest = &ApiMessage.Data.GetCommandHistoryLengthRequest;
142     PCSR_CAPTURE_BUFFER CaptureBuffer;
143 
144     USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
145 
146     if (lpExeName == NULL || NumChars == 0)
147     {
148         SetLastError(ERROR_INVALID_PARAMETER);
149         return 0;
150     }
151 
152     GetCommandHistoryLengthRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
153     GetCommandHistoryLengthRequest->ExeLength     = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
154     GetCommandHistoryLengthRequest->Unicode  =
155     GetCommandHistoryLengthRequest->Unicode2 = bUnicode;
156 
157     // CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
158     CaptureBuffer = CsrAllocateCaptureBuffer(1, GetCommandHistoryLengthRequest->ExeLength);
159     if (!CaptureBuffer)
160     {
161         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
162         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
163         return 0;
164     }
165 
166     CsrCaptureMessageBuffer(CaptureBuffer,
167                             (PVOID)lpExeName,
168                             GetCommandHistoryLengthRequest->ExeLength,
169                             (PVOID)&GetCommandHistoryLengthRequest->ExeName);
170 
171     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
172                         CaptureBuffer,
173                         CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCommandHistoryLength),
174                         sizeof(*GetCommandHistoryLengthRequest));
175 
176     CsrFreeCaptureBuffer(CaptureBuffer);
177 
178     if (!NT_SUCCESS(ApiMessage.Status))
179     {
180         BaseSetLastNTError(ApiMessage.Status);
181         return 0;
182     }
183 
184     return GetCommandHistoryLengthRequest->HistoryLength;
185 }
186 
187 
188 static BOOL
189 IntSetConsoleNumberOfCommands(DWORD dwNumCommands,
190                               LPCVOID lpExeName,
191                               BOOLEAN bUnicode)
192 {
193     CONSOLE_API_MESSAGE ApiMessage;
194     PCONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest = &ApiMessage.Data.SetHistoryNumberCommandsRequest;
195     PCSR_CAPTURE_BUFFER CaptureBuffer;
196 
197     USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
198 
199     if (lpExeName == NULL || NumChars == 0)
200     {
201         SetLastError(ERROR_INVALID_PARAMETER);
202         return FALSE;
203     }
204 
205     SetHistoryNumberCommandsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
206     SetHistoryNumberCommandsRequest->NumCommands   = dwNumCommands;
207     SetHistoryNumberCommandsRequest->ExeLength     = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
208     SetHistoryNumberCommandsRequest->Unicode  =
209     SetHistoryNumberCommandsRequest->Unicode2 = bUnicode;
210 
211     // CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
212     CaptureBuffer = CsrAllocateCaptureBuffer(1, SetHistoryNumberCommandsRequest->ExeLength);
213     if (!CaptureBuffer)
214     {
215         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
216         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
217         return FALSE;
218     }
219 
220     CsrCaptureMessageBuffer(CaptureBuffer,
221                             (PVOID)lpExeName,
222                             SetHistoryNumberCommandsRequest->ExeLength,
223                             (PVOID)&SetHistoryNumberCommandsRequest->ExeName);
224 
225     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
226                         CaptureBuffer,
227                         CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetNumberOfCommands),
228                         sizeof(*SetHistoryNumberCommandsRequest));
229 
230     CsrFreeCaptureBuffer(CaptureBuffer);
231 
232     if (!NT_SUCCESS(ApiMessage.Status))
233     {
234         BaseSetLastNTError(ApiMessage.Status);
235         return FALSE;
236     }
237 
238     return TRUE;
239 }
240 
241 
242 /* FUNCTIONS ******************************************************************/
243 
244 /*
245  * @implemented (Undocumented)
246  */
247 VOID
248 WINAPI
249 DECLSPEC_HOTPATCH
250 ExpungeConsoleCommandHistoryW(IN LPCWSTR lpExeName)
251 {
252     IntExpungeConsoleCommandHistory(lpExeName, TRUE);
253 }
254 
255 
256 /*
257  * @implemented (Undocumented)
258  */
259 VOID
260 WINAPI
261 DECLSPEC_HOTPATCH
262 ExpungeConsoleCommandHistoryA(IN LPCSTR lpExeName)
263 {
264     IntExpungeConsoleCommandHistory(lpExeName, FALSE);
265 }
266 
267 
268 /*
269  * @implemented (Undocumented)
270  */
271 DWORD
272 WINAPI
273 DECLSPEC_HOTPATCH
274 GetConsoleCommandHistoryW(OUT LPWSTR lpHistory,
275                           IN DWORD cbHistory,
276                           IN LPCWSTR lpExeName)
277 {
278     return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, TRUE);
279 }
280 
281 
282 /*
283  * @implemented (Undocumented)
284  */
285 DWORD
286 WINAPI
287 DECLSPEC_HOTPATCH
288 GetConsoleCommandHistoryA(OUT LPSTR lpHistory,
289                           IN DWORD cbHistory,
290                           IN LPCSTR lpExeName)
291 {
292     return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, FALSE);
293 }
294 
295 
296 /*
297  * @implemented (Undocumented)
298  */
299 DWORD
300 WINAPI
301 DECLSPEC_HOTPATCH
302 GetConsoleCommandHistoryLengthW(IN LPCWSTR lpExeName)
303 {
304     return IntGetConsoleCommandHistoryLength(lpExeName, TRUE);
305 }
306 
307 
308 /*
309  * @implemented (Undocumented)
310  */
311 DWORD
312 WINAPI
313 DECLSPEC_HOTPATCH
314 GetConsoleCommandHistoryLengthA(IN LPCSTR lpExeName)
315 {
316     return IntGetConsoleCommandHistoryLength(lpExeName, FALSE);
317 }
318 
319 
320 /*
321  * @implemented (Undocumented)
322  */
323 BOOL
324 WINAPI
325 DECLSPEC_HOTPATCH
326 SetConsoleNumberOfCommandsW(IN DWORD dwNumCommands,
327                             IN LPCWSTR lpExeName)
328 {
329     return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, TRUE);
330 }
331 
332 
333 /*
334  * @implemented (Undocumented)
335  */
336 BOOL
337 WINAPI
338 DECLSPEC_HOTPATCH
339 SetConsoleNumberOfCommandsA(IN DWORD dwNumCommands,
340                             IN LPCSTR lpExeName)
341 {
342     return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, FALSE);
343 }
344 
345 
346 /*
347  * @implemented
348  */
349 BOOL
350 WINAPI
351 DECLSPEC_HOTPATCH
352 SetConsoleCommandHistoryMode(IN DWORD dwMode)
353 {
354     CONSOLE_API_MESSAGE ApiMessage;
355     PCONSOLE_SETHISTORYMODE SetHistoryModeRequest = &ApiMessage.Data.SetHistoryModeRequest;
356 
357     SetHistoryModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
358     SetHistoryModeRequest->Mode          = dwMode;
359 
360     CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
361                         NULL,
362                         CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCommandHistoryMode),
363                         sizeof(*SetHistoryModeRequest));
364     if (!NT_SUCCESS(ApiMessage.Status))
365     {
366         BaseSetLastNTError(ApiMessage.Status);
367         return FALSE;
368     }
369 
370     return TRUE;
371 }
372 
373 /* EOF */
374