ReactOS  0.4.14-dev-49-gfb4591c
lineinput.c
Go to the documentation of this file.
1 /*
2  * LICENSE: GPL - See COPYING in the top level directory
3  * PROJECT: ReactOS Console Server DLL
4  * FILE: win32ss/user/winsrv/consrv_new/lineinput.c
5  * PURPOSE: Console line input functions
6  * PROGRAMMERS: Jeffrey Morlan
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "consrv.h"
12 #include "console.h"
13 #include "include/conio.h"
14 #include "include/conio2.h"
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 typedef struct _HISTORY_BUFFER
20 {
28 
29 
30 /* PRIVATE FUNCTIONS **********************************************************/
31 
32 static PHISTORY_BUFFER
34 {
35  /* TODO: use actual EXE name sent from process that called ReadConsole */
36  UNICODE_STRING ExeName = { 14, 14, L"cmd.exe" };
37  PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
38  PHISTORY_BUFFER Hist;
39 
40  for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink)
41  {
42  Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
43  if (RtlEqualUnicodeString(&ExeName, &Hist->ExeName, FALSE))
44  return Hist;
45  }
46 
47  /* Couldn't find the buffer, create a new one */
48  Hist = ConsoleAllocHeap(0, sizeof(HISTORY_BUFFER) + ExeName.Length);
49  if (!Hist) return NULL;
50  Hist->MaxEntries = Console->HistoryBufferSize;
51  Hist->NumEntries = 0;
52  Hist->Entries = ConsoleAllocHeap(0, Hist->MaxEntries * sizeof(UNICODE_STRING));
53  if (!Hist->Entries)
54  {
55  ConsoleFreeHeap(Hist);
56  return NULL;
57  }
58  Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName.Length;
59  Hist->ExeName.Buffer = (PWCHAR)(Hist + 1);
60  memcpy(Hist->ExeName.Buffer, ExeName.Buffer, ExeName.Length);
61  InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry);
62  return Hist;
63 }
64 
65 static VOID
67 {
68  UNICODE_STRING NewEntry;
70  INT i;
71 
72  if (!Hist) return;
73 
74  NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR);
75  NewEntry.Buffer = Console->LineBuffer;
76 
77  /* Don't add blank or duplicate entries */
78  if (NewEntry.Length == 0 || Hist->MaxEntries == 0 ||
79  (Hist->NumEntries > 0 &&
80  RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1], &NewEntry, FALSE)))
81  {
82  return;
83  }
84 
85  if (Console->HistoryNoDup)
86  {
87  /* Check if this line has been entered before */
88  for (i = Hist->NumEntries - 1; i >= 0; i--)
89  {
90  if (RtlEqualUnicodeString(&Hist->Entries[i], &NewEntry, FALSE))
91  {
92  /* Just rotate the list to bring this entry to the end */
93  NewEntry = Hist->Entries[i];
94  memmove(&Hist->Entries[i], &Hist->Entries[i + 1],
95  (Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING));
96  Hist->Entries[Hist->NumEntries - 1] = NewEntry;
97  Hist->Position = Hist->NumEntries - 1;
98  return;
99  }
100  }
101  }
102 
103  if (Hist->NumEntries == Hist->MaxEntries)
104  {
105  /* List is full, remove oldest entry */
106  RtlFreeUnicodeString(&Hist->Entries[0]);
107  memmove(&Hist->Entries[0], &Hist->Entries[1],
108  --Hist->NumEntries * sizeof(UNICODE_STRING));
109  }
110 
111  if (NT_SUCCESS(RtlDuplicateUnicodeString(0, &NewEntry, &Hist->Entries[Hist->NumEntries])))
112  Hist->NumEntries++;
113  Hist->Position = Hist->NumEntries - 1;
114 }
115 
116 static VOID
118 {
120 
121  if (!Hist || Hist->NumEntries == 0)
122  Entry->Length = 0;
123  else
124  *Entry = Hist->Entries[Hist->Position];
125 }
126 
127 static PHISTORY_BUFFER
129 {
130  PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
131  while (Entry != &Console->HistoryBuffers)
132  {
133  /* For the history APIs, the caller is allowed to give only part of the name */
135  if (RtlPrefixUnicodeString(ExeName, &Hist->ExeName, TRUE))
136  return Hist;
137  Entry = Entry->Flink;
138  }
139  return NULL;
140 }
141 
142 static VOID
144 {
145  if (!Hist) return;
146 
147  while (Hist->NumEntries != 0)
148  RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]);
149 
150  ConsoleFreeHeap(Hist->Entries);
151  RemoveEntryList(&Hist->ListEntry);
152  ConsoleFreeHeap(Hist);
153 }
154 
157 {
158  PLIST_ENTRY CurrentEntry;
159  PHISTORY_BUFFER HistoryBuffer;
160 
161  while (!IsListEmpty(&Console->HistoryBuffers))
162  {
163  CurrentEntry = RemoveHeadList(&Console->HistoryBuffers);
164  HistoryBuffer = CONTAINING_RECORD(CurrentEntry, HISTORY_BUFFER, ListEntry);
165  HistoryDeleteBuffer(HistoryBuffer);
166  }
167 }
168 
169 static VOID
171 {
172  if (Pos != Console->LinePos && Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
173  {
174  PCONSOLE_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
175  SHORT OldCursorX = Buffer->CursorPosition.X;
176  SHORT OldCursorY = Buffer->CursorPosition.Y;
177  INT XY = OldCursorY * Buffer->ScreenBufferSize.X + OldCursorX;
178 
179  XY += (Pos - Console->LinePos);
180  if (XY < 0)
181  XY = 0;
182  else if (XY >= Buffer->ScreenBufferSize.Y * Buffer->ScreenBufferSize.X)
183  XY = Buffer->ScreenBufferSize.Y * Buffer->ScreenBufferSize.X - 1;
184 
185  Buffer->CursorPosition.X = XY % Buffer->ScreenBufferSize.X;
186  Buffer->CursorPosition.Y = XY / Buffer->ScreenBufferSize.X;
187  ConioSetScreenInfo(Console, Buffer, OldCursorX, OldCursorY);
188  }
189 
190  Console->LinePos = Pos;
191 }
192 
193 static VOID
194 LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion)
195 {
196  PTEXTMODE_SCREEN_BUFFER ActiveBuffer;
197  UINT Pos = Console->LinePos;
198  UINT NewSize = Console->LineSize - NumToDelete + NumToInsert;
199  UINT i;
200 
201  if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER) return;
202  ActiveBuffer = (PTEXTMODE_SCREEN_BUFFER)Console->ActiveBuffer;
203 
204  /* Make sure there's always enough room for ending \r\n */
205  if (NewSize + 2 > Console->LineMaxSize)
206  return;
207 
208  memmove(&Console->LineBuffer[Pos + NumToInsert],
209  &Console->LineBuffer[Pos + NumToDelete],
210  (Console->LineSize - (Pos + NumToDelete)) * sizeof(WCHAR));
211  memcpy(&Console->LineBuffer[Pos], Insertion, NumToInsert * sizeof(WCHAR));
212 
213  if (Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
214  {
215  for (i = Pos; i < NewSize; i++)
216  {
217  ConioWriteConsole(Console, ActiveBuffer, &Console->LineBuffer[i], 1, TRUE);
218  }
219  for (; i < Console->LineSize; i++)
220  {
221  ConioWriteConsole(Console, ActiveBuffer, L" ", 1, TRUE);
222  }
223  Console->LinePos = i;
224  }
225 
226  Console->LineSize = NewSize;
227  LineInputSetPos(Console, Pos + NumToInsert);
228 }
229 
230 static VOID
232 {
234  UINT Position = 0;
235 
236  if (!Hist || Hist->NumEntries == 0) return;
237 
238  Position = Hist->Position + Offset;
239  Position = min(max(Position, 0), Hist->NumEntries - 1);
240  Hist->Position = Position;
241 
243  LineInputEdit(Console, Console->LineSize,
244  Hist->Entries[Hist->Position].Length / sizeof(WCHAR),
245  Hist->Entries[Hist->Position].Buffer);
246 }
247 
250 {
251  UINT Pos = Console->LinePos;
252  PHISTORY_BUFFER Hist;
254  INT HistPos;
255 
256  switch (KeyEvent->wVirtualKeyCode)
257  {
258  case VK_ESCAPE:
259  /* Clear entire line */
261  LineInputEdit(Console, Console->LineSize, 0, NULL);
262  return;
263  case VK_HOME:
264  /* Move to start of line. With ctrl, erase everything left of cursor */
268  return;
269  case VK_END:
270  /* Move to end of line. With ctrl, erase everything right of cursor */
272  LineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
273  else
274  LineInputSetPos(Console, Console->LineSize);
275  return;
276  case VK_LEFT:
277  /* Move left. With ctrl, move to beginning of previous word */
279  {
280  while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--;
281  while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--;
282  }
283  else
284  {
285  Pos -= (Pos > 0);
286  }
288  return;
289  case VK_RIGHT:
290  case VK_F1:
291  /* Move right. With ctrl, move to beginning of next word */
293  {
294  while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++;
295  while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++;
297  return;
298  }
299  else
300  {
301  /* Recall one character (but don't overwrite current line) */
303  if (Pos < Console->LineSize)
305  else if (Pos * sizeof(WCHAR) < Entry.Length)
306  LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]);
307  }
308  return;
309  case VK_INSERT:
310  /* Toggle between insert and overstrike */
311  Console->LineInsertToggle = !Console->LineInsertToggle;
312  ConioSetCursorInfo(Console, Console->ActiveBuffer);
313  return;
314  case VK_DELETE:
315  /* Remove character to right of cursor */
316  if (Pos != Console->LineSize)
317  LineInputEdit(Console, 1, 0, NULL);
318  return;
319  case VK_PRIOR:
320  /* Recall first history entry */
322  return;
323  case VK_NEXT:
324  /* Recall last history entry */
326  return;
327  case VK_UP:
328  case VK_F5:
329  /* Recall previous history entry. On first time, actually recall the
330  * current (usually last) entry; on subsequent times go back. */
331  LineInputRecallHistory(Console, Console->LineUpPressed ? -1 : 0);
332  Console->LineUpPressed = TRUE;
333  return;
334  case VK_DOWN:
335  /* Recall next history entry */
337  return;
338  case VK_F3:
339  /* Recall remainder of current history entry */
341  if (Pos * sizeof(WCHAR) < Entry.Length)
342  {
343  UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos);
344  UINT DeleteSize = min(Console->LineSize - Pos, InsertSize);
345  LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]);
346  }
347  return;
348  case VK_F6:
349  /* Insert a ^Z character */
350  KeyEvent->uChar.UnicodeChar = 26;
351  break;
352  case VK_F7:
355  return;
356  case VK_F8:
357  /* Search for history entries starting with input. */
359  if (!Hist || Hist->NumEntries == 0) return;
360 
361  /* Like Up/F5, on first time start from current (usually last) entry,
362  * but on subsequent times start at previous entry. */
363  if (Console->LineUpPressed)
364  Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1;
365  Console->LineUpPressed = TRUE;
366 
367  Entry.Length = Console->LinePos * sizeof(WCHAR);
368  Entry.Buffer = Console->LineBuffer;
369 
370  /* Keep going backwards, even wrapping around to the end,
371  * until we get back to starting point */
372  HistPos = Hist->Position;
373  do
374  {
375  if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE))
376  {
377  Hist->Position = HistPos;
378  LineInputEdit(Console, Console->LineSize - Pos,
379  Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos,
380  &Hist->Entries[HistPos].Buffer[Pos]);
381  /* Cursor stays where it was */
383  return;
384  }
385  if (--HistPos < 0) HistPos += Hist->NumEntries;
386  } while (HistPos != Hist->Position);
387  return;
388  }
389 
390  if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT)
391  {
392  /* backspace handling - if processed input enabled then we handle it here
393  * otherwise we treat it like a normal char. */
394  if (Pos > 0)
395  {
397  LineInputEdit(Console, 1, 0, NULL);
398  }
399  }
400  else if (KeyEvent->uChar.UnicodeChar == L'\r')
401  {
403 
404  /* TODO: Expand aliases */
405 
406  LineInputSetPos(Console, Console->LineSize);
407  Console->LineBuffer[Console->LineSize++] = L'\r';
408  if (Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
409  {
410  if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
411  {
412  ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\r", 1, TRUE);
413  }
414  }
415 
416  /* Add \n if processed input. There should usually be room for it,
417  * but an exception to the rule exists: the buffer could have been
418  * pre-filled with LineMaxSize - 1 characters. */
419  if (Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
420  Console->LineSize < Console->LineMaxSize)
421  {
422  Console->LineBuffer[Console->LineSize++] = L'\n';
423  if (Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
424  {
425  if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
426  {
427  ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\n", 1, TRUE);
428  }
429  }
430  }
431  Console->LineComplete = TRUE;
432  Console->LinePos = 0;
433  }
434  else if (KeyEvent->uChar.UnicodeChar != L'\0')
435  {
436  if (KeyEvent->uChar.UnicodeChar < 0x20 &&
437  Console->LineWakeupMask & (1 << KeyEvent->uChar.UnicodeChar))
438  {
439  /* Control key client wants to handle itself (e.g. for tab completion) */
440  Console->LineBuffer[Console->LineSize++] = L' ';
441  Console->LineBuffer[Console->LinePos] = KeyEvent->uChar.UnicodeChar;
442  Console->LineComplete = TRUE;
443  Console->LinePos = 0;
444  }
445  else
446  {
447  /* Normal character */
448  BOOL Overstrike = Console->LineInsertToggle && Console->LinePos != Console->LineSize;
449  LineInputEdit(Console, Overstrike, 1, &KeyEvent->uChar.UnicodeChar);
450  }
451  }
452 }
453 
454 
455 /* PUBLIC SERVER APIS *********************************************************/
456 
457 CSR_API(SrvGetConsoleCommandHistory)
458 {
459  PCONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryRequest;
463  PHISTORY_BUFFER Hist;
464  PBYTE Buffer = (PBYTE)GetCommandHistoryRequest->History;
465  ULONG BufferSize = GetCommandHistoryRequest->Length;
466  UINT i;
467 
468  if ( !CsrValidateMessageBuffer(ApiMessage,
469  (PVOID*)&GetCommandHistoryRequest->History,
470  GetCommandHistoryRequest->Length,
471  sizeof(BYTE)) ||
472  !CsrValidateMessageBuffer(ApiMessage,
473  (PVOID*)&GetCommandHistoryRequest->ExeName.Buffer,
474  GetCommandHistoryRequest->ExeName.Length,
475  sizeof(BYTE)) )
476  {
478  }
479 
480  Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
481  if (NT_SUCCESS(Status))
482  {
483  Hist = HistoryFindBuffer(Console, &GetCommandHistoryRequest->ExeName);
484  if (Hist)
485  {
486  for (i = 0; i < Hist->NumEntries; i++)
487  {
488  if (BufferSize < (Hist->Entries[i].Length + sizeof(WCHAR)))
489  {
491  break;
492  }
493  memcpy(Buffer, Hist->Entries[i].Buffer, Hist->Entries[i].Length);
494  Buffer += Hist->Entries[i].Length;
495  *(PWCHAR)Buffer = L'\0';
496  Buffer += sizeof(WCHAR);
497  }
498  }
499  GetCommandHistoryRequest->Length = Buffer - (PBYTE)GetCommandHistoryRequest->History;
501  }
502  return Status;
503 }
504 
505 CSR_API(SrvGetConsoleCommandHistoryLength)
506 {
507  PCONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryLengthRequest;
511  PHISTORY_BUFFER Hist;
512  ULONG Length = 0;
513  UINT i;
514 
515  if (!CsrValidateMessageBuffer(ApiMessage,
516  (PVOID*)&GetCommandHistoryLengthRequest->ExeName.Buffer,
517  GetCommandHistoryLengthRequest->ExeName.Length,
518  sizeof(BYTE)))
519  {
521  }
522 
523  Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
524  if (NT_SUCCESS(Status))
525  {
526  Hist = HistoryFindBuffer(Console, &GetCommandHistoryLengthRequest->ExeName);
527  if (Hist)
528  {
529  for (i = 0; i < Hist->NumEntries; i++)
530  Length += Hist->Entries[i].Length + sizeof(WCHAR);
531  }
532  GetCommandHistoryLengthRequest->Length = Length;
534  }
535  return Status;
536 }
537 
538 CSR_API(SrvExpungeConsoleCommandHistory)
539 {
540  PCONSOLE_EXPUNGECOMMANDHISTORY ExpungeCommandHistoryRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ExpungeCommandHistoryRequest;
543  PHISTORY_BUFFER Hist;
545 
546  if (!CsrValidateMessageBuffer(ApiMessage,
547  (PVOID*)&ExpungeCommandHistoryRequest->ExeName.Buffer,
548  ExpungeCommandHistoryRequest->ExeName.Length,
549  sizeof(BYTE)))
550  {
552  }
553 
554  Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
555  if (NT_SUCCESS(Status))
556  {
557  Hist = HistoryFindBuffer(Console, &ExpungeCommandHistoryRequest->ExeName);
558  HistoryDeleteBuffer(Hist);
560  }
561  return Status;
562 }
563 
564 CSR_API(SrvSetConsoleNumberOfCommands)
565 {
566  PCONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryNumberCommandsRequest;
569  PHISTORY_BUFFER Hist;
571  UINT MaxEntries = SetHistoryNumberCommandsRequest->NumCommands;
572  PUNICODE_STRING OldEntryList, NewEntryList;
573 
574  if (!CsrValidateMessageBuffer(ApiMessage,
575  (PVOID*)&SetHistoryNumberCommandsRequest->ExeName.Buffer,
576  SetHistoryNumberCommandsRequest->ExeName.Length,
577  sizeof(BYTE)))
578  {
580  }
581 
582  Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
583  if (NT_SUCCESS(Status))
584  {
585  Hist = HistoryFindBuffer(Console, &SetHistoryNumberCommandsRequest->ExeName);
586  if (Hist)
587  {
588  OldEntryList = Hist->Entries;
589  NewEntryList = ConsoleAllocHeap(0, MaxEntries * sizeof(UNICODE_STRING));
590  if (!NewEntryList)
591  {
593  }
594  else
595  {
596  /* If necessary, shrink by removing oldest entries */
597  for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--)
598  {
599  RtlFreeUnicodeString(Hist->Entries++);
600  Hist->Position += (Hist->Position == 0);
601  }
602 
603  Hist->MaxEntries = MaxEntries;
604  Hist->Entries = memcpy(NewEntryList, Hist->Entries,
605  Hist->NumEntries * sizeof(UNICODE_STRING));
606  ConsoleFreeHeap(OldEntryList);
607  }
608  }
610  }
611  return Status;
612 }
613 
614 CSR_API(SrvGetConsoleHistory)
615 {
616  PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
619  if (NT_SUCCESS(Status))
620  {
621  HistoryInfoRequest->HistoryBufferSize = Console->HistoryBufferSize;
622  HistoryInfoRequest->NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
623  HistoryInfoRequest->dwFlags = Console->HistoryNoDup;
625  }
626  return Status;
627 }
628 
629 CSR_API(SrvSetConsoleHistory)
630 {
631  PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
634  if (NT_SUCCESS(Status))
635  {
636  Console->HistoryBufferSize = HistoryInfoRequest->HistoryBufferSize;
637  Console->NumberOfHistoryBuffers = HistoryInfoRequest->NumberOfHistoryBuffers;
638  Console->HistoryNoDup = HistoryInfoRequest->dwFlags & HISTORY_NO_DUP_FLAG;
640  }
641  return Status;
642 }
643 
644 /* EOF */
static VOID LineInputRecallHistory(PCONSOLE Console, INT Offset)
Definition: lineinput.c:231
NTSTATUS ConSrvGetConsole(IN PCONSOLE_PROCESS_DATA ProcessData, OUT PCONSRV_CONSOLE *Console, IN BOOLEAN LockConsole)
Definition: console.c:271
#define CsrGetClientThread()
Definition: csrsrv.h:77
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
WCHAR UnicodeChar
Definition: wincon.h:230
static PHISTORY_BUFFER HistoryCurrentBuffer(PCONSOLE Console)
Definition: lineinput.c:33
struct _HISTORY_BUFFER HISTORY_BUFFER
#define VK_F5
Definition: winuser.h:2234
UNICODE_STRING ExeName
Definition: history.c:23
#define VK_F6
Definition: winuser.h:2235
struct _Entry Entry
Definition: kefuncs.h:640
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
static VOID LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion)
Definition: lineinput.c:194
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
ULONG NumEntries
Definition: history.c:22
static COORD Position
Definition: mouse.c:34
struct _CONSOLE_API_MESSAGE * PCONSOLE_API_MESSAGE
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1315
ush Pos
Definition: deflate.h:92
#define ConsoleAllocHeap(Flags, Size)
Definition: heap.h:14
DWORD dwControlKeyState
Definition: wincon.h:233
#define VK_LEFT
Definition: winuser.h:2199
#define VK_DOWN
Definition: winuser.h:2202
#define VK_INSERT
Definition: winuser.h:2207
#define VK_PRIOR
Definition: winuser.h:2195
uint16_t * PWCHAR
Definition: typedefs.h:54
#define TEXTMODE_BUFFER
Definition: pccons.c:21
#define VK_ESCAPE
Definition: winuser.h:2189
VOID LineInputKeyDown(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, KEY_EVENT_RECORD *KeyEvent)
Definition: lineinput.c:166
#define FASTCALL
Definition: nt_native.h:50
VOID ConSrvReleaseConsole(IN PCONSRV_CONSOLE Console, IN BOOLEAN IsConsoleLocked)
Definition: console.c:296
int32_t INT
Definition: typedefs.h:56
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define VK_NEXT
Definition: winuser.h:2196
WORD wVirtualKeyCode
Definition: wincon.h:227
static NTSTATUS ConioWriteConsole(PFRONTEND FrontEnd, PTEXTMODE_SCREEN_BUFFER Buff, PWCHAR Buffer, DWORD Length, BOOL Attrib)
Definition: terminal.c:495
#define ENABLE_ECHO_INPUT
Definition: wincon.h:77
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
ULONG MaxEntries
Definition: history.c:21
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define VK_HOME
Definition: winuser.h:2198
#define VK_UP
Definition: winuser.h:2200
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
short SHORT
Definition: pedump.c:59
#define ConioSetCursorInfo(Console, Buff)
Definition: conio2.h:18
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
LIST_ENTRY ListEntry
Definition: history.c:19
Definition: bufpool.h:45
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define VK_DELETE
Definition: winuser.h:2208
#define LEFT_ALT_PRESSED
Definition: wincon.h:132
VOID HistoryGetCurrentEntry(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Entry)
Definition: history.c:197
union _KEY_EVENT_RECORD::@3153 uChar
PUNICODE_STRING Entries
Definition: history.c:24
#define VK_F7
Definition: winuser.h:2236
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ConsoleGetPerProcessData(Process)
Definition: consrv.h:37
#define BufferSize
Definition: classpnp.h:419
unsigned short WORD
Definition: ntddk_ex.h:93
ULONG Position
Definition: history.c:20
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define VK_F3
Definition: winuser.h:2232
#define VK_F8
Definition: winuser.h:2237
#define LEFT_CTRL_PRESSED
Definition: wincon.h:134
INT GetType(BOOL bLocal, LPOSVERSIONINFOEX osvi, LPSERVER_INFO_102 pBuf102)
Definition: gettype.c:129
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
static const WCHAR L[]
Definition: oid.c:1250
VOID HistoryAddEntry(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Entry)
Definition: history.c:141
CSR_API(SrvGetConsoleCommandHistory)
Definition: lineinput.c:457
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
Definition: typedefs.h:117
Status
Definition: gdiplustypes.h:24
#define VK_RIGHT
Definition: winuser.h:2201
static VOID LineInputSetPos(PCONSOLE Console, UINT Pos)
Definition: lineinput.c:170
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:75
#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY)
Definition: conio2.h:20
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
struct _HISTORY_BUFFER * PHISTORY_BUFFER
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define VK_F1
Definition: winuser.h:2230
CConsole Console
#define ConsoleFreeHeap(HeapBase)
Definition: heap.h:15
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
VOID FASTCALL HistoryDeleteBuffers(PCONSOLE Console)
Definition: lineinput.c:156
unsigned int ULONG
Definition: retypes.h:1
static VOID HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
Definition: lineinput.c:143
#define RIGHT_CTRL_PRESSED
Definition: wincon.h:133
static PHISTORY_BUFFER HistoryFindBuffer(PCONSOLE Console, PUNICODE_STRING ExeName)
Definition: lineinput.c:128
struct _TEXTMODE_SCREEN_BUFFER * PTEXTMODE_SCREEN_BUFFER
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
BYTE * PBYTE
Definition: pedump.c:66
#define VK_END
Definition: winuser.h:2197
base of all file and directory entries
Definition: entries.h:82
#define RIGHT_ALT_PRESSED
Definition: wincon.h:131