00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
#include "precomp.h"
00059
#pragma hdrstop
00060
00061 #define COPY_TO_CHAR_PROMPT_LENGTH 26
00062 #define COPY_FROM_CHAR_PROMPT_LENGTH 28
00063
00064 #define COMMAND_NUMBER_PROMPT_LENGTH 22
00065 #define COMMAND_NUMBER_LENGTH 5
00066 #define MINIMUM_COMMAND_PROMPT_SIZE COMMAND_NUMBER_LENGTH
00067
00068
#if defined(FE_SB)
00069
#define CHAR_COUNT(cch) cch
00070
#else
00071 #define CHAR_COUNT(cch) ((cch)/sizeof(WCHAR))
00072
#endif
00073
00074
00075 #define ALT_PRESSED (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)
00076 #define CTRL_PRESSED (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)
00077
00078 #define CTRL_BUT_NOT_ALT(n) \
00079
(((n) & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && \
00080
!((n) & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))
00081
00082
00083
00084
00085
00086 ExtKeyDefTable
gaKeyDef;
00087
00088 CONST ExtKeyDefTable
gaDefaultKeyDef = {
00089 {
00090 0, VK_HOME, 0,
00091 LEFT_CTRL_PRESSED, VK_HOME, 0,
00092 0, 0, 0,
00093 },
00094 {
00095 0, VK_LEFT, 0,
00096 LEFT_CTRL_PRESSED, VK_LEFT, 0,
00097 },
00098 {
00099 0,
00100 },
00101 {
00102 0, VK_DELETE, 0,
00103 LEFT_CTRL_PRESSED, VK_DELETE, 0,
00104 0, 0, 0,
00105 },
00106 {
00107 0, VK_END, 0,
00108 LEFT_CTRL_PRESSED, VK_END, 0,
00109 0, 0, 0,
00110 },
00111 {
00112 0, VK_RIGHT, 0,
00113 LEFT_CTRL_PRESSED, VK_RIGHT, 0,
00114 0, 0, 0,
00115 },
00116 {
00117 0,
00118 },
00119 {
00120 0,
00121 },
00122 {
00123 0,
00124 },
00125 {
00126 0,
00127 },
00128 {
00129 LEFT_CTRL_PRESSED, VK_END, 0,
00130 },
00131 {
00132 0,
00133 },
00134 {
00135 0,
00136 },
00137 {
00138 0, VK_DOWN, 0,
00139 },
00140 {
00141 0,
00142 },
00143 {
00144 0, VK_UP, 0,
00145 },
00146 {
00147 0,
00148 },
00149 {
00150 0, VK_F8, 0,
00151 },
00152 {
00153 0, VK_PAUSE, 0,
00154 },
00155 {
00156 LEFT_CTRL_PRESSED, VK_DELETE, 0,
00157 },
00158 {
00159 0, VK_ESCAPE, 0,
00160 },
00161 {
00162 0,
00163 },
00164 {
00165 LEFT_CTRL_PRESSED, VK_BACK, EXTKEY_ERASE_PREV_WORD,
00166 },
00167 {
00168 0,
00169 },
00170 {
00171 0,
00172 },
00173 {
00174 0,
00175 },
00176 };
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 VOID InitExtendedEditKeys(CONST ExtKeyDefBuf* pKeyDefBuf)
00187 {
00188 CONST
BYTE* lpbyte;
00189
int i;
00190
DWORD dwCheckSum;
00191
00192
00193
00194
00195
00196
00197
if (pKeyDefBuf ==
NULL || pKeyDefBuf->dwVersion != 0) {
00198
#if DBG
00199
if (pKeyDefBuf !=
NULL) {
00200
DbgPrint(
"InitExtendedEditKeys: Unsupported version number(%d)\n", pKeyDefBuf->dwVersion);
00201 }
00202
#endif
00203
retry_clean:
00204 memcpy(
gaKeyDef,
gaDefaultKeyDef,
sizeof gaKeyDef);
00205
return;
00206 }
00207
00208
00209
00210
00211 dwCheckSum = 0;
00212
for (lpbyte = (CONST
BYTE*)pKeyDefBuf, i = FIELD_OFFSET(ExtKeyDefBuf, table); i <
sizeof *pKeyDefBuf; ++i) {
00213 dwCheckSum += lpbyte[i];
00214 }
00215
if (dwCheckSum != pKeyDefBuf->dwCheckSum) {
00216
#if DBG
00217
DbgPrint(
"InitExtendedEditKeys: Checksum(%d) does not match.\n", pKeyDefBuf->dwCheckSum);
00218
#endif
00219
goto retry_clean;
00220 }
00221
00222
00223
00224
00225
00226 memcpy(
gaKeyDef, pKeyDefBuf->table,
sizeof gaKeyDef);
00227 }
00228
00229 CONST ExtKeySubst*
ParseEditKeyInfo(IN OUT PKEY_EVENT_RECORD pKeyEvent)
00230 {
00231 CONST ExtKeyDef* pKeyDef;
00232 CONST ExtKeySubst* pKeySubst;
00233
00234
00235
00236
00237
00238
if (!
gExtendedEditKey ||
00239 (pKeyEvent->dwControlKeyState & (
CTRL_PRESSED |
ALT_PRESSED)) == 0 ||
00240 pKeyEvent->wVirtualKeyCode <
'A' || pKeyEvent->wVirtualKeyCode >
'Z') {
00241
00242
return NULL;
00243 }
00244
00245
00246
00247
00248 pKeyDef = &
gaKeyDef[pKeyEvent->wVirtualKeyCode -
'A'];
00249
00250
00251
00252
00253
if (pKeyEvent->dwControlKeyState &
ALT_PRESSED) {
00254
if (pKeyEvent->dwControlKeyState &
CTRL_PRESSED) {
00255 pKeySubst = &pKeyDef->keys[2];
00256 }
else {
00257 pKeySubst = &pKeyDef->keys[1];
00258 }
00259 }
else {
00260
ASSERT(pKeyEvent->dwControlKeyState &
CTRL_PRESSED);
00261 pKeySubst = &pKeyDef->keys[0];
00262 }
00263
00264
ASSERT(pKeySubst);
00265
00266
00267
00268
00269
if (pKeySubst->wVirKey == 0) {
00270
return NULL;
00271 }
00272
00273
00274
00275
00276 pKeyEvent->dwControlKeyState = pKeySubst->wMod;
00277 pKeyEvent->wVirtualKeyCode = pKeySubst->wVirKey;
00278 pKeyEvent->uChar.UnicodeChar = pKeySubst->wUnicodeChar;
00279
00280
return pKeySubst;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 BOOL IsPauseKey(IN PKEY_EVENT_RECORD pKeyEvent)
00290 {
00291
if (
gExtendedEditKey) {
00292 KEY_EVENT_RECORD KeyEvent = *pKeyEvent;
00293 CONST ExtKeySubst* pKeySubst =
ParseEditKeyInfo(&KeyEvent);
00294
00295
return pKeySubst !=
NULL && pKeySubst->wVirKey == VK_PAUSE;
00296 }
00297
00298
return pKeyEvent->wVirtualKeyCode ==
L'S' &&
CTRL_BUT_NOT_ALT(pKeyEvent->dwControlKeyState);
00299 }
00300
00301
00302
00303
00304
00305
00306 WCHAR
gaWordDelimChars[
WORD_DELIM_MAX];
00307 CONST WCHAR
gaWordDelimCharsDefault[
WORD_DELIM_MAX] =
L"\\" L"+!:=/.<>;|&";
00308
00309 BOOL IsWordDelim(WCHAR wch)
00310 {
00311
int i;
00312
00313
00314
00315
00316
00317
ASSERT(wch !=
L' ' &&
gaWordDelimChars[0]);
00318
00319
for (i = 0;
gaWordDelimChars[i] && i <
WORD_DELIM_MAX; ++i) {
00320
if (wch ==
gaWordDelimChars[i]) {
00321
return TRUE;
00322 }
00323 }
00324
00325
return FALSE;
00326 }
00327
00328
PEXE_ALIAS_LIST
00329 AddExeAliasList(
00330 IN
PCONSOLE_INFORMATION Console,
00331 IN LPVOID ExeName,
00332 IN USHORT ExeLength,
00333 IN BOOLEAN UnicodeExe
00334 )
00335 {
00336
PEXE_ALIAS_LIST AliasList;
00337
00338 AliasList = (
PEXE_ALIAS_LIST)
ConsoleHeapAlloc(
MAKE_TAG(
ALIAS_TAG ),
sizeof(
EXE_ALIAS_LIST));
00339
if (AliasList ==
NULL) {
00340
return NULL;
00341 }
00342
if (UnicodeExe) {
00343 AliasList->
ExeName = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
ALIAS_TAG ),ExeLength);
00344
if (AliasList->
ExeName ==
NULL) {
00345
ConsoleHeapFree(AliasList);
00346
return NULL;
00347 }
00348 RtlCopyMemory(AliasList->
ExeName,ExeName,ExeLength);
00349 AliasList->
ExeLength = ExeLength;
00350 }
else {
00351 AliasList->
ExeName = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
ALIAS_TAG ),ExeLength*
sizeof(WCHAR));
00352
if (AliasList->
ExeName ==
NULL) {
00353
ConsoleHeapFree(AliasList);
00354
return NULL;
00355 }
00356 AliasList->
ExeLength = (
USHORT)
ConvertInputToUnicode(Console->CP,
00357 ExeName,
00358 ExeLength,
00359 AliasList->
ExeName,
00360 ExeLength);
00361 AliasList->
ExeLength *= 2;
00362 }
00363 InitializeListHead(&AliasList->
AliasList);
00364 InsertHeadList(&Console->ExeAliasList,&AliasList->
ListLink);
00365
return AliasList;
00366 }
00367
00368
int
00369 MyStringCompareW(
00370 IN LPWSTR Str1,
00371 IN LPWSTR Str2,
00372 IN USHORT Length,
00373 IN BOOLEAN bCaseInsensitive
00374 )
00375 {
00376 UNICODE_STRING
String1;
00377 UNICODE_STRING
String2;
00378
00379
String1.Length = Length;
00380
String1.MaximumLength = Length;
00381
String1.Buffer = Str1;
00382
String2.Length = Length;
00383
String2.MaximumLength = Length;
00384
String2.Buffer = Str2;
00385
return RtlCompareUnicodeString(&
String1,
00386 &
String2,
00387 bCaseInsensitive);
00388 }
00389
00390 #define my_wcsncmpi(p1, p2, n) MyStringCompareW(p1, p2, n, TRUE)
00391 #define my_wcsncmp(p1, p2, n) MyStringCompareW(p1, p2, n, FALSE)
00392
00393
PEXE_ALIAS_LIST
00394 FindExe(
00395 IN
PCONSOLE_INFORMATION Console,
00396 IN LPVOID ExeName,
00397 IN USHORT ExeLength,
00398 IN BOOLEAN UnicodeExe
00399 )
00400
00401
00402
00403
00404
00405
00406
00407
00408 {
00409
PEXE_ALIAS_LIST AliasList;
00410 PLIST_ENTRY ListHead, ListNext;
00411 LPWSTR UnicodeExeName;
00412
00413
00414
if (UnicodeExe) {
00415 UnicodeExeName = ExeName;
00416 }
else {
00417 UnicodeExeName = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),ExeLength*
sizeof(WCHAR));
00418
if (UnicodeExeName ==
NULL)
00419
return NULL;
00420 ExeLength = (
USHORT)
ConvertInputToUnicode(Console->CP,
00421 ExeName,
00422 ExeLength,
00423 UnicodeExeName,
00424 ExeLength);
00425 ExeLength *= 2;
00426 }
00427 ListHead = &Console->ExeAliasList;
00428 ListNext = ListHead->Flink;
00429
while (ListNext != ListHead) {
00430 AliasList = CONTAINING_RECORD( ListNext,
EXE_ALIAS_LIST, ListLink );
00431
if (AliasList->
ExeLength == ExeLength &&
00432 !
my_wcsncmpi(AliasList->
ExeName,UnicodeExeName,ExeLength)) {
00433
if (!UnicodeExe) {
00434
ConsoleHeapFree(UnicodeExeName);
00435 }
00436
return AliasList;
00437 }
00438 ListNext = ListNext->Flink;
00439 }
00440
if (!UnicodeExe) {
00441
ConsoleHeapFree(UnicodeExeName);
00442 }
00443
return NULL;
00444 }
00445
00446
PALIAS
00447 FindAlias(
00448 IN
PEXE_ALIAS_LIST AliasList,
00449 IN LPWSTR AliasName,
00450 IN USHORT AliasLength
00451 )
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 {
00462
PALIAS Alias;
00463 PLIST_ENTRY ListHead, ListNext;
00464
00465 ListHead = &AliasList->AliasList;
00466 ListNext = ListHead->Flink;
00467
while (ListNext != ListHead) {
00468 Alias = CONTAINING_RECORD( ListNext,
ALIAS, ListLink );
00469
if (Alias->
SourceLength == AliasLength &&
00470 !
my_wcsncmpi(Alias->
Source,AliasName,AliasLength)) {
00471
if (ListNext != ListHead->Flink) {
00472 RemoveEntryList(ListNext);
00473 InsertHeadList(ListHead,ListNext);
00474 }
00475
return Alias;
00476 }
00477 ListNext = ListNext->Flink;
00478 }
00479
return NULL;
00480 }
00481
00482
NTSTATUS
00483 AddAlias(
00484 IN
PEXE_ALIAS_LIST ExeAliasList,
00485 IN LPWSTR Source,
00486 IN USHORT SourceLength,
00487 IN LPWSTR Target,
00488 IN USHORT TargetLength
00489 )
00490
00491
00492
00493
00494
00495
00496
00497 {
00498
PALIAS Alias;
00499
00500 Alias = (
PALIAS)
ConsoleHeapAlloc(
MAKE_TAG(
ALIAS_TAG ),
sizeof(
ALIAS));
00501
if (Alias ==
NULL) {
00502
return STATUS_NO_MEMORY;
00503 }
00504 Alias->
Source = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
ALIAS_TAG ),SourceLength);
00505
if (Alias->
Source ==
NULL) {
00506
ConsoleHeapFree(Alias);
00507
return STATUS_NO_MEMORY;
00508 }
00509 Alias->
Target = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
ALIAS_TAG ),TargetLength);
00510
if (Alias->
Target ==
NULL) {
00511
ConsoleHeapFree(Alias->
Source);
00512
ConsoleHeapFree(Alias);
00513
return STATUS_NO_MEMORY;
00514 }
00515 Alias->
SourceLength = SourceLength;
00516 Alias->
TargetLength = TargetLength;
00517 RtlCopyMemory(Alias->
Source,Source,SourceLength);
00518 RtlCopyMemory(Alias->
Target,Target,TargetLength);
00519 InsertHeadList(&ExeAliasList->AliasList,&Alias->
ListLink);
00520
return STATUS_SUCCESS;
00521 }
00522
00523
NTSTATUS
00524 ReplaceAlias(
00525 IN
PALIAS Alias,
00526 IN LPWSTR Target,
00527 IN USHORT TargetLength
00528 )
00529
00530
00531
00532
00533
00534
00535
00536 {
00537 LPWSTR NewTarget;
00538
00539 NewTarget = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
ALIAS_TAG ),TargetLength);
00540
if (NewTarget ==
NULL) {
00541
return STATUS_NO_MEMORY;
00542 }
00543
ConsoleHeapFree(Alias->Target);
00544 Alias->Target = NewTarget;
00545 Alias->TargetLength = TargetLength;
00546 RtlCopyMemory(Alias->Target,Target,TargetLength);
00547
return STATUS_SUCCESS;
00548 }
00549
00550
00551
NTSTATUS
00552 RemoveAlias(
00553 IN
PALIAS Alias
00554 )
00555
00556
00557
00558
00559
00560
00561
00562 {
00563 RemoveEntryList(&Alias->ListLink);
00564
ConsoleHeapFree(Alias->Source);
00565
ConsoleHeapFree(Alias->Target);
00566
ConsoleHeapFree(Alias);
00567
return STATUS_SUCCESS;
00568 }
00569
00570
VOID
00571 FreeAliasList(
00572 IN
PEXE_ALIAS_LIST ExeAliasList
00573 )
00574 {
00575 PLIST_ENTRY ListHead, ListNext;
00576
PALIAS Alias;
00577
00578 ListHead = &ExeAliasList->AliasList;
00579 ListNext = ListHead->Flink;
00580
while (ListNext != ListHead) {
00581 Alias = CONTAINING_RECORD( ListNext,
ALIAS, ListLink );
00582 ListNext = ListNext->Flink;
00583
RemoveAlias(Alias);
00584 }
00585 RemoveEntryList(&ExeAliasList->ListLink);
00586
ConsoleHeapFree(ExeAliasList->ExeName);
00587
ConsoleHeapFree(ExeAliasList);
00588 }
00589
00590
VOID
00591 FreeAliasBuffers(
00592 IN
PCONSOLE_INFORMATION Console
00593 )
00594 {
00595
PEXE_ALIAS_LIST AliasList;
00596 PLIST_ENTRY ListHead, ListNext;
00597
00598 ListHead = &Console->ExeAliasList;
00599 ListNext = ListHead->Flink;
00600
while (ListNext != ListHead) {
00601 AliasList = CONTAINING_RECORD( ListNext,
EXE_ALIAS_LIST, ListLink );
00602 ListNext = ListNext->Flink;
00603
FreeAliasList(AliasList);
00604 }
00605 }
00606
00607 ULONG
00608 SrvAddConsoleAlias(
00609 IN OUT PCSR_API_MSG m,
00610 IN OUT PCSR_REPLY_STATUS ReplyStatus
00611 )
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 {
00630
00631
PCONSOLE_ADDALIAS_MSG a = (
PCONSOLE_ADDALIAS_MSG)&m->u.ApiMessageData;
00632
PALIAS Alias;
00633
PCONSOLE_INFORMATION Console;
00634
PEXE_ALIAS_LIST ExeAliasList;
00635
NTSTATUS Status;
00636 LPWSTR Source,Target;
00637
00638
Status =
ApiPreamble(a->
ConsoleHandle,
00639 &Console
00640 );
00641
if (!
NT_SUCCESS(
Status)) {
00642
return Status;
00643 }
00644
00645
if (!CsrValidateMessageBuffer(m, &a->
Source, a->
SourceLength,
sizeof(
BYTE)) ||
00646 !CsrValidateMessageBuffer(m, &a->
Target,a->
TargetLength,
sizeof(
BYTE)) ||
00647 !CsrValidateMessageBuffer(m, &a->
Exe, a->
ExeLength,
sizeof(
BYTE))) {
00648
00649
UnlockConsole(Console);
00650
return STATUS_INVALID_PARAMETER;
00651 }
00652
00653
if (a->
Unicode) {
00654 Source = a->
Source;
00655 Target = a->
Target;
00656 }
else {
00657 Source = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),a->
SourceLength*
sizeof(WCHAR));
00658
if (Source ==
NULL) {
00659
UnlockConsole(Console);
00660
return (ULONG)STATUS_NO_MEMORY;
00661 }
00662 Target = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),a->
TargetLength*
sizeof(WCHAR));
00663
if (Target ==
NULL) {
00664
ConsoleHeapFree(Source);
00665
UnlockConsole(Console);
00666
return (ULONG)STATUS_NO_MEMORY;
00667 }
00668 a->
SourceLength = (
USHORT)
ConvertInputToUnicode(Console->
CP,
00669 a->
Source,
00670 a->
SourceLength,
00671 Source,
00672 a->
SourceLength);
00673 a->
SourceLength *= 2;
00674 a->
TargetLength = (
USHORT)
ConvertInputToUnicode(Console->
CP,
00675 a->
Target,
00676 a->
TargetLength,
00677 Target,
00678 a->
TargetLength);
00679 a->
TargetLength *= 2;
00680 }
00681
00682
00683
00684
00685
00686
00687 ExeAliasList =
FindExe(Console,a->
Exe,a->
ExeLength,a->
UnicodeExe);
00688
if (ExeAliasList) {
00689 Alias =
FindAlias(ExeAliasList,Source,a->
SourceLength);
00690
if (a->
TargetLength) {
00691
if (Alias) {
00692
Status =
ReplaceAlias(Alias,
00693 Target,
00694 a->
TargetLength);
00695 }
else {
00696
Status =
AddAlias(ExeAliasList,
00697 Source,
00698 a->
SourceLength,
00699 Target,
00700 a->
TargetLength);
00701 }
00702 }
else {
00703
if (Alias) {
00704
Status =
RemoveAlias(Alias);
00705 }
00706 }
00707 }
else {
00708
if (a->
TargetLength) {
00709 ExeAliasList =
AddExeAliasList(Console,a->
Exe,a->
ExeLength,a->
UnicodeExe);
00710
if (ExeAliasList) {
00711
Status =
AddAlias(ExeAliasList,
00712 Source,
00713 a->
SourceLength,
00714 Target,
00715 a->
TargetLength);
00716 }
else {
00717
Status = STATUS_NO_MEMORY;
00718 }
00719 }
00720 }
00721
UnlockConsole(Console);
00722
if (!a->
Unicode) {
00723
ConsoleHeapFree(Source);
00724
ConsoleHeapFree(Target);
00725 }
00726
return Status;
00727 UNREFERENCED_PARAMETER(ReplyStatus);
00728 }
00729
00730 ULONG
00731 SrvGetConsoleAlias(
00732 IN OUT PCSR_API_MSG m,
00733 IN OUT PCSR_REPLY_STATUS ReplyStatus
00734 )
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 {
00753
00754
NTSTATUS Status;
00755
PCONSOLE_GETALIAS_MSG a = (
PCONSOLE_GETALIAS_MSG)&m->u.ApiMessageData;
00756
PALIAS Alias;
00757
PCONSOLE_INFORMATION Console;
00758
PEXE_ALIAS_LIST ExeAliasList;
00759 LPWSTR Source,Target;
00760
00761
Status =
ApiPreamble(a->
ConsoleHandle,
00762 &Console
00763 );
00764
if (!
NT_SUCCESS(
Status)) {
00765
return Status;
00766 }
00767
00768
if (!CsrValidateMessageBuffer(m, &a->
Source, a->
SourceLength,
sizeof(
BYTE)) ||
00769 !CsrValidateMessageBuffer(m, &a->
Target, a->
TargetLength,
sizeof(
BYTE)) ||
00770 !CsrValidateMessageBuffer(m, &a->
Exe, a->
ExeLength,
sizeof(
BYTE))) {
00771
00772
UnlockConsole(Console);
00773
return STATUS_INVALID_PARAMETER;
00774 }
00775
00776
if (a->
Unicode) {
00777 Source = a->
Source;
00778 Target = a->
Target;
00779 }
else {
00780 Source = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),a->
SourceLength*
sizeof(WCHAR));
00781
if (Source ==
NULL) {
00782
UnlockConsole(Console);
00783
return (ULONG)STATUS_NO_MEMORY;
00784 }
00785 Target = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),a->
TargetLength*
sizeof(WCHAR));
00786
if (Target ==
NULL) {
00787
ConsoleHeapFree(Source);
00788
UnlockConsole(Console);
00789
return (ULONG)STATUS_NO_MEMORY;
00790 }
00791 a->
TargetLength = (
USHORT)(a->
TargetLength *
sizeof(WCHAR));
00792 a->
SourceLength = (
USHORT)
ConvertInputToUnicode(Console->
CP,
00793 a->
Source,
00794 a->
SourceLength,
00795 Source,
00796 a->
SourceLength);
00797 a->
SourceLength *= 2;
00798 }
00799 ExeAliasList =
FindExe(Console,a->
Exe,a->
ExeLength,a->
UnicodeExe);
00800
if (ExeAliasList) {
00801 Alias =
FindAlias(ExeAliasList,Source,a->
SourceLength);
00802
if (Alias) {
00803
if (Alias->
TargetLength +
sizeof(WCHAR) > a->
TargetLength) {
00804
Status = STATUS_BUFFER_TOO_SMALL;
00805 }
else {
00806 a->
TargetLength = Alias->
TargetLength +
sizeof(WCHAR);
00807 RtlCopyMemory(Target,Alias->
Target,Alias->
TargetLength);
00808 Target[Alias->
TargetLength/
sizeof(WCHAR)] =
L'\0';
00809 }
00810 }
else {
00811
Status = STATUS_UNSUCCESSFUL;
00812 }
00813 }
else {
00814
Status = STATUS_UNSUCCESSFUL;
00815 }
00816
if (!a->
Unicode) {
00817
if (
NT_SUCCESS(
Status)) {
00818 a->
TargetLength = (
USHORT)
ConvertToOem(Console->
CP,
00819 Target,
00820 a->
TargetLength /
sizeof(WCHAR),
00821 a->
Target,
00822
CHAR_COUNT(a->
TargetLength)
00823 );
00824 }
00825
ConsoleHeapFree(Source);
00826
ConsoleHeapFree(Target);
00827 }
00828
UnlockConsole(Console);
00829
return Status;
00830 UNREFERENCED_PARAMETER(ReplyStatus);
00831 }
00832
00833
DWORD
00834 SrvGetConsoleAliasesLength(
00835 IN OUT PCSR_API_MSG m,
00836 IN OUT PCSR_REPLY_STATUS ReplyStatus
00837 )
00838 {
00839
PCONSOLE_GETALIASESLENGTH_MSG a = (
PCONSOLE_GETALIASESLENGTH_MSG)&m->u.ApiMessageData;
00840
PCONSOLE_INFORMATION Console;
00841
PEXE_ALIAS_LIST ExeAliasList;
00842
PALIAS Alias;
00843 PLIST_ENTRY ListHead, ListNext;
00844
NTSTATUS Status;
00845
00846
Status =
ApiPreamble(a->
ConsoleHandle,
00847 &Console
00848 );
00849
if (!
NT_SUCCESS(
Status)) {
00850
return Status;
00851 }
00852
00853
if (!CsrValidateMessageBuffer(m, &a->
Exe, a->
ExeLength,
sizeof(
BYTE))) {
00854
UnlockConsole(Console);
00855
return STATUS_INVALID_PARAMETER;
00856 }
00857
00858 a->
AliasesLength = 0;
00859 ExeAliasList =
FindExe(Console,a->
Exe,a->
ExeLength,a->
UnicodeExe);
00860
if (ExeAliasList) {
00861 ListHead = &ExeAliasList->
AliasList;
00862 ListNext = ListHead->Flink;
00863
while (ListNext != ListHead) {
00864 Alias = CONTAINING_RECORD( ListNext,
ALIAS, ListLink );
00865 a->
AliasesLength += Alias->
SourceLength + Alias->
TargetLength + (2*
sizeof(WCHAR));
00866 ListNext = ListNext->Flink;
00867 }
00868 }
00869
if (!a->
Unicode) {
00870 a->
AliasesLength /=
sizeof(WCHAR);
00871 }
00872
UnlockConsole(Console);
00873
return STATUS_SUCCESS;
00874 UNREFERENCED_PARAMETER(ReplyStatus);
00875 }
00876
00877
VOID
00878 ClearAliases(
00879 IN
PCONSOLE_INFORMATION Console
00880 )
00881 {
00882
PEXE_ALIAS_LIST ExeAliasList;
00883 PLIST_ENTRY ListHead, ListNext;
00884
PALIAS Alias;
00885
00886 ExeAliasList =
FindExe(Console,
00887
L"cmd.exe",
00888 14,
00889
TRUE);
00890
if (ExeAliasList ==
NULL) {
00891
return;
00892 }
00893 ListHead = &ExeAliasList->
AliasList;
00894 ListNext = ListHead->Flink;
00895
while (ListNext != ListHead) {
00896 Alias = CONTAINING_RECORD( ListNext,
ALIAS, ListLink );
00897 ListNext = ListNext->Flink;
00898
RemoveAlias(Alias);
00899 }
00900 }
00901
00902
DWORD
00903 SrvGetConsoleAliases(
00904 IN OUT PCSR_API_MSG m,
00905 IN OUT PCSR_REPLY_STATUS ReplyStatus
00906 )
00907 {
00908
PCONSOLE_GETALIASES_MSG a = (
PCONSOLE_GETALIASES_MSG)&m->u.ApiMessageData;
00909
PCONSOLE_INFORMATION Console;
00910
PEXE_ALIAS_LIST ExeAliasList;
00911
PALIAS Alias;
00912 PLIST_ENTRY ListHead, ListNext;
00913
DWORD AliasesBufferLength;
00914 LPWSTR AliasesBufferPtrW;
00915 LPSTR AliasesBufferPtrA;
00916
NTSTATUS Status;
00917
00918
Status =
ApiPreamble(a->
ConsoleHandle,
00919 &Console
00920 );
00921
if (!
NT_SUCCESS(
Status)) {
00922
return Status;
00923 }
00924
00925
if (!CsrValidateMessageBuffer(m, &a->
AliasesBuffer, a->
AliasesBufferLength,
sizeof(
BYTE)) ||
00926 !CsrValidateMessageBuffer(m, &a->
Exe, a->
ExeLength,
sizeof(
BYTE))) {
00927
00928
UnlockConsole(Console);
00929
return STATUS_INVALID_PARAMETER;
00930 }
00931
00932 AliasesBufferLength = a->
AliasesBufferLength;
00933
if (a->
Unicode) {
00934 AliasesBufferPtrW = a->
AliasesBuffer;
00935 }
else {
00936 AliasesBufferPtrA = a->
AliasesBuffer;
00937 }
00938 a->
AliasesBufferLength = 0;
00939 ExeAliasList =
FindExe(Console,a->
Exe,a->
ExeLength,a->
UnicodeExe);
00940
if (ExeAliasList) {
00941 ListHead = &ExeAliasList->
AliasList;
00942 ListNext = ListHead->Flink;
00943
while (ListNext != ListHead) {
00944 Alias = CONTAINING_RECORD( ListNext,
ALIAS, ListLink );
00945
if (a->
Unicode) {
00946
if ((a->
AliasesBufferLength + Alias->
SourceLength + Alias->
TargetLength + (2*
sizeof(WCHAR)))
00947 <= AliasesBufferLength) {
00948 RtlCopyMemory(AliasesBufferPtrW,Alias->
Source,Alias->
SourceLength);
00949 AliasesBufferPtrW+=Alias->
SourceLength/
sizeof(WCHAR);
00950 *AliasesBufferPtrW++= (WCHAR)
'=';
00951 RtlCopyMemory(AliasesBufferPtrW,Alias->
Target,Alias->
TargetLength);
00952 AliasesBufferPtrW+=Alias->
TargetLength/
sizeof(WCHAR);
00953 *AliasesBufferPtrW++= (WCHAR)
'\0';
00954 a->
AliasesBufferLength += Alias->
SourceLength + Alias->
TargetLength + (2*
sizeof(WCHAR));
00955 }
else {
00956
UnlockConsole(Console);
00957
return (ULONG)STATUS_BUFFER_OVERFLOW;
00958 }
00959 }
else {
00960
if ((a->
AliasesBufferLength + ((Alias->
SourceLength + Alias->
TargetLength)/
sizeof(WCHAR)) + (2*
sizeof(
CHAR)))
00961 <= AliasesBufferLength) {
00962
USHORT SourceLength,TargetLength;
00963 SourceLength = (
USHORT)
ConvertToOem(Console->
CP,
00964 Alias->
Source,
00965 Alias->
SourceLength /
sizeof(WCHAR),
00966 AliasesBufferPtrA,
00967
CHAR_COUNT(Alias->
SourceLength)
00968 );
00969 AliasesBufferPtrA+=SourceLength;
00970 *AliasesBufferPtrA++ =
'=';
00971 TargetLength = (
USHORT)
ConvertToOem(Console->
CP,
00972 Alias->
Target,
00973 Alias->
TargetLength /
sizeof(WCHAR),
00974 AliasesBufferPtrA,
00975
CHAR_COUNT(Alias->
TargetLength)
00976 );
00977 AliasesBufferPtrA+=TargetLength;
00978 *AliasesBufferPtrA++=
'\0';
00979 a->
AliasesBufferLength += SourceLength + TargetLength + (2*
sizeof(
CHAR));
00980 }
else {
00981
UnlockConsole(Console);
00982
return (ULONG)STATUS_BUFFER_OVERFLOW;
00983 }
00984 }
00985 ListNext = ListNext->Flink;
00986 }
00987 }
00988
UnlockConsole(Console);
00989
return STATUS_SUCCESS;
00990 UNREFERENCED_PARAMETER(ReplyStatus);
00991 }
00992
00993
DWORD
00994 SrvGetConsoleAliasExesLength(
00995 IN OUT PCSR_API_MSG m,
00996 IN OUT PCSR_REPLY_STATUS ReplyStatus
00997 )
00998 {
00999
PCONSOLE_GETALIASEXESLENGTH_MSG a = (
PCONSOLE_GETALIASEXESLENGTH_MSG)&m->u.ApiMessageData;
01000
PCONSOLE_INFORMATION Console;
01001
PEXE_ALIAS_LIST AliasList;
01002 PLIST_ENTRY ListHead, ListNext;
01003
NTSTATUS Status;
01004
01005
Status =
ApiPreamble(a->
ConsoleHandle,
01006 &Console
01007 );
01008
if (!
NT_SUCCESS(
Status)) {
01009
return Status;
01010 }
01011
01012 a->
AliasExesLength = 0;
01013 ListHead = &Console->
ExeAliasList;
01014 ListNext = ListHead->Flink;
01015
while (ListNext != ListHead) {
01016 AliasList = CONTAINING_RECORD( ListNext,
EXE_ALIAS_LIST, ListLink );
01017 a->
AliasExesLength += AliasList->
ExeLength + (1*
sizeof(WCHAR));
01018 ListNext = ListNext->Flink;
01019 }
01020
if (!a->
Unicode) {
01021 a->
AliasExesLength /=
sizeof(WCHAR);
01022 }
01023
UnlockConsole(Console);
01024
return STATUS_SUCCESS;
01025 UNREFERENCED_PARAMETER(ReplyStatus);
01026 }
01027
01028
DWORD
01029 SrvGetConsoleAliasExes(
01030 IN OUT PCSR_API_MSG m,
01031 IN OUT PCSR_REPLY_STATUS ReplyStatus
01032 )
01033 {
01034
PCONSOLE_GETALIASEXES_MSG a = (
PCONSOLE_GETALIASEXES_MSG)&m->u.ApiMessageData;
01035
PCONSOLE_INFORMATION Console;
01036
PEXE_ALIAS_LIST AliasList;
01037 PLIST_ENTRY ListHead, ListNext;
01038
DWORD AliasExesBufferLength;
01039 LPWSTR AliasExesBufferPtrW;
01040 LPSTR AliasExesBufferPtrA;
01041
NTSTATUS Status;
01042
01043
Status =
ApiPreamble(a->
ConsoleHandle,
01044 &Console
01045 );
01046
if (!
NT_SUCCESS(
Status)) {
01047
return Status;
01048 }
01049
01050
if (!CsrValidateMessageBuffer(m, &a->
AliasExesBuffer, a->
AliasExesBufferLength,
sizeof(
BYTE))) {
01051
UnlockConsole(Console);
01052
return STATUS_INVALID_PARAMETER;
01053 }
01054
01055 AliasExesBufferLength = a->
AliasExesBufferLength;
01056
if (a->
Unicode) {
01057 AliasExesBufferPtrW = a->
AliasExesBuffer;
01058 }
else {
01059 AliasExesBufferPtrA = a->
AliasExesBuffer;
01060 }
01061 a->
AliasExesBufferLength = 0;
01062 ListHead = &Console->
ExeAliasList;
01063 ListNext = ListHead->Flink;
01064
while (ListNext != ListHead) {
01065 AliasList = CONTAINING_RECORD( ListNext,
EXE_ALIAS_LIST, ListLink );
01066
if (a->
Unicode) {
01067
if ((a->
AliasExesBufferLength + AliasList->
ExeLength + (1*
sizeof(WCHAR)))
01068 <= AliasExesBufferLength) {
01069 RtlCopyMemory(AliasExesBufferPtrW,AliasList->
ExeName,AliasList->
ExeLength);
01070 AliasExesBufferPtrW+=AliasList->
ExeLength/
sizeof(WCHAR);
01071 *AliasExesBufferPtrW++= (WCHAR)
'\0';
01072 a->
AliasExesBufferLength += AliasList->
ExeLength + (1*
sizeof(WCHAR));
01073 }
else {
01074
UnlockConsole(Console);
01075
return (ULONG)STATUS_BUFFER_OVERFLOW;
01076 }
01077 }
else {
01078
if ((a->
AliasExesBufferLength + (AliasList->
ExeLength/
sizeof(WCHAR)) + (1*
sizeof(
CHAR)))
01079 <= AliasExesBufferLength) {
01080
USHORT Length;
01081 Length = (
USHORT)
ConvertToOem(Console->
CP,
01082 AliasList->
ExeName,
01083 AliasList->
ExeLength /
sizeof(WCHAR),
01084 AliasExesBufferPtrA,
01085
CHAR_COUNT(AliasList->
ExeLength)
01086 );
01087 AliasExesBufferPtrA+=Length;
01088 *AliasExesBufferPtrA++= (WCHAR)
'\0';
01089 a->
AliasExesBufferLength += Length + (1*
sizeof(
CHAR));
01090 }
else {
01091
UnlockConsole(Console);
01092
return (ULONG)STATUS_BUFFER_OVERFLOW;
01093 }
01094 }
01095 ListNext = ListNext->Flink;
01096 }
01097
UnlockConsole(Console);
01098
return STATUS_SUCCESS;
01099 UNREFERENCED_PARAMETER(ReplyStatus);
01100 }
01101
01102 #define MAX_ARGS 9
01103
01104
NTSTATUS
01105 MatchandCopyAlias(
01106 IN
PCONSOLE_INFORMATION Console,
01107 IN PWCHAR Source,
01108 IN USHORT SourceLength,
01109 OUT PWCHAR TargetBuffer,
01110 IN OUT PUSHORT TargetLength,
01111 IN LPWSTR Exe,
01112 IN USHORT ExeLength,
01113 OUT PDWORD LineCount
01114 )
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 {
01149
PALIAS Alias;
01150
NTSTATUS Status = STATUS_SUCCESS;
01151
USHORT SourceUpToFirstBlank=0;
01152 PWCHAR Tmp;
01153
PEXE_ALIAS_LIST ExeAliasList;
01154 LPWSTR Args[
MAX_ARGS];
01155
USHORT ArgsLength[
MAX_ARGS];
01156
USHORT NumSourceArgs;
01157 LPWSTR SourcePtr;
01158
USHORT ArgCount,i,j,NewTargetLength;
01159
USHORT SourceRemainderLength;
01160 PWCHAR
Buffer,TargetAlias;
01161 PWCHAR TmpBuffer;
01162
01163
01164
01165
01166
01167
if (Exe ==
NULL)
01168
return STATUS_UNSUCCESSFUL;
01169
01170
01171
01172
01173
01174 ExeAliasList =
FindExe(Console,Exe,ExeLength,
TRUE);
01175
if (!ExeAliasList) {
01176
return STATUS_UNSUCCESSFUL;
01177 }
01178
01179
01180
01181
01182
01183
for (Tmp=Source,SourceUpToFirstBlank=0;
01184 *Tmp!=(WCHAR)
' ' && SourceUpToFirstBlank<(
USHORT)(SourceLength/
sizeof(WCHAR));
01185 Tmp++,SourceUpToFirstBlank++) ;
01186
01187
01188
01189
01190
01191 j=SourceUpToFirstBlank;
01192
while (j<(
USHORT)(SourceLength/
sizeof(WCHAR)) && *Tmp==(WCHAR)
' ') {
01193 Tmp++;
01194 j++;
01195 }
01196 SourcePtr = Tmp;
01197 SourceRemainderLength = (
USHORT)((SourceLength/
sizeof(WCHAR)) - j);
01198
01199
01200
01201
01202
01203 Alias =
FindAlias(ExeAliasList,Source,(
USHORT)(SourceUpToFirstBlank*
sizeof(WCHAR)));
01204
if (!Alias) {
01205
return STATUS_UNSUCCESSFUL;
01206 }
01207
01208 TmpBuffer = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),*TargetLength);
01209
if (!TmpBuffer)
01210
return STATUS_NO_MEMORY;
01211
01212
01213
01214
01215
01216 ArgCount=0;
01217 *LineCount=1;
01218 Tmp=Alias->
Target;
01219
for (i=0;(
USHORT)(i+1)<(
USHORT)(Alias->
TargetLength/
sizeof(WCHAR));i++) {
01220
if (*Tmp == (WCHAR)
'$' && *(Tmp+1) >= (WCHAR)
'1' && *(Tmp+1) <= (WCHAR)
'9') {
01221
USHORT ArgNum = *(Tmp+1) - (WCHAR)
'0';
01222
if (ArgNum > ArgCount) {
01223 ArgCount = ArgNum;
01224 }
01225 Tmp++;
01226 i++;
01227 }
else if (*Tmp == (WCHAR)
'$' && *(Tmp+1) == (WCHAR)
'*') {
01228
if (ArgCount==0) {
01229 ArgCount = 1;
01230 }
01231 Tmp++;
01232 i++;
01233 }
01234 Tmp++;
01235 }
01236
01237
01238
01239
01240
01241
01242
01243 NumSourceArgs=0;
01244 Tmp = SourcePtr;
01245
for (i=0,j=0;i<ArgCount;i++) {
01246
if (j<SourceRemainderLength) {
01247 Args[NumSourceArgs] = Tmp;
01248 ArgsLength[NumSourceArgs] = 0;
01249
while (j++<SourceRemainderLength && *Tmp++ != (WCHAR)
' ') {
01250 ArgsLength[NumSourceArgs] +=
sizeof(WCHAR);
01251 }
01252
while (j<SourceRemainderLength && *Tmp == (WCHAR)
' ') {
01253 j++;
01254 Tmp++;
01255 }
01256 NumSourceArgs++;
01257 }
else {
01258
break;
01259 }
01260 }
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
Buffer = TmpBuffer;
01278 NewTargetLength = 2*
sizeof(WCHAR);
01279 TargetAlias=Alias->
Target;
01280
for (i=0;i<(
USHORT)(Alias->
TargetLength/
sizeof(WCHAR));i++) {
01281
if (NewTargetLength >= *TargetLength) {
01282 *TargetLength = NewTargetLength;
01283
Status = STATUS_BUFFER_TOO_SMALL;
01284
break;
01285 }
01286
if (*TargetAlias == (WCHAR)
'$' && (
USHORT)(i+1)<(
USHORT)(Alias->
TargetLength/
sizeof(WCHAR))) {
01287 TargetAlias++;
01288 i++;
01289
if (*TargetAlias >= (WCHAR)
'1' && *TargetAlias <= (WCHAR)
'9') {
01290
01291
01292
01293
01294
01295
USHORT ArgNumber;
01296
01297 ArgNumber = (
USHORT)(*TargetAlias - (WCHAR)
'1');
01298
if (ArgNumber < NumSourceArgs) {
01299
if ((NewTargetLength+ArgsLength[ArgNumber])<=*TargetLength) {
01300 RtlCopyMemory(
Buffer,Args[ArgNumber],ArgsLength[ArgNumber]);
01301
Buffer+=ArgsLength[ArgNumber]/
sizeof(WCHAR);
01302 NewTargetLength+=ArgsLength[ArgNumber];
01303 }
else {
01304
Status = STATUS_BUFFER_TOO_SMALL;
01305
break;
01306 }
01307 }
01308 }
else if (*TargetAlias == (WCHAR)
'*') {
01309
01310
01311
01312
01313
01314
if (NumSourceArgs) {
01315
if ((
USHORT)(NewTargetLength+(SourceRemainderLength*
sizeof(WCHAR)))<=*TargetLength) {
01316 RtlCopyMemory(
Buffer,Args[0],SourceRemainderLength*
sizeof(WCHAR));
01317
Buffer+=SourceRemainderLength;
01318 NewTargetLength+=SourceRemainderLength*
sizeof(WCHAR);
01319 }
else {
01320
Status = STATUS_BUFFER_TOO_SMALL;
01321
break;
01322 }
01323 }
01324 }
else if (*TargetAlias == (WCHAR)
'l' || *TargetAlias == (WCHAR)
'L') {
01325
01326
01327
01328
01329
01330 *
Buffer++ = (WCHAR)
'<';
01331 NewTargetLength+=
sizeof(WCHAR);
01332 }
else if (*TargetAlias == (WCHAR)
'g' || *TargetAlias == (WCHAR)
'G') {
01333
01334
01335
01336
01337
01338 *
Buffer++ = (WCHAR)
'>';
01339 NewTargetLength+=
sizeof(WCHAR);
01340 }
else if (*TargetAlias == (WCHAR)
'b' || *TargetAlias == (WCHAR)
'B') {
01341
01342
01343
01344
01345
01346 *
Buffer++ = (WCHAR)
'|';
01347 NewTargetLength+=
sizeof(WCHAR);
01348 }
else if (*TargetAlias == (WCHAR)
't' || *TargetAlias == (WCHAR)
'T') {
01349
01350
01351
01352
01353
01354
if ((
USHORT)(NewTargetLength+(
sizeof(WCHAR)*2))>*TargetLength) {
01355
Status = STATUS_BUFFER_TOO_SMALL;
01356 }
01357
01358 *LineCount += 1;
01359 *
Buffer++ =
UNICODE_CARRIAGERETURN;
01360 *
Buffer++ =
UNICODE_LINEFEED;
01361 NewTargetLength+=
sizeof(WCHAR)*2;
01362 }
else {
01363
01364
01365
01366
01367
01368 *
Buffer++ = (WCHAR)
'$';
01369 NewTargetLength+=
sizeof(WCHAR);
01370 *
Buffer++ = *TargetAlias;
01371 NewTargetLength+=
sizeof(WCHAR);
01372 }
01373 TargetAlias++;
01374 }
else {
01375
01376
01377
01378
01379
01380 *
Buffer++ = *TargetAlias++;
01381 NewTargetLength+=
sizeof(WCHAR);
01382 }
01383 }
01384 *
Buffer++ =
UNICODE_CARRIAGERETURN;
01385 *
Buffer++ =
UNICODE_LINEFEED;
01386 RtlCopyMemory(TargetBuffer,TmpBuffer,NewTargetLength);
01387
ConsoleHeapFree(TmpBuffer);
01388 *TargetLength = NewTargetLength;
01389
return Status;
01390 }
01391
01392
DWORD
01393 SrvExpungeConsoleCommandHistory(
01394 IN OUT PCSR_API_MSG m,
01395 IN OUT PCSR_REPLY_STATUS ReplyStatus
01396 )
01397 {
01398
PCONSOLE_EXPUNGECOMMANDHISTORY_MSG a = (
PCONSOLE_EXPUNGECOMMANDHISTORY_MSG)&m->u.ApiMessageData;
01399
PCONSOLE_INFORMATION Console;
01400
NTSTATUS Status;
01401
01402
Status =
ApiPreamble(a->
ConsoleHandle,
01403 &Console
01404 );
01405
if (!
NT_SUCCESS(
Status)) {
01406
return Status;
01407 }
01408
01409
if (!CsrValidateMessageBuffer(m, &a->
Exe, a->
ExeLength,
sizeof(
BYTE))) {
01410
UnlockConsole(Console);
01411
return STATUS_INVALID_PARAMETER;
01412 }
01413
01414
EmptyCommandHistory(
FindExeCommandHistory(Console,
01415 a->
Exe,
01416 a->
ExeLength,
01417 a->
UnicodeExe));
01418
UnlockConsole(Console);
01419
return STATUS_SUCCESS;
01420 UNREFERENCED_PARAMETER(ReplyStatus);
01421 }
01422
01423
DWORD
01424 SrvSetConsoleNumberOfCommands(
01425 IN OUT PCSR_API_MSG m,
01426 IN OUT PCSR_REPLY_STATUS ReplyStatus
01427 )
01428 {
01429
PCONSOLE_SETNUMBEROFCOMMANDS_MSG a = (
PCONSOLE_SETNUMBEROFCOMMANDS_MSG)&m->u.ApiMessageData;
01430
PCONSOLE_INFORMATION Console;
01431
NTSTATUS Status;
01432
01433
Status =
ApiPreamble(a->
ConsoleHandle,
01434 &Console
01435 );
01436
if (!
NT_SUCCESS(
Status)) {
01437
return Status;
01438 }
01439
01440
if (!CsrValidateMessageBuffer(m, &a->
Exe, a->
ExeLength,
sizeof(
BYTE))) {
01441
UnlockConsole(Console);
01442
return STATUS_INVALID_PARAMETER;
01443 }
01444
01445
ReallocCommandHistory(Console,
01446
FindExeCommandHistory(Console,
01447 a->
Exe,
01448 a->
ExeLength,
01449 a->
UnicodeExe),
01450 a->
NumCommands
01451 );
01452
UnlockConsole(Console);
01453
return STATUS_SUCCESS;
01454 UNREFERENCED_PARAMETER(ReplyStatus);
01455 }
01456
01457
DWORD
01458 SrvGetConsoleCommandHistoryLength(
01459 IN OUT PCSR_API_MSG m,
01460 IN OUT PCSR_REPLY_STATUS ReplyStatus
01461 )
01462 {
01463
PCONSOLE_GETCOMMANDHISTORYLENGTH_MSG a = (
PCONSOLE_GETCOMMANDHISTORYLENGTH_MSG)&m->u.ApiMessageData;
01464
PCONSOLE_INFORMATION Console;
01465
NTSTATUS Status;
01466
SHORT i;
01467
PCOMMAND_HISTORY CommandHistory;
01468
01469
Status =
ApiPreamble(a->
ConsoleHandle,
01470 &Console
01471 );
01472
if (!
NT_SUCCESS(
Status)) {
01473
return Status;
01474 }
01475
01476
if (!CsrValidateMessageBuffer(m, &a->
Exe, a->
ExeLength,
sizeof(
BYTE))) {
01477
UnlockConsole(Console);
01478
return STATUS_INVALID_PARAMETER;
01479 }
01480
01481 a->
CommandHistoryLength=0;
01482 CommandHistory=
FindExeCommandHistory(Console,
01483 a->
Exe,
01484 a->
ExeLength,
01485 a->
UnicodeExe);
01486
if (CommandHistory) {
01487
for (i=0;i<CommandHistory->
NumberOfCommands;i++) {
01488 a->
CommandHistoryLength+=CommandHistory->
Commands[i]->
CommandLength+
sizeof(WCHAR);
01489 }
01490 }
01491
if (!a->
Unicode) {
01492 a->
CommandHistoryLength /=
sizeof(WCHAR);
01493 }
01494
UnlockConsole(Console);
01495
return STATUS_SUCCESS;
01496 UNREFERENCED_PARAMETER(ReplyStatus);
01497 }
01498
01499
DWORD
01500 SrvGetConsoleCommandHistory(
01501 IN OUT PCSR_API_MSG m,
01502 IN OUT PCSR_REPLY_STATUS ReplyStatus
01503 )
01504 {
01505
PCONSOLE_GETCOMMANDHISTORY_MSG a = (
PCONSOLE_GETCOMMANDHISTORY_MSG)&m->u.ApiMessageData;
01506
PCONSOLE_INFORMATION Console;
01507
NTSTATUS Status;
01508
SHORT i,CommandHistoryLength;
01509
PCOMMAND_HISTORY CommandHistory;
01510 PWCHAR CommandBufferW;
01511 PCHAR CommandBufferA;
01512
01513
Status =
ApiPreamble(a->
ConsoleHandle,
01514 &Console
01515 );
01516
if (!
NT_SUCCESS(
Status)) {
01517
return Status;
01518 }
01519
01520
if (!CsrValidateMessageBuffer(m, &a->
CommandBuffer, a->
CommandBufferLength,
sizeof(
BYTE)) ||
01521 !CsrValidateMessageBuffer(m, &a->
Exe, a->
ExeLength,
sizeof(
BYTE))) {
01522
01523
UnlockConsole(Console);
01524
return STATUS_INVALID_PARAMETER;
01525 }
01526
01527
if (a->
Unicode) {
01528 CommandBufferW=a->
CommandBuffer;
01529 }
else {
01530 CommandBufferA=a->
CommandBuffer;
01531 }
01532 CommandHistoryLength=0;
01533 CommandHistory=
FindExeCommandHistory(Console,
01534 a->
Exe,
01535 a->
ExeLength,
01536 a->
UnicodeExe);
01537
if (CommandHistory) {
01538
for (i=0;i<CommandHistory->
NumberOfCommands;i++) {
01539
if (a->
Unicode) {
01540
if ((CommandHistoryLength+CommandHistory->
Commands[i]->
CommandLength+
sizeof(WCHAR)) <= a->
CommandBufferLength) {
01541 RtlCopyMemory(CommandBufferW,CommandHistory->
Commands[i]->
Command,CommandHistory->
Commands[i]->
CommandLength);
01542 CommandBufferW+=CommandHistory->
Commands[i]->
CommandLength/
sizeof(WCHAR);
01543 *CommandBufferW++=(WCHAR)
'\0';
01544 CommandHistoryLength+=CommandHistory->
Commands[i]->
CommandLength+
sizeof(WCHAR);
01545 }
else {
01546
Status = STATUS_BUFFER_OVERFLOW;
01547
break;
01548 }
01549 }
else {
01550
if ((CommandHistoryLength+(CommandHistory->
Commands[i]->
CommandLength/
sizeof(WCHAR))+
sizeof(
CHAR)) <= a->
CommandBufferLength) {
01551
USHORT Length;
01552 Length = (
USHORT)
ConvertToOem(Console->
CP,
01553 CommandHistory->
Commands[i]->
Command,
01554 CommandHistory->
Commands[i]->
CommandLength /
sizeof(WCHAR),
01555 CommandBufferA,
01556
CHAR_COUNT(CommandHistory->
Commands[i]->
CommandLength)
01557 );
01558 CommandBufferA+=Length;
01559 *CommandBufferA++=(WCHAR)
'\0';
01560 CommandHistoryLength+=CommandHistory->
Commands[i]->
CommandLength+
sizeof(WCHAR);
01561 }
else {
01562
Status = STATUS_BUFFER_OVERFLOW;
01563
break;
01564 }
01565 }
01566 }
01567 }
01568 a->
CommandBufferLength=CommandHistoryLength;
01569
UnlockConsole(Console);
01570
return Status;
01571 UNREFERENCED_PARAMETER(ReplyStatus);
01572 }
01573
01574
DWORD
01575 SrvSetConsoleCommandHistoryMode(
01576 IN OUT PCSR_API_MSG m,
01577 IN OUT PCSR_REPLY_STATUS ReplyStatus
01578 )
01579 {
01580
PCONSOLE_SETCOMMANDHISTORYMODE_MSG a = (
PCONSOLE_SETCOMMANDHISTORYMODE_MSG)&m->u.ApiMessageData;
01581
PCONSOLE_INFORMATION Console;
01582
NTSTATUS Status;
01583
01584
Status =
ApiPreamble(a->
ConsoleHandle,
01585 &Console
01586 );
01587
if (!
NT_SUCCESS(
Status)) {
01588
return Status;
01589 }
01590 Console->
InsertMode = (BOOLEAN) (a->
Flags != CONSOLE_OVERSTRIKE);
01591
UnlockConsole(Console);
01592
return STATUS_SUCCESS;
01593 UNREFERENCED_PARAMETER(ReplyStatus);
01594 }
01595
01596
PCOMMAND_HISTORY
01597 ReallocCommandHistory(
01598 IN
PCONSOLE_INFORMATION Console,
01599 IN
PCOMMAND_HISTORY CurrentCommandHistory,
01600 IN DWORD NumCommands
01601 )
01602 {
01603
PCOMMAND_HISTORY History;
01604
int i;
01605
01606
if (CurrentCommandHistory ==
NULL ||
01607 CurrentCommandHistory->MaximumNumberOfCommands==(
SHORT)NumCommands) {
01608
return CurrentCommandHistory;
01609 }
01610
History = (
PCOMMAND_HISTORY)
ConsoleHeapAlloc(
MAKE_TAG(
HISTORY_TAG ),
sizeof(
COMMAND_HISTORY) + ((NumCommands-1) *
sizeof(
PCOMMAND)));
01611
if (
History ==
NULL) {
01612
return CurrentCommandHistory;
01613 }
01614 *
History=*CurrentCommandHistory;
01615
History->Flags |=
CLE_RESET;
01616
History->NumberOfCommands =
min(
History->NumberOfCommands, (
SHORT)NumCommands);
01617
History->LastAdded =
History->NumberOfCommands - 1;
01618
History->LastDisplayed =
History->NumberOfCommands - 1;
01619
History->FirstCommand = 0;
01620
History->MaximumNumberOfCommands=(
SHORT)NumCommands;
01621
for (i=0; i<
History->NumberOfCommands; i++) {
01622
History->Commands[i] = CurrentCommandHistory->Commands[
COMMAND_NUM_TO_INDEX(i,CurrentCommandHistory)];
01623 }
01624
for (; i<CurrentCommandHistory->NumberOfCommands; i++) {
01625
ConsoleHeapFree(CurrentCommandHistory->Commands[
COMMAND_NUM_TO_INDEX(i,CurrentCommandHistory)]);
01626 }
01627
01628 RemoveEntryList(&CurrentCommandHistory->ListLink);
01629 InitializeListHead(&
History->PopupList);
01630 InsertHeadList(&Console->CommandHistoryList,&
History->ListLink);
01631
01632
ConsoleHeapFree(CurrentCommandHistory);
01633
return History;
01634 }
01635
01636
PCOMMAND_HISTORY
01637 FindExeCommandHistory(
01638 IN
PCONSOLE_INFORMATION Console,
01639 IN PVOID AppName,
01640 IN DWORD AppNameLength,
01641 IN BOOLEAN Unicode
01642 )
01643 {
01644
PCOMMAND_HISTORY History;
01645 PLIST_ENTRY ListHead, ListNext;
01646 PWCHAR AppNamePtr;
01647
01648
if (!
Unicode) {
01649 AppNamePtr = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),AppNameLength *
sizeof(WCHAR));
01650
if (AppNamePtr ==
NULL) {
01651
return NULL;
01652 }
01653 AppNameLength =
ConvertInputToUnicode(Console->CP,
01654 AppName,
01655 AppNameLength,
01656 AppNamePtr,
01657 AppNameLength);
01658 AppNameLength *= 2;
01659 }
else {
01660 AppNamePtr = AppName;
01661 }
01662 ListHead = &Console->CommandHistoryList;
01663 ListNext = ListHead->Flink;
01664
while (ListNext != ListHead) {
01665
History = CONTAINING_RECORD( ListNext,
COMMAND_HISTORY, ListLink );
01666 ListNext = ListNext->Flink;
01667
01668
if (
History->Flags &
CLE_ALLOCATED &&
01669 !
my_wcsncmpi(
History->AppName,AppNamePtr,(
USHORT)AppNameLength)) {
01670
if (!
Unicode) {
01671
ConsoleHeapFree(AppNamePtr);
01672 }
01673
return History;
01674 }
01675 }
01676
if (!
Unicode) {
01677
ConsoleHeapFree(AppNamePtr);
01678 }
01679
return NULL;
01680 }
01681
01682
PCOMMAND_HISTORY
01683 AllocateCommandHistory(
01684 IN
PCONSOLE_INFORMATION Console,
01685 IN DWORD AppNameLength,
01686 IN PWCHAR AppName,
01687 IN HANDLE ProcessHandle
01688 )
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707 {
01708
PCOMMAND_HISTORY History,BestCandidate;
01709 PLIST_ENTRY ListHead, ListNext;
01710
BOOL SameApp;
01711
01712
01713
01714
01715
01716
01717 ListHead = &Console->CommandHistoryList;
01718 ListNext = ListHead->Blink;
01719 BestCandidate =
NULL;
01720 SameApp =
FALSE;
01721
while (ListNext != ListHead) {
01722
History = CONTAINING_RECORD( ListNext,
COMMAND_HISTORY, ListLink );
01723 ListNext = ListNext->Blink;
01724
01725
if ((
History->Flags &
CLE_ALLOCATED) == 0) {
01726
01727
01728
01729
01730
01731
if (
History->AppName && !
my_wcsncmpi(
History->AppName,AppName,(
USHORT)AppNameLength)) {
01732 BestCandidate =
History;
01733 SameApp =
TRUE;
01734
break;
01735 }
01736
01737
01738
01739
01740
01741
if (BestCandidate ==
NULL) {
01742 BestCandidate =
History;
01743 }
01744 }
01745 }
01746
01747
01748
01749
01750
01751
01752
if (!SameApp && Console->NumCommandHistories < Console->MaxCommandHistories) {
01753
History = (
PCOMMAND_HISTORY)
ConsoleHeapAlloc(
MAKE_TAG(
HISTORY_TAG ),
sizeof(
COMMAND_HISTORY) + ((Console->CommandHistorySize-1) *
sizeof(
PCOMMAND)));
01754
if (
History ==
NULL) {
01755
return NULL;
01756 }
01757
History->AppName = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
HISTORY_TAG ),AppNameLength);
01758
if (
History->AppName ==
NULL) {
01759
ConsoleHeapFree(
History);
01760
return NULL;
01761 }
01762 RtlCopyMemory(
History->AppName,AppName,AppNameLength);
01763
History->Flags =
CLE_ALLOCATED;
01764
History->NumberOfCommands = 0;
01765
History->LastAdded = -1;
01766
History->LastDisplayed = -1;
01767
History->FirstCommand = 0;
01768
History->MaximumNumberOfCommands = Console->CommandHistorySize;
01769 InsertHeadList(&Console->CommandHistoryList,&
History->ListLink);
01770 Console->NumCommandHistories+=1;
01771
History->ProcessHandle = ProcessHandle;
01772 InitializeListHead(&
History->PopupList);
01773
return History;
01774 }
01775
01776
01777
01778
01779
01780
if (BestCandidate) {
01781
History = BestCandidate;
01782
ASSERT(
CLE_NO_POPUPS(
History));
01783
if (!SameApp) {
01784
SHORT i;
01785
if (
History->AppName) {
01786
DBGPRINT((
"Reusing %ls command history\n",
History->AppName));
01787
ConsoleHeapFree(
History->AppName);
01788 }
01789
for (i=0;i<
History->NumberOfCommands;i++) {
01790
ConsoleHeapFree(
History->Commands[i]);
01791 }
01792
History->NumberOfCommands = 0;
01793
History->LastAdded = -1;
01794
History->LastDisplayed = -1;
01795
History->FirstCommand = 0;
01796
History->AppName = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
HISTORY_TAG ),AppNameLength);
01797
if (
History->AppName ==
NULL) {
01798
History->Flags &= ~
CLE_ALLOCATED;
01799
return NULL;
01800 }
01801 RtlCopyMemory(
History->AppName,AppName,AppNameLength);
01802 }
01803
History->ProcessHandle = ProcessHandle;
01804
History->Flags |=
CLE_ALLOCATED;
01805
01806
01807
01808
01809
01810 RemoveEntryList(&BestCandidate->ListLink);
01811 InsertHeadList(&Console->CommandHistoryList,&BestCandidate->ListLink);
01812 }
01813
return BestCandidate;
01814 }
01815
01816
NTSTATUS
01817 BeginPopup(
01818 IN
PSCREEN_INFORMATION ScreenInfo,
01819 IN
PCOMMAND_HISTORY CommandHistory,
01820 IN COORD PopupSize
01821 )
01822 {
01823 COORD Origin;
01824 COORD
Size;
01825
PCLE_POPUP Popup;
01826 SMALL_RECT TargetRect;
01827
01828
01829
01830
Size = PopupSize;
01831
Size.X += 2;
01832
Size.Y += 2;
01833
if (
Size.X >= (
SHORT)(
CONSOLE_WINDOW_SIZE_X(ScreenInfo))) {
01834
Size.X = (
SHORT)(
CONSOLE_WINDOW_SIZE_X(ScreenInfo));
01835 }
01836
if (
Size.Y >= (
SHORT)(
CONSOLE_WINDOW_SIZE_Y(ScreenInfo))) {
01837
Size.Y = (
SHORT)(
CONSOLE_WINDOW_SIZE_Y(ScreenInfo));
01838 }
01839
01840
01841
01842
if (
Size.X < 2 ||
Size.Y < 2) {
01843
return STATUS_BUFFER_TOO_SMALL;
01844 }
01845
01846
01847 Origin.X = (
SHORT)((
CONSOLE_WINDOW_SIZE_X(ScreenInfo) -
Size.X) / 2 + ScreenInfo->Window.Left);
01848 Origin.Y = (
SHORT)((
CONSOLE_WINDOW_SIZE_Y(ScreenInfo) -
Size.Y) / 2 + ScreenInfo->Window.Top);
01849
01850
01851
01852 Popup = (
PCLE_POPUP)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),
sizeof(
CLE_POPUP));
01853
if (Popup ==
NULL) {
01854
return STATUS_NO_MEMORY;
01855 }
01856
01857
01858
01859
#if !defined(FE_SB)
01860
Popup->
OldContents = (PCHAR_INFO)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),
Size.X *
Size.Y *
sizeof(CHAR_INFO));
01861
#else
01862
Popup->OldScreenSize = ScreenInfo->ScreenBufferSize;
01863 Popup->
OldContents = (PCHAR_INFO)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),Popup->OldScreenSize.X *
Size.Y *
sizeof(CHAR_INFO));
01864
#endif
01865
if (Popup->
OldContents ==
NULL) {
01866
ConsoleHeapFree(Popup);
01867
return STATUS_NO_MEMORY;
01868 }
01869
if ((ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01870 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
01871 Popup->
Flags |=
CLEPF_FALSE_UNICODE;
01872 }
else {
01873 Popup->
Flags &= ~
CLEPF_FALSE_UNICODE;
01874 }
01875
01876
01877
01878
01879
01880 InsertHeadList(&CommandHistory->PopupList,&Popup->
ListLink);
01881 Popup->
Region.Left = Origin.X;
01882 Popup->
Region.Top = Origin.Y;
01883 Popup->
Region.Right = (
SHORT)(Origin.X +
Size.X - 1);
01884 Popup->
Region.Bottom = (
SHORT)(Origin.Y +
Size.Y - 1);
01885 Popup->
Attributes = ScreenInfo->PopupAttributes;
01886 Popup->
BottomIndex =
COMMAND_INDEX_TO_NUM(CommandHistory->LastDisplayed,CommandHistory);
01887
01888
01889
01890
01891
01892
#if !defined(FE_SB)
01893
TargetRect = Popup->
Region;
01894
#else
01895
TargetRect.Left = 0;
01896 TargetRect.Top = Popup->
Region.Top;
01897 TargetRect.Right = Popup->OldScreenSize.X - 1;
01898 TargetRect.Bottom = Popup->
Region.Bottom;
01899
#endif
01900
ReadScreenBuffer(ScreenInfo,
01901 Popup->
OldContents,
01902 &TargetRect);
01903
01904 ScreenInfo->Console->PopupCount++;
01905
DrawCommandListBorder(Popup,ScreenInfo);
01906
return STATUS_SUCCESS;
01907 }
01908
01909
NTSTATUS
01910 EndPopup(
01911 IN
PSCREEN_INFORMATION ScreenInfo,
01912 IN
PCOMMAND_HISTORY CommandHistory
01913 )
01914 {
01915 COORD
Size;
01916 SMALL_RECT SourceRect;
01917
PCLE_POPUP Popup;
01918
01919
ASSERT(!
CLE_NO_POPUPS(CommandHistory));
01920
if (
CLE_NO_POPUPS(CommandHistory))
01921
return STATUS_UNSUCCESSFUL;
01922
01923
ConsoleHideCursor(ScreenInfo);
01924 Popup = CONTAINING_RECORD( CommandHistory->PopupList.Flink,
CLE_POPUP, ListLink );
01925
01926
01927
01928
01929
01930
#if !defined(FE_SB)
01931
Size.X = (
SHORT)(Popup->
Region.Right - Popup->
Region.Left + 1);
01932
Size.Y = (
SHORT)(Popup->
Region.Bottom - Popup->
Region.Top + 1);
01933 SourceRect = Popup->
Region;
01934
#else
01935
Size.X = Popup->OldScreenSize.X;
01936
Size.Y = (
SHORT)(Popup->
Region.Bottom - Popup->
Region.Top + 1);
01937 SourceRect.Left = 0;
01938 SourceRect.Top = Popup->
Region.Top;
01939 SourceRect.Right = Popup->OldScreenSize.X - 1;
01940 SourceRect.Bottom = Popup->
Region.Bottom;
01941
#endif
01942
if ((ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
01943 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
01944
01945
01946
01947
if (!(Popup->
Flags &
CLEPF_FALSE_UNICODE)) {
01948
#if !defined(FE_SB)
01949
TranslateOutputToAnsiUnicode(ScreenInfo->Console,
01950 Popup->
OldContents,
Size);
01951
#else
01952
TranslateOutputToAnsiUnicode(ScreenInfo->Console,
01953 Popup->
OldContents,
Size,
01954
NULL);
01955
#endif
01956
}
01957 }
else {
01958
01959
01960
01961
if (Popup->
Flags &
CLEPF_FALSE_UNICODE) {
01962
#if !defined(FE_SB)
01963
TranslateOutputToOemUnicode(ScreenInfo->Console,
01964 Popup->
OldContents,
Size);
01965
#else
01966
TranslateOutputToOemUnicode(ScreenInfo->Console,
01967 Popup->
OldContents,
Size,
FALSE);
01968
#endif
01969
}
01970 }
01971
WriteScreenBuffer(ScreenInfo,
01972 Popup->
OldContents,
01973 &SourceRect
01974 );
01975
WriteToScreen(ScreenInfo,
01976 &SourceRect
01977 );
01978
01979
ConsoleShowCursor(ScreenInfo);
01980
01981
01982
01983
01984
01985 RemoveEntryList(&Popup->
ListLink);
01986
ConsoleHeapFree(Popup->
OldContents);
01987
ConsoleHeapFree(Popup);
01988 ScreenInfo->Console->PopupCount--;
01989
return STATUS_SUCCESS;
01990 }
01991
01992
VOID
01993 CleanUpPopups(
01994 IN
PCOOKED_READ_DATA CookedReadData
01995 )
01996 {
01997
PCOMMAND_HISTORY CommandHistory;
01998
01999 CommandHistory = CookedReadData->CommandHistory;
02000
if (!CommandHistory)
02001
return;
02002
while (!
CLE_NO_POPUPS(CommandHistory)) {
02003
EndPopup(CookedReadData->ScreenInfo,CommandHistory);
02004 }
02005 }
02006
02007
02008
VOID
02009 DeleteCommandLine(
02010 IN OUT
PCOOKED_READ_DATA CookedReadData,
02011 IN BOOL UpdateFields
02012 )
02013 {
02014
DWORD CharsToWrite = CookedReadData->NumberOfVisibleChars;
02015 COORD Coord = CookedReadData->OriginalCursorPosition;
02016
02017
02018
02019
02020
02021
02022
if (Coord.Y < 0) {
02023 CharsToWrite += CookedReadData->ScreenInfo->ScreenBufferSize.X * Coord.Y;
02024 CharsToWrite += CookedReadData->OriginalCursorPosition.X;
02025 CookedReadData->OriginalCursorPosition.X = 0;
02026 CookedReadData->OriginalCursorPosition.Y = 0;
02027 Coord.X = 0;
02028 Coord.Y = 0;
02029 }
02030
#if defined(FE_SB)
02031
if (CONSOLE_IS_DBCS_OUTPUTCP(CookedReadData->ScreenInfo->Console) &&
02032 !CheckBisectStringW(CookedReadData->ScreenInfo,
02033 CookedReadData->ScreenInfo->Console->CP,
02034 CookedReadData->BackupLimit,
02035 CharsToWrite,
02036 CookedReadData->ScreenInfo->ScreenBufferSize.X
02037 -CookedReadData->OriginalCursorPosition.X
02038 )) {
02039 CharsToWrite++;
02040 }
02041
#endif
02042
FillOutput(CookedReadData->ScreenInfo,
02043 (WCHAR)
' ',
02044 Coord,
02045
CONSOLE_FALSE_UNICODE,
02046 &CharsToWrite
02047 );
02048
if (UpdateFields) {
02049 CookedReadData->BufPtr=CookedReadData->BackupLimit;
02050 CookedReadData->BytesRead=0;
02051 CookedReadData->CurrentPosition=0;
02052 CookedReadData->NumberOfVisibleChars = 0;
02053 }
02054
SetCursorPosition(CookedReadData->ScreenInfo,
02055 CookedReadData->OriginalCursorPosition,
02056
TRUE
02057 );
02058 }
02059
02060
VOID
02061 RedrawCommandLine(
02062 IN OUT
PCOOKED_READ_DATA CookedReadData
02063 )
02064 {
02065
NTSTATUS Status;
02066 COORD CursorPosition;
02067
SHORT ScrollY=0;
02068
02069
if (CookedReadData->Echo) {
02070
02071
02072
02073 CookedReadData->OriginalCursorPosition = CookedReadData->ScreenInfo->BufferInfo.TextInfo.CursorPosition;
02074
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
02075 CookedReadData->BackupLimit,
02076 CookedReadData->BackupLimit,
02077 CookedReadData->BackupLimit,
02078 &CookedReadData->BytesRead,
02079 &CookedReadData->NumberOfVisibleChars,
02080 CookedReadData->OriginalCursorPosition.X,
02081
WC_DESTRUCTIVE_BACKSPACE |
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
02082 &ScrollY);
02083
ASSERT(
NT_SUCCESS(
Status));
02084 CookedReadData->OriginalCursorPosition.Y += ScrollY;
02085
02086
02087
02088
02089 CursorPosition = CookedReadData->OriginalCursorPosition;
02090 CursorPosition.X += (
SHORT)
RetrieveTotalNumberOfSpaces(CookedReadData->OriginalCursorPosition.X,
02091 CookedReadData->BackupLimit,
02092 CookedReadData->CurrentPosition,
02093 CookedReadData->ScreenInfo->Console);
02094
if (CheckBisectStringW(CookedReadData->ScreenInfo,
02095 CookedReadData->ScreenInfo->Console->CP,
02096 CookedReadData->BackupLimit,
02097 CookedReadData->CurrentPosition,
02098 CookedReadData->ScreenInfo->ScreenBufferSize.X
02099 -CookedReadData->OriginalCursorPosition.X)) {
02100 CursorPosition.X++;
02101 }
02102
Status =
AdjustCursorPosition(CookedReadData->ScreenInfo,
02103 CursorPosition,
02104
TRUE,
02105
NULL);
02106
ASSERT(
NT_SUCCESS(
Status));
02107 }
02108 }
02109
02110
NTSTATUS
02111 RetrieveNthCommand(
02112 IN
PCOMMAND_HISTORY CommandHistory,
02113 IN SHORT Index,
02114 IN PWCHAR Buffer,
02115 IN ULONG BufferSize,
02116 OUT PULONG CommandSize
02117 )
02118 {
02119
PCOMMAND CommandRecord;
02120
02121
ASSERT (Index < CommandHistory->NumberOfCommands);
02122 CommandHistory->LastDisplayed =
Index;
02123 CommandRecord = CommandHistory->Commands[
Index];
02124
if (CommandRecord->
CommandLength > (
USHORT)
BufferSize) {
02125 *CommandSize = (
USHORT)
BufferSize;
02126 }
02127
else {
02128 *CommandSize = CommandRecord->
CommandLength;
02129 }
02130 RtlCopyMemory(
Buffer,CommandRecord->
Command,*CommandSize);
02131
return STATUS_SUCCESS;
02132 }
02133
02134
02135
VOID
02136 SetCurrentCommandLine(
02137 IN
PCOOKED_READ_DATA CookedReadData,
02138 IN SHORT Index
02139 )
02140
02141
02142
02143
02144
02145
02146 {
02147
DWORD CharsToWrite;
02148
NTSTATUS Status;
02149
SHORT ScrollY=0;
02150
02151
DeleteCommandLine(CookedReadData,
02152
TRUE);
02153
Status =
RetrieveNthCommand(CookedReadData->CommandHistory,
02154
Index,
02155 CookedReadData->BackupLimit,
02156 CookedReadData->BufferSize,
02157 &CookedReadData->BytesRead);
02158
ASSERT(
NT_SUCCESS(
Status));
02159
ASSERT(CookedReadData->BackupLimit == CookedReadData->BufPtr);
02160
if (CookedReadData->Echo) {
02161
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
02162 CookedReadData->BackupLimit,
02163 CookedReadData->BufPtr,
02164 CookedReadData->BufPtr,
02165 &CookedReadData->BytesRead,
02166 (PLONG)&CookedReadData->NumberOfVisibleChars,
02167 CookedReadData->OriginalCursorPosition.X,
02168
WC_DESTRUCTIVE_BACKSPACE |
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
02169 &ScrollY);
02170
ASSERT(
NT_SUCCESS(
Status));
02171 CookedReadData->OriginalCursorPosition.Y += ScrollY;
02172 }
02173 CharsToWrite = CookedReadData->BytesRead/
sizeof(WCHAR);
02174 CookedReadData->CurrentPosition = CharsToWrite;
02175 CookedReadData->BufPtr = CookedReadData->BackupLimit + CharsToWrite;
02176 }
02177
02178
BOOL
02179 IsCommandLinePopupKey(
02180 IN OUT PKEY_EVENT_RECORD KeyEvent
02181 )
02182 {
02183
if (!(KeyEvent->dwControlKeyState &
02184 (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED |
02185 RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))) {
02186
switch (KeyEvent->wVirtualKeyCode) {
02187
case VK_ESCAPE:
02188
case VK_PRIOR:
02189
case VK_NEXT:
02190
case VK_END:
02191
case VK_HOME:
02192
case VK_LEFT:
02193
case VK_UP:
02194
case VK_RIGHT:
02195
case VK_DOWN:
02196
case VK_F9:
02197
return TRUE;
02198
default:
02199
break;
02200 }
02201 }
02202
02203
02204
02205
02206
if (
gExtendedEditKey &&
ParseEditKeyInfo(KeyEvent)) {
02207
return KeyEvent->uChar.UnicodeChar == 0;
02208 }
02209
02210
return FALSE;
02211 }
02212
02213
BOOL
02214 IsCommandLineEditingKey(
02215 IN PKEY_EVENT_RECORD KeyEvent
02216 )
02217 {
02218
if (!(KeyEvent->dwControlKeyState &
02219 (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED |
02220 RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))) {
02221
switch (KeyEvent->wVirtualKeyCode) {
02222
case VK_ESCAPE:
02223
case VK_PRIOR:
02224
case VK_NEXT:
02225
case VK_END:
02226
case VK_HOME:
02227
case VK_LEFT:
02228
case VK_UP:
02229
case VK_RIGHT:
02230
case VK_DOWN:
02231
case VK_INSERT:
02232
case VK_DELETE:
02233
case VK_F1:
02234
case VK_F2:
02235
case VK_F3:
02236
case VK_F4:
02237
case VK_F5:
02238
case VK_F6:
02239
case VK_F7:
02240
case VK_F8:
02241
case VK_F9:
02242
return TRUE;
02243
default:
02244
break;
02245 }
02246 }
02247
if ((KeyEvent->dwControlKeyState &
02248 (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))) {
02249
switch (KeyEvent->wVirtualKeyCode) {
02250
case VK_END:
02251
case VK_HOME:
02252
case VK_LEFT:
02253
case VK_RIGHT:
02254
return TRUE;
02255
default:
02256
break;
02257 }
02258 }
02259
02260
02261
02262
02263
if (
gExtendedEditKey &&
ParseEditKeyInfo(KeyEvent)) {
02264
02265
02266
02267
02268
02269
return KeyEvent->uChar.UnicodeChar == 0;
02270 }
02271
02272
if ((KeyEvent->dwControlKeyState &
02273 (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))) {
02274
switch (KeyEvent->wVirtualKeyCode) {
02275
case VK_F7:
02276
case VK_F10:
02277
return TRUE;
02278
default:
02279
break;
02280 }
02281 }
02282
return FALSE;
02283 }
02284
02285
02286
NTSTATUS
02287 ProcessCommandListInput(
02288 IN PVOID CookedReadDataPtr,
02289 IN PCSR_API_MSG WaitReplyMessage,
02290 IN PCSR_THREAD WaitingThread,
02291 IN BOOLEAN WaitRoutine
02292 )
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308 {
02309
NTSTATUS Status;
02310
PCLE_POPUP Popup;
02311
PCOMMAND_HISTORY CommandHistory;
02312
PCOOKED_READ_DATA CookedReadData=(
PCOOKED_READ_DATA)CookedReadDataPtr;
02313 WCHAR Char;
02314 BOOLEAN CommandLinePopupKeys =
FALSE;
02315
PCONSOLE_READCONSOLE_MSG a;
02316
PHANDLE_DATA HandleData;
02317
SHORT Index;
02318
02319 CommandHistory = CookedReadData->
CommandHistory;
02320 Popup = CONTAINING_RECORD( CommandHistory->
PopupList.Flink,
CLE_POPUP, ListLink );
02321
Status =
DereferenceIoHandleNoCheck(CookedReadData->
ProcessData,
02322 CookedReadData->
HandleIndex,
02323 &HandleData
02324 );
02325
ASSERT (
NT_SUCCESS(
Status));
02326
while (
TRUE) {
02327
Status =
GetChar(CookedReadData->
InputInfo,
02328 &Char,
02329
TRUE,
02330 CookedReadData->
Console,
02331 HandleData,
02332 WaitReplyMessage,
02333
CookedReadWaitRoutine,
02334 CookedReadData,
02335
sizeof(*CookedReadData),
02336 WaitRoutine,
02337
NULL,
02338 &CommandLinePopupKeys,
02339
NULL,
02340
NULL
02341 );
02342
if (!
NT_SUCCESS(
Status)) {
02343
if (
Status !=
CONSOLE_STATUS_WAIT) {
02344 CookedReadData->BytesRead = 0;
02345 }
02346
return Status;
02347 }
02348
02349
if (CommandLinePopupKeys) {
02350
switch (Char) {
02351
case VK_F9:
02352
02353
02354
02355
02356
02357
02358 {
02359 COORD PopupSize;
02360
02361
if (CookedReadData->CommandHistory &&
02362 CookedReadData->ScreenInfo->ScreenBufferSize.X >=
MINIMUM_COMMAND_PROMPT_SIZE+2) {
02363 PopupSize.X =
COMMAND_NUMBER_PROMPT_LENGTH+
COMMAND_NUMBER_LENGTH;
02364 PopupSize.Y = 1;
02365
Status =
BeginPopup(CookedReadData->ScreenInfo,
02366 CookedReadData->CommandHistory,
02367 PopupSize
02368 );
02369
if (
NT_SUCCESS(
Status)) {
02370
02371
return CommandNumberPopup(CookedReadData,
02372 WaitReplyMessage,
02373 WaitingThread,
02374 WaitRoutine
02375 );
02376 }
02377 }
02378 }
02379
break;
02380
case VK_ESCAPE:
02381
EndPopup(CookedReadData->ScreenInfo,CommandHistory);
02382 HandleData->
InputReadData->
ReadCount += 1;
02383
return CONSOLE_STATUS_WAIT_NO_BLOCK;
02384
case VK_UP:
02385
UpdateCommandListPopup(-1,
02386 &Popup->
CurrentCommand,
02387 CommandHistory,
02388 Popup,
02389 CookedReadData->ScreenInfo, 0);
02390
break;
02391
case VK_DOWN:
02392
UpdateCommandListPopup(1,
02393 &Popup->
CurrentCommand,
02394 CommandHistory,
02395 Popup,
02396 CookedReadData->ScreenInfo, 0);
02397
break;
02398
case VK_END:
02399
02400
02401
02402
UpdateCommandListPopup((
SHORT)(CommandHistory->
NumberOfCommands),
02403 &Popup->
CurrentCommand,
02404 CommandHistory,
02405 Popup,
02406 CookedReadData->ScreenInfo, 0);
02407
break;
02408
case VK_HOME:
02409
02410
02411
02412
UpdateCommandListPopup((
SHORT)-(CommandHistory->
NumberOfCommands),
02413 &Popup->
CurrentCommand,
02414 CommandHistory,
02415 Popup,
02416 CookedReadData->ScreenInfo, 0);
02417
break;
02418
case VK_PRIOR:
02419
UpdateCommandListPopup((
SHORT)-
POPUP_SIZE_Y(Popup),
02420 &Popup->CurrentCommand,
02421 CommandHistory,
02422 Popup,
02423 CookedReadData->ScreenInfo, 0);
02424
break;
02425
case VK_NEXT:
02426
UpdateCommandListPopup(
POPUP_SIZE_Y(Popup),
02427 &Popup->CurrentCommand,
02428 CommandHistory,
02429 Popup,
02430 CookedReadData->ScreenInfo, 0);
02431
break;
02432
case VK_LEFT:
02433
case VK_RIGHT:
02434
Index = Popup->CurrentCommand;
02435
EndPopup(CookedReadData->ScreenInfo,CommandHistory);
02436
SetCurrentCommandLine(CookedReadData,
Index);
02437 HandleData->
InputReadData->
ReadCount += 1;
02438
return CONSOLE_STATUS_WAIT_NO_BLOCK;
02439
default:
02440
break;
02441 }
02442 }
else if (Char ==
UNICODE_CARRIAGERETURN) {
02443 ULONG i,lStringLength;
02444
DWORD LineCount=1;
02445
Index = Popup->
CurrentCommand;
02446
EndPopup(CookedReadData->ScreenInfo,CommandHistory);
02447
SetCurrentCommandLine(CookedReadData,
Index);
02448 lStringLength = CookedReadData->BytesRead;
02449
ProcessCookedReadInput(CookedReadData,
02450
UNICODE_CARRIAGERETURN,
02451 0,
02452 &
Status);
02453
02454
02455
02456
02457
if (CookedReadData->Echo) {
02458
02459
02460
02461
02462
02463 i = CookedReadData->BufferSize;
02464
if (
NT_SUCCESS(
MatchandCopyAlias(CookedReadData->Console,
02465 CookedReadData->BackupLimit,
02466 (
USHORT)lStringLength,
02467 CookedReadData->BackupLimit,
02468 (
PUSHORT)&i,
02469 CookedReadData->ExeName,
02470 CookedReadData->ExeNameLength,
02471 &LineCount
02472 ))) {
02473 CookedReadData->BytesRead = i;
02474 }
02475
CloseOutputHandle(
CONSOLE_FROMTHREADPERPROCESSDATA(WaitingThread),
02476 CookedReadData->Console,
02477 &CookedReadData->TempHandle,
02478
NULL,
02479
FALSE
02480 );
02481 }
02482 WaitReplyMessage->ReturnValue = STATUS_SUCCESS;
02483 a = (
PCONSOLE_READCONSOLE_MSG)&WaitReplyMessage->u.ApiMessageData;
02484
if (CookedReadData->BytesRead > CookedReadData->UserBufferSize || LineCount > 1) {
02485
if (LineCount > 1) {
02486 PWSTR Tmp;
02487 HandleData->
InputReadData->
InputHandleFlags |=
HANDLE_MULTI_LINE_INPUT;
02488
for (Tmp=CookedReadData->BackupLimit;*Tmp!=
UNICODE_LINEFEED;Tmp++)
02489
ASSERT(Tmp<(CookedReadData->BackupLimit+CookedReadData->BytesRead));
02490 a->
NumBytes = (ULONG)(Tmp-CookedReadData->BackupLimit+1)*
sizeof(*Tmp);
02491 }
else {
02492 a->
NumBytes = CookedReadData->UserBufferSize;
02493 }
02494 HandleData->
InputReadData->
InputHandleFlags |=
HANDLE_INPUT_PENDING;
02495 HandleData->
InputReadData->
BufPtr = CookedReadData->BackupLimit;
02496 HandleData->
InputReadData->
BytesAvailable = CookedReadData->BytesRead - a->
NumBytes;
02497 HandleData->
InputReadData->
CurrentBufPtr=(PWCHAR)((
PBYTE)CookedReadData->BackupLimit+a->
NumBytes);
02498 RtlCopyMemory(CookedReadData->UserBuffer,CookedReadData->BackupLimit,a->
NumBytes);
02499 }
02500
else {
02501 a->
NumBytes = CookedReadData->BytesRead;
02502 RtlCopyMemory(CookedReadData->UserBuffer,CookedReadData->BackupLimit,a->
NumBytes);
02503 }
02504
if (!a->
Unicode) {
02505
02506
02507
02508
02509
02510 PCHAR TransBuffer;
02511
02512 TransBuffer = (PCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),
CHAR_COUNT(a->
NumBytes));
02513
if (TransBuffer ==
NULL) {
02514
return STATUS_NO_MEMORY;
02515 }
02516
02517 a->
NumBytes = (ULONG)
ConvertToOem(CookedReadData->Console->CP,
02518 CookedReadData->UserBuffer,
02519 a->
NumBytes /
sizeof(WCHAR),
02520 TransBuffer,
02521
CHAR_COUNT(a->
NumBytes)
02522 );
02523 RtlCopyMemory(CookedReadData->UserBuffer,TransBuffer,a->
NumBytes);
02524
ConsoleHeapFree(TransBuffer);
02525 }
02526
02527
return CONSOLE_STATUS_READ_COMPLETE;
02528
02529 }
else {
02530
Index =
FindMatchingCommand(CookedReadData->CommandHistory,
02531 &Char, 1 *
sizeof(WCHAR),
02532 Popup->
CurrentCommand,
FMCFL_JUST_LOOKING);
02533
if (
Index != -1) {
02534
UpdateCommandListPopup(
02535 (
SHORT)(
Index - Popup->
CurrentCommand),
02536 &Popup->
CurrentCommand,
02537 CommandHistory,
02538 Popup,
02539 CookedReadData->ScreenInfo,
UCLP_WRAP);
02540 }
02541 }
02542 }
02543 }
02544
02545
NTSTATUS
02546 ProcessCopyFromCharInput(
02547 IN PVOID CookedReadDataPtr,
02548 IN PCSR_API_MSG WaitReplyMessage,
02549 IN PCSR_THREAD WaitingThread,
02550 IN BOOLEAN WaitRoutine
02551 )
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567 {
02568
NTSTATUS Status;
02569
PCOOKED_READ_DATA CookedReadData=(
PCOOKED_READ_DATA)CookedReadDataPtr;
02570 WCHAR Char;
02571
PHANDLE_DATA HandleData;
02572
int i;
02573
02574
Status =
DereferenceIoHandleNoCheck(CookedReadData->
ProcessData,
02575 CookedReadData->
HandleIndex,
02576 &HandleData
02577 );
02578
ASSERT (
NT_SUCCESS(
Status));
02579
while (
TRUE) {
02580
Status =
GetChar(CookedReadData->
InputInfo,
02581 &Char,
02582
TRUE,
02583 CookedReadData->
Console,
02584 HandleData,
02585 WaitReplyMessage,
02586
CookedReadWaitRoutine,
02587 CookedReadData,
02588
sizeof(*CookedReadData),
02589 WaitRoutine,
02590
NULL,
02591
NULL,
02592
NULL,
02593
NULL
02594 );
02595
if (!
NT_SUCCESS(
Status)) {
02596
if (
Status !=
CONSOLE_STATUS_WAIT) {
02597 CookedReadData->BytesRead = 0;
02598 }
02599
return Status;
02600 }
02601
02602
EndPopup(CookedReadData->ScreenInfo,CookedReadData->CommandHistory);
02603
02604
02605
02606
02607
02608
for (i=CookedReadData->CurrentPosition+1;
02609 i<(
int)(CookedReadData->BytesRead/
sizeof(WCHAR));
02610 i++) {
02611
if (CookedReadData->BackupLimit[i] == Char) {
02612
break;
02613 }
02614 }
02615
if (i!=(
int)(CookedReadData->BytesRead/
sizeof(WCHAR)+1)) {
02616 COORD CursorPosition;
02617
02618
02619
02620
02621
02622 CursorPosition = CookedReadData->ScreenInfo->BufferInfo.TextInfo.CursorPosition;
02623
02624
02625
02626
02627
02628
DeleteCommandLine(CookedReadData,
02629
FALSE);
02630
02631
02632
02633
02634 RtlCopyMemory(&CookedReadData->BackupLimit[CookedReadData->CurrentPosition],
02635 &CookedReadData->BackupLimit[i],
02636 CookedReadData->BytesRead-(i*
sizeof(WCHAR))
02637 );
02638 CookedReadData->BytesRead -= (i-CookedReadData->CurrentPosition)*
sizeof(WCHAR);
02639
02640
02641
02642
02643
02644
if (CookedReadData->Echo) {
02645
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
02646 CookedReadData->BackupLimit,
02647 CookedReadData->BackupLimit,
02648 CookedReadData->BackupLimit,
02649 &CookedReadData->BytesRead,
02650 (PLONG)&CookedReadData->NumberOfVisibleChars,
02651 CookedReadData->OriginalCursorPosition.X,
02652
WC_DESTRUCTIVE_BACKSPACE |
02653
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
02654
NULL
02655 );
02656
ASSERT(
NT_SUCCESS(
Status));
02657 }
02658
02659
02660
02661
02662
02663
Status =
SetCursorPosition(CookedReadData->ScreenInfo,
02664 CursorPosition,
02665
TRUE
02666 );
02667
ASSERT(
NT_SUCCESS(
Status));
02668 }
02669
02670 HandleData->
InputReadData->
ReadCount += 1;
02671
return CONSOLE_STATUS_WAIT_NO_BLOCK;
02672 }
02673 UNREFERENCED_PARAMETER(WaitingThread);
02674 }
02675
02676
NTSTATUS
02677 ProcessCopyToCharInput(
02678 IN PVOID CookedReadDataPtr,
02679 IN PCSR_API_MSG WaitReplyMessage,
02680 IN PCSR_THREAD WaitingThread,
02681 IN BOOLEAN WaitRoutine
02682 )
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698 {
02699
NTSTATUS Status;
02700
PCOOKED_READ_DATA CookedReadData=(
PCOOKED_READ_DATA)CookedReadDataPtr;
02701 WCHAR Char;
02702
PCOMMAND LastCommand;
02703
DWORD NumSpaces;
02704
SHORT ScrollY=0;
02705
PHANDLE_DATA HandleData;
02706
02707
Status =
DereferenceIoHandleNoCheck(CookedReadData->
ProcessData,
02708 CookedReadData->
HandleIndex,
02709 &HandleData
02710 );
02711
ASSERT (
NT_SUCCESS(
Status));
02712
while (
TRUE) {
02713
Status =
GetChar(CookedReadData->
InputInfo,
02714 &Char,
02715
TRUE,
02716 CookedReadData->
Console,
02717 HandleData,
02718 WaitReplyMessage,
02719
CookedReadWaitRoutine,
02720 CookedReadData,
02721
sizeof(*CookedReadData),
02722 WaitRoutine,
02723
NULL,
02724
NULL,
02725
NULL,
02726
NULL
02727 );
02728
if (!
NT_SUCCESS(
Status)) {
02729
if (
Status !=
CONSOLE_STATUS_WAIT) {
02730 CookedReadData->BytesRead = 0;
02731 }
02732
return Status;
02733 }
02734
02735
EndPopup(CookedReadData->ScreenInfo,CookedReadData->CommandHistory);
02736
02737
02738
02739
02740
02741 LastCommand =
GetLastCommand(CookedReadData->CommandHistory);
02742
if (LastCommand) {
02743
int i,j;
02744
02745
02746
02747
02748
02749
for (i=CookedReadData->CurrentPosition+1;i<(
int)(LastCommand->
CommandLength/
sizeof(WCHAR));i++) {
02750
if (LastCommand->
Command[i] == Char)
02751
break;
02752 }
02753
02754
02755
02756
02757
02758
if (i<(
int)(LastCommand->
CommandLength/
sizeof(WCHAR)) && (
USHORT)(LastCommand->
CommandLength/
sizeof(WCHAR)) > (
USHORT)CookedReadData->CurrentPosition) {
02759 j=i-CookedReadData->CurrentPosition;
02760
ASSERT(j>0);
02761 RtlCopyMemory(CookedReadData->BufPtr,
02762 &LastCommand->
Command[CookedReadData->CurrentPosition],
02763 j*
sizeof(WCHAR));
02764 CookedReadData->CurrentPosition += j;
02765 j*=
sizeof(WCHAR);
02766 CookedReadData->BytesRead += j;
02767
if (CookedReadData->Echo) {
02768
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
02769 CookedReadData->BackupLimit,
02770 CookedReadData->BufPtr,
02771 CookedReadData->BufPtr,
02772 (PDWORD) &j,
02773 (PLONG)&NumSpaces,
02774 CookedReadData->OriginalCursorPosition.X,
02775
WC_DESTRUCTIVE_BACKSPACE |
02776
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
02777 &ScrollY
02778 );
02779
ASSERT(
NT_SUCCESS(
Status));
02780 CookedReadData->OriginalCursorPosition.Y += ScrollY;
02781 CookedReadData->NumberOfVisibleChars += NumSpaces;
02782 }
02783 CookedReadData->BufPtr+=j/
sizeof(WCHAR);
02784 }
02785 }
02786 HandleData->
InputReadData->
ReadCount += 1;
02787
return CONSOLE_STATUS_WAIT_NO_BLOCK;
02788 }
02789 UNREFERENCED_PARAMETER(WaitingThread);
02790 }
02791
02792
NTSTATUS
02793 ProcessCommandNumberInput(
02794 IN PVOID CookedReadDataPtr,
02795 IN PCSR_API_MSG WaitReplyMessage,
02796 IN PCSR_THREAD WaitingThread,
02797 IN BOOLEAN WaitRoutine
02798 )
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814 {
02815
NTSTATUS Status;
02816
PCLE_POPUP Popup;
02817
PCOMMAND_HISTORY CommandHistory;
02818
PCOOKED_READ_DATA CookedReadData=(
PCOOKED_READ_DATA)CookedReadDataPtr;
02819 WCHAR Char;
02820
DWORD NumSpaces;
02821 BOOLEAN CommandLinePopupKeys;
02822
SHORT CommandNumber;
02823
PHANDLE_DATA HandleData;
02824
02825 CommandHistory = CookedReadData->
CommandHistory;
02826 Popup = CONTAINING_RECORD( CommandHistory->
PopupList.Flink,
CLE_POPUP, ListLink );
02827
Status =
DereferenceIoHandleNoCheck(CookedReadData->
ProcessData,
02828 CookedReadData->
HandleIndex,
02829 &HandleData
02830 );
02831
ASSERT (
NT_SUCCESS(
Status));
02832
while (
TRUE) {
02833
Status =
GetChar(CookedReadData->
InputInfo,
02834 &Char,
02835
TRUE,
02836 CookedReadData->
Console,
02837 HandleData,
02838 WaitReplyMessage,
02839
CookedReadWaitRoutine,
02840 CookedReadData,
02841
sizeof(*CookedReadData),
02842 WaitRoutine,
02843
NULL,
02844 &CommandLinePopupKeys,
02845
NULL,
02846
NULL
02847 );
02848
if (!
NT_SUCCESS(
Status)) {
02849
if (
Status !=
CONSOLE_STATUS_WAIT) {
02850 CookedReadData->BytesRead = 0;
02851 }
02852
return Status;
02853 }
02854
02855
if (Char >= (WCHAR)0x30 && Char <= (WCHAR)0x39) {
02856
if (Popup->
NumberRead < 5) {
02857
DWORD CharsToWrite;
02858 WORD RealAttributes;
02859
02860 RealAttributes = CookedReadData->ScreenInfo->Attributes;
02861 CookedReadData->ScreenInfo->Attributes = Popup->
Attributes;
02862 CharsToWrite =
sizeof(WCHAR);
02863
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
02864 Popup->
NumberBuffer,
02865 &Popup->
NumberBuffer[Popup->
NumberRead],
02866 &Char,
02867 &CharsToWrite,
02868 (PLONG)&NumSpaces,
02869 CookedReadData->OriginalCursorPosition.X,
02870
WC_DESTRUCTIVE_BACKSPACE |
02871
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
02872
NULL
02873 );
02874
ASSERT(
NT_SUCCESS(
Status));
02875 CookedReadData->ScreenInfo->Attributes = RealAttributes;
02876 Popup->
NumberBuffer[Popup->
NumberRead] = Char;
02877 Popup->
NumberRead += 1;
02878 }
02879 }
else if (Char ==
UNICODE_BACKSPACE) {
02880
if (Popup->
NumberRead > 0) {
02881
DWORD CharsToWrite;
02882 WORD RealAttributes;
02883
02884 RealAttributes = CookedReadData->ScreenInfo->Attributes;
02885 CookedReadData->ScreenInfo->Attributes = Popup->
Attributes;
02886 CharsToWrite =
sizeof(WCHAR);
02887
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
02888 Popup->
NumberBuffer,
02889 &Popup->
NumberBuffer[Popup->
NumberRead],
02890 &Char,
02891 &CharsToWrite,
02892 (PLONG)&NumSpaces,
02893 CookedReadData->OriginalCursorPosition.X,
02894
WC_DESTRUCTIVE_BACKSPACE |
02895
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
02896
NULL
02897 );
02898
ASSERT(
NT_SUCCESS(
Status));
02899 CookedReadData->ScreenInfo->Attributes = RealAttributes;
02900 Popup->
NumberBuffer[Popup->
NumberRead] = (WCHAR)
' ';
02901 Popup->
NumberRead -= 1;
02902 }
02903 }
else if (Char == (WCHAR)VK_ESCAPE) {
02904
EndPopup(CookedReadData->ScreenInfo,CookedReadData->CommandHistory);
02905
if (!
CLE_NO_POPUPS(CommandHistory)) {
02906
EndPopup(CookedReadData->ScreenInfo,CookedReadData->CommandHistory);
02907 }
02908
DeleteCommandLine(CookedReadData,
02909
TRUE);
02910 }
else if (Char ==
UNICODE_CARRIAGERETURN) {
02911
CHAR NumberBuffer[6];
02912
int i;
02913
02914
for (i=0;i<Popup->
NumberRead;i++) {
02915 NumberBuffer[i] = (
CHAR)Popup->
NumberBuffer[i];
02916 }
02917 NumberBuffer[i] = 0;
02918 CommandNumber = (
SHORT)atoi(NumberBuffer);
02919
if ((WORD)CommandNumber >= (WORD)CookedReadData->CommandHistory->NumberOfCommands) {
02920 CommandNumber = (
SHORT)(CookedReadData->CommandHistory->NumberOfCommands-1);
02921 }
02922
EndPopup(CookedReadData->ScreenInfo,CookedReadData->CommandHistory);
02923
if (!
CLE_NO_POPUPS(CommandHistory)) {
02924
EndPopup(CookedReadData->ScreenInfo,CookedReadData->CommandHistory);
02925 }
02926
SetCurrentCommandLine(CookedReadData,
COMMAND_NUM_TO_INDEX(CommandNumber,CookedReadData->CommandHistory));
02927 }
02928 HandleData->
InputReadData->
ReadCount += 1;
02929
return CONSOLE_STATUS_WAIT_NO_BLOCK;
02930 }
02931 UNREFERENCED_PARAMETER(WaitingThread);
02932 }
02933
02934
NTSTATUS
02935 CommandListPopup(
02936 IN
PCOOKED_READ_DATA CookedReadData,
02937 IN PCSR_API_MSG WaitReplyMessage,
02938 IN PCSR_THREAD WaitingThread,
02939 IN BOOLEAN WaitRoutine
02940 )
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957 {
02958
SHORT CurrentCommand;
02959
PCLE_POPUP Popup;
02960
PCOMMAND_HISTORY CommandHistory;
02961
02962 CommandHistory = CookedReadData->CommandHistory;
02963 Popup = CONTAINING_RECORD( CommandHistory->
PopupList.Flink,
CLE_POPUP, ListLink );
02964
02965 CurrentCommand =
COMMAND_INDEX_TO_NUM(CommandHistory->
LastDisplayed,CommandHistory);
02966
02967
if (CurrentCommand < (
SHORT)(CommandHistory->
NumberOfCommands -
POPUP_SIZE_Y(Popup))) {
02968 Popup->
BottomIndex = (
SHORT)(
max(CurrentCommand,
POPUP_SIZE_Y(Popup)-1));
02969 }
else {
02970 Popup->
BottomIndex = (
SHORT)(CommandHistory->
NumberOfCommands-1);
02971 }
02972 Popup->
CurrentCommand = CommandHistory->
LastDisplayed;
02973
DrawCommandListPopup(Popup,
02974 CommandHistory->
LastDisplayed,
02975 CommandHistory,
02976 CookedReadData->ScreenInfo);
02977 Popup->
PopupInputRoutine = (
PCLE_POPUP_INPUT_ROUTINE)
ProcessCommandListInput;
02978
return ProcessCommandListInput(CookedReadData,
02979 WaitReplyMessage,
02980 WaitingThread,
02981 WaitRoutine
02982 );
02983 }
02984
02985
VOID
02986 DrawPromptPopup(
02987 IN
PCLE_POPUP Popup,
02988 IN
PSCREEN_INFORMATION ScreenInfo,
02989 IN PWCHAR Prompt,
02990 IN ULONG PromptLength
02991 )
02992 {
02993 ULONG lStringLength;
02994 COORD WriteCoord;
02995
SHORT i;
02996
02997
02998
02999
03000
03001 WriteCoord.X = (
SHORT)(Popup->Region.Left+1);
03002 WriteCoord.Y = (
SHORT)(Popup->Region.Top+1);
03003 lStringLength =
POPUP_SIZE_X(Popup);
03004
for (i=0;i<
POPUP_SIZE_Y(Popup);i++) {
03005
FillOutput(ScreenInfo,
03006 Popup->Attributes,
03007 WriteCoord,
03008
CONSOLE_ATTRIBUTE,
03009 &lStringLength
03010 );
03011
FillOutput(ScreenInfo,
03012 (WCHAR)
' ',
03013 WriteCoord,
03014
CONSOLE_FALSE_UNICODE,
03015 &lStringLength
03016 );
03017 WriteCoord.Y += 1;
03018 }
03019
03020 WriteCoord.X = (
SHORT)(Popup->Region.Left+1);
03021 WriteCoord.Y = (
SHORT)(Popup->Region.Top+1);
03022
03023
03024
03025
03026
03027 lStringLength = PromptLength;
03028
if (lStringLength > (ULONG)
POPUP_SIZE_X(Popup))
03029 lStringLength = (ULONG)(
POPUP_SIZE_X(Popup));
03030
WriteOutputString(ScreenInfo,
03031 Prompt,
03032 WriteCoord,
03033
CONSOLE_REAL_UNICODE,
03034 &lStringLength,
03035
NULL
03036 );
03037 }
03038
03039
NTSTATUS
03040 CopyFromCharPopup(
03041 IN
PCOOKED_READ_DATA CookedReadData,
03042 IN PCSR_API_MSG WaitReplyMessage,
03043 IN PCSR_THREAD WaitingThread,
03044 IN BOOLEAN WaitRoutine
03045 )
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062 {
03063
PCLE_POPUP Popup;
03064
PCOMMAND_HISTORY CommandHistory;
03065 WCHAR ItemString[70];
03066
int ItemLength;
03067
NTSTATUS Status;
03068 LANGID LangId;
03069
03070
Status =
GetConsoleLangId(CookedReadData->ScreenInfo->Console->OutputCP, &LangId);
03071
if (
NT_SUCCESS(
Status)) {
03072 ItemLength =
LoadStringEx(
ghInstance,
msgCmdLineF4,ItemString,70,LangId);
03073 }
03074
if (!
NT_SUCCESS(
Status) || ItemLength == 0) {
03075 ItemLength = LoadString(
ghInstance,
msgCmdLineF4,ItemString,70);
03076 }
03077
03078 CommandHistory = CookedReadData->CommandHistory;
03079 Popup = CONTAINING_RECORD( CommandHistory->
PopupList.Flink,
CLE_POPUP, ListLink );
03080
03081
DrawPromptPopup(Popup,
03082 CookedReadData->ScreenInfo,
03083 ItemString,
03084 ItemLength
03085 );
03086 Popup->
PopupInputRoutine = (
PCLE_POPUP_INPUT_ROUTINE)
ProcessCopyFromCharInput;
03087
return ProcessCopyFromCharInput(CookedReadData,
03088 WaitReplyMessage,
03089 WaitingThread,
03090 WaitRoutine
03091 );
03092 }
03093
03094
03095
NTSTATUS
03096 CopyToCharPopup(
03097 IN
PCOOKED_READ_DATA CookedReadData,
03098 IN PCSR_API_MSG WaitReplyMessage,
03099 IN PCSR_THREAD WaitingThread,
03100 IN BOOLEAN WaitRoutine
03101 )
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118 {
03119
PCLE_POPUP Popup;
03120
PCOMMAND_HISTORY CommandHistory;
03121 WCHAR ItemString[70];
03122
int ItemLength;
03123
NTSTATUS Status;
03124 LANGID LangId;
03125
03126
Status =
GetConsoleLangId(CookedReadData->ScreenInfo->Console->OutputCP, &LangId);
03127
if (
NT_SUCCESS(
Status)) {
03128 ItemLength =
LoadStringEx(
ghInstance,
msgCmdLineF2,ItemString,70,LangId);
03129 }
03130
if (!
NT_SUCCESS(
Status) || ItemLength == 0) {
03131 ItemLength = LoadString(
ghInstance,
msgCmdLineF2,ItemString,70);
03132 }
03133
03134 CommandHistory = CookedReadData->CommandHistory;
03135 Popup = CONTAINING_RECORD( CommandHistory->
PopupList.Flink,
CLE_POPUP, ListLink );
03136
DrawPromptPopup(Popup,
03137 CookedReadData->ScreenInfo,
03138 ItemString,
03139 ItemLength
03140 );
03141 Popup->
PopupInputRoutine = (
PCLE_POPUP_INPUT_ROUTINE)
ProcessCopyToCharInput;
03142
return ProcessCopyToCharInput(CookedReadData,
03143 WaitReplyMessage,
03144 WaitingThread,
03145 WaitRoutine
03146 );
03147 }
03148
03149
NTSTATUS
03150 CommandNumberPopup(
03151 IN
PCOOKED_READ_DATA CookedReadData,
03152 IN PCSR_API_MSG WaitReplyMessage,
03153 IN PCSR_THREAD WaitingThread,
03154 IN BOOLEAN WaitRoutine
03155 )
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172 {
03173
PCLE_POPUP Popup;
03174
PCOMMAND_HISTORY CommandHistory;
03175 COORD CursorPosition;
03176 WCHAR ItemString[70];
03177
int ItemLength;
03178
NTSTATUS Status;
03179 LANGID LangId;
03180
03181 CommandHistory = CookedReadData->CommandHistory;
03182 Popup = CONTAINING_RECORD( CommandHistory->
PopupList.Flink,
CLE_POPUP, ListLink );
03183
03184
Status =
GetConsoleLangId(CookedReadData->ScreenInfo->Console->OutputCP, &LangId);
03185
if (
NT_SUCCESS(
Status)) {
03186 ItemLength =
LoadStringEx(
ghInstance,
msgCmdLineF9,ItemString,70,LangId);
03187 }
03188
if (!
NT_SUCCESS(
Status) || ItemLength == 0) {
03189 ItemLength = LoadString(
ghInstance,
msgCmdLineF9,ItemString,70);
03190 }
03191
03192
if (ItemLength >
POPUP_SIZE_X(Popup) -
COMMAND_NUMBER_LENGTH) {
03193 ItemLength =
POPUP_SIZE_X(Popup) -
COMMAND_NUMBER_LENGTH;
03194 }
03195
DrawPromptPopup(Popup,
03196 CookedReadData->ScreenInfo,
03197 ItemString,
03198 ItemLength
03199 );
03200 CursorPosition.X = (
SHORT)(Popup->
Region.Right -
MINIMUM_COMMAND_PROMPT_SIZE);
03201 CursorPosition.Y = (
SHORT)(Popup->
Region.Top+1);
03202
SetCursorPosition(CookedReadData->ScreenInfo,
03203 CursorPosition,
03204
TRUE
03205 );
03206 Popup->
NumberRead=0;
03207 Popup->
PopupInputRoutine = (
PCLE_POPUP_INPUT_ROUTINE)
ProcessCommandNumberInput;
03208
return ProcessCommandNumberInput(CookedReadData,
03209 WaitReplyMessage,
03210 WaitingThread,
03211 WaitRoutine
03212 );
03213 }
03214
03215
03216
PCOMMAND
03217 GetLastCommand(
03218 IN
PCOMMAND_HISTORY CommandHistory
03219 )
03220 {
03221
if (CommandHistory->NumberOfCommands == 0)
03222
return NULL;
03223
return CommandHistory->Commands[CommandHistory->LastDisplayed];
03224 }
03225
03226
VOID
03227 EmptyCommandHistory(
03228 IN
PCOMMAND_HISTORY CommandHistory
03229 )
03230 {
03231
SHORT i;
03232
if (CommandHistory==
NULL)
03233
return;
03234
for (i=0;i<CommandHistory->NumberOfCommands;i++) {
03235
ConsoleHeapFree(CommandHistory->Commands[i]);
03236 }
03237 CommandHistory->NumberOfCommands = 0;
03238 CommandHistory->LastAdded = -1;
03239 CommandHistory->LastDisplayed = -1;
03240 CommandHistory->FirstCommand = 0;
03241 CommandHistory->Flags =
CLE_RESET;
03242 }
03243
03244
BOOL
03245 AtFirstCommand(
03246 IN
PCOMMAND_HISTORY CommandHistory
03247 )
03248 {
03249
SHORT i;
03250
03251
if (CommandHistory==
NULL)
03252
return FALSE;
03253
if (CommandHistory->Flags &
CLE_RESET)
03254
return FALSE;
03255 i = (
SHORT)(CommandHistory->LastDisplayed - 1);
03256
if (i==-1)
03257 i=(
SHORT)(CommandHistory->NumberOfCommands-1);
03258
return (i == CommandHistory->LastAdded);
03259 }
03260
03261
BOOL
03262 AtLastCommand(
03263 IN
PCOMMAND_HISTORY CommandHistory
03264 )
03265 {
03266
if (CommandHistory==
NULL)
03267
return FALSE;
03268
return (CommandHistory->LastDisplayed == CommandHistory->LastAdded);
03269 }
03270
03271
NTSTATUS
03272 ProcessCommandLine(
03273 IN
03274
PCOOKED_READ_DATA CookedReadData,
03275 IN WCHAR Char,
03276 IN DWORD KeyState,
03277 IN PCSR_API_MSG WaitReplyMessage,
03278 IN PCSR_THREAD WaitingThread,
03279 IN BOOLEAN WaitRoutine
03280 )
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294 {
03295 COORD CurrentPosition;
03296
DWORD CharsToWrite;
03297
NTSTATUS Status;
03298
BOOL UpdateCursorPosition;
03299
SHORT ScrollY=0;
03300
BOOL fStartFromDelim;
03301
03302 UpdateCursorPosition =
FALSE;
03303
if (Char == VK_F7 &&
03304 !(KeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))) {
03305 COORD PopupSize;
03306
03307
if (CookedReadData->CommandHistory &&
03308 CookedReadData->CommandHistory->NumberOfCommands) {
03309 PopupSize.X = 40;
03310 PopupSize.Y = 10;
03311
Status =
BeginPopup(CookedReadData->ScreenInfo,
03312 CookedReadData->CommandHistory,
03313 PopupSize
03314 );
03315
if (
NT_SUCCESS(
Status)) {
03316
03317
return CommandListPopup(CookedReadData,
03318 WaitReplyMessage,
03319 WaitingThread,
03320 WaitRoutine
03321 );
03322 }
03323 }
03324 }
else {
03325
switch (Char) {
03326
case VK_ESCAPE:
03327
DeleteCommandLine(CookedReadData,
03328
TRUE);
03329
break;
03330
case VK_UP:
03331
case VK_DOWN:
03332
case VK_F5:
03333
if (Char == VK_F5)
03334 Char = VK_UP;
03335
03336
if (Char==VK_UP && !
AtFirstCommand(CookedReadData->CommandHistory) ||
03337 Char==VK_DOWN && !
AtLastCommand(CookedReadData->CommandHistory)) {
03338
DeleteCommandLine(CookedReadData,
03339
TRUE);
03340
Status =
RetrieveCommand(CookedReadData->CommandHistory,
03341 Char,
03342 CookedReadData->BackupLimit,
03343 CookedReadData->BufferSize,
03344 &CookedReadData->BytesRead);
03345
ASSERT(CookedReadData->BackupLimit == CookedReadData->BufPtr);
03346
if (CookedReadData->Echo) {
03347
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
03348 CookedReadData->BackupLimit,
03349 CookedReadData->BufPtr,
03350 CookedReadData->BufPtr,
03351 &CookedReadData->BytesRead,
03352 (PLONG)&CookedReadData->NumberOfVisibleChars,
03353 CookedReadData->OriginalCursorPosition.X,
03354
WC_DESTRUCTIVE_BACKSPACE |
03355
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
03356 &ScrollY );
03357
ASSERT(
NT_SUCCESS(
Status));
03358 CookedReadData->OriginalCursorPosition.Y += ScrollY;
03359 }
03360 CharsToWrite = CookedReadData->BytesRead/
sizeof(WCHAR);
03361 CookedReadData->CurrentPosition = CharsToWrite;
03362 CookedReadData->BufPtr = CookedReadData->BackupLimit + CharsToWrite;
03363 }
03364
break;
03365
case VK_PRIOR:
03366
case VK_NEXT:
03367
if (CookedReadData->CommandHistory &&
03368 CookedReadData->CommandHistory->NumberOfCommands) {
03369
03370
03371
03372
03373
03374
SHORT CommandNumber;
03375
if (Char == VK_PRIOR) {
03376 CommandNumber = 0;
03377 }
else {
03378 CommandNumber = (
SHORT)(CookedReadData->CommandHistory->NumberOfCommands-1);
03379 }
03380
DeleteCommandLine(CookedReadData,
03381
TRUE);
03382
Status =
RetrieveNthCommand(CookedReadData->CommandHistory,
03383
COMMAND_NUM_TO_INDEX(CommandNumber,CookedReadData->CommandHistory),
03384 CookedReadData->BackupLimit,
03385 CookedReadData->BufferSize,
03386 &CookedReadData->BytesRead);
03387
ASSERT(CookedReadData->BackupLimit == CookedReadData->BufPtr);
03388
if (CookedReadData->Echo) {
03389
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
03390 CookedReadData->BackupLimit,
03391 CookedReadData->BufPtr,
03392 CookedReadData->BufPtr,
03393 &CookedReadData->BytesRead,
03394 (PLONG)&CookedReadData->NumberOfVisibleChars,
03395 CookedReadData->OriginalCursorPosition.X,
03396
WC_DESTRUCTIVE_BACKSPACE |
03397
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
03398 &ScrollY
03399 );
03400
ASSERT(
NT_SUCCESS(
Status));
03401 CookedReadData->OriginalCursorPosition.Y += ScrollY;
03402 }
03403 CharsToWrite = CookedReadData->BytesRead/
sizeof(WCHAR);
03404 CookedReadData->CurrentPosition = CharsToWrite;
03405 CookedReadData->BufPtr = CookedReadData->BackupLimit + CharsToWrite;
03406 }
03407
break;
03408
case VK_END:
03409
if (KeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) {
03410
DeleteCommandLine(CookedReadData,
03411
FALSE);
03412 CookedReadData->BytesRead = CookedReadData->CurrentPosition*
sizeof(WCHAR);
03413
if (CookedReadData->Echo) {
03414
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
03415 CookedReadData->BackupLimit,
03416 CookedReadData->BackupLimit,
03417 CookedReadData->BackupLimit,
03418 &CookedReadData->BytesRead,
03419 (PLONG)&CookedReadData->NumberOfVisibleChars,
03420 CookedReadData->OriginalCursorPosition.X,
03421
WC_DESTRUCTIVE_BACKSPACE |
03422
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
03423
NULL
03424 );
03425
ASSERT(
NT_SUCCESS(
Status));
03426 }
03427 }
else {
03428 CookedReadData->CurrentPosition = CookedReadData->BytesRead/
sizeof(WCHAR);
03429 CookedReadData->BufPtr = CookedReadData->BackupLimit + CookedReadData->CurrentPosition;
03430 CurrentPosition.X = (
SHORT)(CookedReadData->OriginalCursorPosition.X + CookedReadData->NumberOfVisibleChars);
03431 CurrentPosition.Y = CookedReadData->OriginalCursorPosition.Y;
03432
#if defined(FE_SB)
03433
if (CheckBisectProcessW(CookedReadData->ScreenInfo,
03434 CookedReadData->ScreenInfo->Console->CP,
03435 CookedReadData->BackupLimit,
03436 CookedReadData->CurrentPosition,
03437 CookedReadData->ScreenInfo->ScreenBufferSize.X-CookedReadData->OriginalCursorPosition.X,
03438 CookedReadData->OriginalCursorPosition.X,
03439
TRUE)) {
03440 CurrentPosition.X++;
03441 }
03442
#endif
03443
UpdateCursorPosition =
TRUE;
03444 }
03445
break;
03446
case VK_HOME:
03447
if (KeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) {
03448
DeleteCommandLine(CookedReadData,
03449
FALSE);
03450 CookedReadData->BytesRead -= CookedReadData->CurrentPosition*
sizeof(WCHAR);
03451 CookedReadData->CurrentPosition = 0;
03452 RtlCopyMemory(CookedReadData->BackupLimit,
03453 CookedReadData->BufPtr,
03454 CookedReadData->BytesRead
03455 );
03456 CookedReadData->BufPtr = CookedReadData->BackupLimit;
03457
if (CookedReadData->Echo) {
03458
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
03459 CookedReadData->BackupLimit,
03460 CookedReadData->BackupLimit,
03461 CookedReadData->BackupLimit,
03462 &CookedReadData->BytesRead,
03463 (PLONG)&CookedReadData->NumberOfVisibleChars,
03464 CookedReadData->OriginalCursorPosition.X,
03465
WC_DESTRUCTIVE_BACKSPACE |
03466
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
03467
NULL
03468 );
03469
ASSERT(
NT_SUCCESS(
Status));
03470 }
03471 CurrentPosition = CookedReadData->OriginalCursorPosition;
03472 UpdateCursorPosition =
TRUE;
03473 }
else {
03474 CookedReadData->CurrentPosition = 0;
03475 CookedReadData->BufPtr = CookedReadData->BackupLimit;
03476 CurrentPosition = CookedReadData->OriginalCursorPosition;
03477 UpdateCursorPosition =
TRUE;
03478 }
03479
break;
03480
case VK_LEFT:
03481
if (KeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) {
03482 PWCHAR LastWord;
03483
BOOL NonSpaceCharSeen=
FALSE;
03484
if (CookedReadData->BufPtr != CookedReadData->BackupLimit) {
03485 LastWord = CookedReadData->BufPtr-1;
03486
while (LastWord != CookedReadData->BackupLimit) {
03487
if (!
IS_WORD_DELIM(*LastWord))
03488 NonSpaceCharSeen=
TRUE;
03489
else
03490
if (NonSpaceCharSeen)
03491
break;
03492 LastWord--;
03493 }
03494
if (LastWord != CookedReadData->BackupLimit) {
03495 CookedReadData->BufPtr = LastWord+1;
03496 }
else {
03497 CookedReadData->BufPtr = LastWord;
03498 }
03499 CookedReadData->CurrentPosition=(ULONG)(CookedReadData->BufPtr-CookedReadData->BackupLimit);
03500 CurrentPosition = CookedReadData->OriginalCursorPosition;
03501
#if defined(FE_SB)
03502
CurrentPosition.X = (
SHORT)(CurrentPosition.X +
03503
RetrieveTotalNumberOfSpaces(CookedReadData->OriginalCursorPosition.X,
03504 CookedReadData->BackupLimit,
03505 CookedReadData->CurrentPosition,
03506 CookedReadData->ScreenInfo->Console));
03507
if (CheckBisectStringW(CookedReadData->ScreenInfo,
03508 CookedReadData->ScreenInfo->Console->CP,
03509 CookedReadData->BackupLimit,
03510 CookedReadData->CurrentPosition+1,
03511 CookedReadData->ScreenInfo->ScreenBufferSize.X
03512 -CookedReadData->OriginalCursorPosition.X
03513 )) {
03514 CurrentPosition.X++;
03515 }
03516
#else
03517
CurrentPosition.X = (
SHORT)(CurrentPosition.X +
RetrieveTotalNumberOfSpaces(CookedReadData->OriginalCursorPosition.X,
03518 CookedReadData->BackupLimit,
03519 CookedReadData->CurrentPosition));
03520
#endif
03521
UpdateCursorPosition =
TRUE;
03522 }
03523 }
else {
03524
if (CookedReadData->BufPtr != CookedReadData->BackupLimit) {
03525 CookedReadData->BufPtr--;
03526 CookedReadData->CurrentPosition--;
03527 CurrentPosition.X = CookedReadData->ScreenInfo->BufferInfo.TextInfo.CursorPosition.X;
03528 CurrentPosition.Y = CookedReadData->ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y;
03529
#if defined(FE_SB)
03530
CurrentPosition.X = (
SHORT)(CurrentPosition.X -
03531
RetrieveNumberOfSpaces(CookedReadData->OriginalCursorPosition.X,
03532 CookedReadData->BackupLimit,
03533 CookedReadData->CurrentPosition,
03534 CookedReadData->ScreenInfo->Console,
03535 CookedReadData->ScreenInfo->Console->CP));
03536
if (CheckBisectProcessW(CookedReadData->ScreenInfo,
03537 CookedReadData->ScreenInfo->Console->CP,
03538 CookedReadData->BackupLimit,
03539 CookedReadData->CurrentPosition+2,
03540 CookedReadData->ScreenInfo->ScreenBufferSize.X
03541 -CookedReadData->OriginalCursorPosition.X,
03542 CookedReadData->OriginalCursorPosition.X,
03543
TRUE)) {
03544
if ((CurrentPosition.X == -2) ||
03545 (CurrentPosition.X == -1)) {
03546 CurrentPosition.X--;
03547 }
03548 }
03549
#else
03550
CurrentPosition.X = (
SHORT)(CurrentPosition.X -
RetrieveNumberOfSpaces(CookedReadData->OriginalCursorPosition.X,
03551 CookedReadData->BackupLimit,
03552 CookedReadData->CurrentPosition));
03553
#endif
03554
UpdateCursorPosition =
TRUE;
03555 }
03556 }
03557
break;
03558
case VK_RIGHT:
03559
case VK_F1:
03560
03561
03562
03563
03564
03565
03566
if (KeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) {
03567
if (Char != VK_F1) {
03568 PWCHAR NextWord;
03569
SHORT i;
03570
if (CookedReadData->CurrentPosition < (CookedReadData->BytesRead/
sizeof(WCHAR))) {
03571 NextWord = CookedReadData->BufPtr;
03572
for (i=(
SHORT)(CookedReadData->CurrentPosition);
03573 i<(
SHORT)((CookedReadData->BytesRead-1)/
sizeof(WCHAR));
03574 i++) {
03575
if (
IS_WORD_DELIM(*NextWord)) {
03576 i++;
03577 NextWord++;
03578
while ((i<(
SHORT)((CookedReadData->BytesRead-1)/
sizeof(WCHAR))) &&
03579
IS_WORD_DELIM(*NextWord)) {
03580 i++;
03581 NextWord++;
03582 }
03583
break;
03584 }
03585 NextWord++;
03586 }
03587 CookedReadData->BufPtr = NextWord;
03588 CookedReadData->CurrentPosition=(ULONG)(CookedReadData->BufPtr-CookedReadData->BackupLimit);
03589
#if defined(FE_SB)
03590
CurrentPosition = CookedReadData->OriginalCursorPosition;
03591 CurrentPosition.X = (
SHORT)(CurrentPosition.X +
03592
RetrieveTotalNumberOfSpaces(CookedReadData->OriginalCursorPosition.X,
03593 CookedReadData->BackupLimit,
03594 CookedReadData->CurrentPosition,
03595 CookedReadData->ScreenInfo->Console));
03596
if (CheckBisectStringW(CookedReadData->ScreenInfo,
03597 CookedReadData->ScreenInfo->Console->CP,
03598 CookedReadData->BackupLimit,
03599 CookedReadData->CurrentPosition+1,
03600 CookedReadData->ScreenInfo->ScreenBufferSize.X
03601 -CookedReadData->OriginalCursorPosition.X
03602 )) {
03603 CurrentPosition.X++;
03604 }
03605
#else
03606
CurrentPosition = CookedReadData->OriginalCursorPosition;
03607 CurrentPosition.X = (
SHORT)(CurrentPosition.X +
RetrieveTotalNumberOfSpaces(CookedReadData->OriginalCursorPosition.X,
03608 CookedReadData->BackupLimit,
03609 CookedReadData->CurrentPosition));
03610
#endif
03611
UpdateCursorPosition =
TRUE;
03612 }
03613 }
03614 }
else {
03615
03616
03617
03618
03619
03620
if (CookedReadData->CurrentPosition < (CookedReadData->BytesRead/
sizeof(WCHAR))) {
03621 CurrentPosition = CookedReadData->ScreenInfo->BufferInfo.TextInfo.CursorPosition;
03622
#if defined(FE_SB)
03623
CurrentPosition.X = (
SHORT)(CurrentPosition.X +
03624
RetrieveNumberOfSpaces(CookedReadData->OriginalCursorPosition.X,
03625 CookedReadData->BackupLimit,
03626 CookedReadData->CurrentPosition,
03627 CookedReadData->ScreenInfo->Console,
03628 CookedReadData->ScreenInfo->Console->CP));
03629
if (CheckBisectProcessW(CookedReadData->ScreenInfo,
03630 CookedReadData->ScreenInfo->Console->CP,
03631 CookedReadData->BackupLimit,
03632 CookedReadData->CurrentPosition+2,
03633 CookedReadData->ScreenInfo->ScreenBufferSize.X
03634 -CookedReadData->OriginalCursorPosition.X,
03635 CookedReadData->OriginalCursorPosition.X,
03636
TRUE)) {
03637
if (CurrentPosition.X == (CookedReadData->ScreenInfo->ScreenBufferSize.X-1))
03638 CurrentPosition.X++;
03639 }
03640
#else
03641
CurrentPosition.X = (
SHORT)(CurrentPosition.X +
RetrieveNumberOfSpaces(CookedReadData->OriginalCursorPosition.X,
03642 CookedReadData->BackupLimit,
03643 CookedReadData->CurrentPosition));
03644
#endif
03645
CookedReadData->BufPtr++;
03646 CookedReadData->CurrentPosition++;
03647 UpdateCursorPosition =
TRUE;
03648
03649
03650
03651
03652
03653
03654 }
else if (CookedReadData->CommandHistory) {
03655
PCOMMAND LastCommand;
03656
DWORD NumSpaces;
03657 LastCommand =
GetLastCommand(CookedReadData->CommandHistory);
03658
if (LastCommand && (
USHORT)(LastCommand->
CommandLength/
sizeof(WCHAR)) > (
USHORT)CookedReadData->CurrentPosition) {
03659 *CookedReadData->BufPtr = LastCommand->
Command[CookedReadData->CurrentPosition];
03660 CookedReadData->BytesRead +=
sizeof(WCHAR);
03661 CookedReadData->CurrentPosition++;
03662
if (CookedReadData->Echo) {
03663 CharsToWrite =
sizeof(WCHAR);
03664
Status =
WriteCharsFromInput(
03665 CookedReadData->ScreenInfo,
03666 CookedReadData->BackupLimit,
03667 CookedReadData->BufPtr,
03668 CookedReadData->BufPtr,
03669 &CharsToWrite,
03670 (PLONG)&NumSpaces,
03671 CookedReadData->OriginalCursorPosition.X,
03672
WC_DESTRUCTIVE_BACKSPACE |
03673
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
03674 &ScrollY);
03675
ASSERT(
NT_SUCCESS(
Status));
03676 CookedReadData->OriginalCursorPosition.Y += ScrollY;
03677 CookedReadData->NumberOfVisibleChars += NumSpaces;
03678 }
03679 CookedReadData->BufPtr+=1;
03680 }
03681 }
03682 }
03683
break;
03684
case VK_F2:
03685
03686
03687
03688
03689
03690
03691
03692
if (CookedReadData->CommandHistory) {
03693 COORD PopupSize;
03694
03695 PopupSize.X =
COPY_TO_CHAR_PROMPT_LENGTH+2;
03696 PopupSize.Y = 1;
03697
Status =
BeginPopup(CookedReadData->ScreenInfo,
03698 CookedReadData->CommandHistory,
03699 PopupSize
03700 );
03701
if (
NT_SUCCESS(
Status)) {
03702
03703
return CopyToCharPopup(CookedReadData,
03704 WaitReplyMessage,
03705 WaitingThread,
03706 WaitRoutine
03707 );
03708 }
03709 }
03710
break;
03711
case VK_F3:
03712
03713
03714
03715
03716
03717
if (CookedReadData->CommandHistory) {
03718
PCOMMAND LastCommand;
03719
DWORD NumSpaces;
03720
int j;
03721 LastCommand =
GetLastCommand(CookedReadData->CommandHistory);
03722
if (LastCommand && (
USHORT)(LastCommand->
CommandLength/
sizeof(WCHAR)) > (
USHORT)CookedReadData->CurrentPosition) {
03723 j = (LastCommand->
CommandLength/
sizeof(WCHAR)) - CookedReadData->CurrentPosition;
03724 RtlCopyMemory(CookedReadData->BufPtr,
03725 &LastCommand->
Command[CookedReadData->CurrentPosition],
03726 j*
sizeof(WCHAR)
03727 );
03728 CookedReadData->CurrentPosition += j;
03729 j *=
sizeof(WCHAR);
03730 CookedReadData->BytesRead += j;
03731
if (CookedReadData->Echo) {
03732
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
03733 CookedReadData->BackupLimit,
03734 CookedReadData->BufPtr,
03735 CookedReadData->BufPtr,
03736 (PDWORD) &j,
03737 (PLONG)&NumSpaces,
03738 CookedReadData->OriginalCursorPosition.X,
03739
WC_DESTRUCTIVE_BACKSPACE |
03740
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
03741 &ScrollY);
03742
ASSERT(
NT_SUCCESS(
Status));
03743 CookedReadData->OriginalCursorPosition.Y += ScrollY;
03744 CookedReadData->NumberOfVisibleChars += NumSpaces;
03745 }
03746 CookedReadData->BufPtr+=j/
sizeof(WCHAR);
03747 }
03748 }
03749
break;
03750
case VK_F4:
03751
03752
03753
03754
03755
03756
03757
03758
if (CookedReadData->CommandHistory) {
03759 COORD PopupSize;
03760
03761 PopupSize.X =
COPY_FROM_CHAR_PROMPT_LENGTH+2;
03762 PopupSize.Y = 1;
03763
Status =
BeginPopup(CookedReadData->ScreenInfo,
03764 CookedReadData->CommandHistory,
03765 PopupSize
03766 );
03767
if (
NT_SUCCESS(
Status)) {
03768
03769
return CopyFromCharPopup(CookedReadData,
03770 WaitReplyMessage,
03771 WaitingThread,
03772 WaitRoutine
03773 );
03774 }
03775 }
03776
break;
03777
case VK_F6:
03778
03779
03780
03781
03782
03783 {
03784
DWORD NumSpaces;
03785 *CookedReadData->BufPtr = (WCHAR)0x1a;
03786 CookedReadData->BytesRead +=
sizeof(WCHAR);
03787 CookedReadData->CurrentPosition++;
03788
if (CookedReadData->Echo) {
03789 CharsToWrite =
sizeof(WCHAR);
03790
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
03791 CookedReadData->BackupLimit,
03792 CookedReadData->BufPtr,
03793 CookedReadData->BufPtr,
03794 &CharsToWrite,
03795 (PLONG)&NumSpaces,
03796 CookedReadData->OriginalCursorPosition.X,
03797
WC_DESTRUCTIVE_BACKSPACE |
03798
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
03799 &ScrollY
03800 );
03801
ASSERT(
NT_SUCCESS(
Status));
03802 CookedReadData->OriginalCursorPosition.Y += ScrollY;
03803 CookedReadData->NumberOfVisibleChars += NumSpaces;
03804 }
03805 CookedReadData->BufPtr+=1;
03806 }
03807
break;
03808
case VK_F7:
03809
if (KeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) {
03810
EmptyCommandHistory(CookedReadData->CommandHistory);
03811 CookedReadData->CommandHistory->Flags |=
CLE_ALLOCATED;
03812 }
03813
break;
03814
case VK_F8:
03815
if (CookedReadData->CommandHistory) {
03816
SHORT i;
03817
03818
03819
03820
03821
03822
03823 i =
FindMatchingCommand(CookedReadData->CommandHistory,
03824 CookedReadData->BackupLimit,
03825 CookedReadData->CurrentPosition*
sizeof(WCHAR),
03826 CookedReadData->CommandHistory->LastDisplayed, 0);
03827
if (i!=-1) {
03828
SHORT CurrentPosition;
03829 COORD CursorPosition;
03830
03831
03832
03833
03834
03835 CurrentPosition = (
SHORT)CookedReadData->CurrentPosition;
03836 CursorPosition = CookedReadData->ScreenInfo->BufferInfo.TextInfo.CursorPosition;
03837
03838
DeleteCommandLine(CookedReadData,
03839
TRUE);
03840
Status =
RetrieveNthCommand(CookedReadData->CommandHistory,
03841 i,
03842 CookedReadData->BackupLimit,
03843 CookedReadData->BufferSize,
03844 &CookedReadData->BytesRead);
03845
ASSERT(CookedReadData->BackupLimit == CookedReadData->BufPtr);
03846
if (CookedReadData->Echo) {
03847
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
03848 CookedReadData->BackupLimit,
03849 CookedReadData->BufPtr,
03850 CookedReadData->BufPtr,
03851 &CookedReadData->BytesRead,
03852 (PLONG)&CookedReadData->NumberOfVisibleChars,
03853 CookedReadData->OriginalCursorPosition.X,
03854
WC_DESTRUCTIVE_BACKSPACE |
03855
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
03856 &ScrollY);
03857
ASSERT(
NT_SUCCESS(
Status));
03858 CookedReadData->OriginalCursorPosition.Y += ScrollY;
03859 }
03860 CursorPosition.Y += ScrollY;
03861
03862
03863
03864
03865
03866 CookedReadData->BufPtr = CookedReadData->BackupLimit + CurrentPosition;
03867 CookedReadData->CurrentPosition = CurrentPosition;
03868
Status =
SetCursorPosition(CookedReadData->ScreenInfo,
03869 CursorPosition,
03870
TRUE
03871 );
03872
ASSERT(
NT_SUCCESS(
Status));
03873 }
03874 }
03875
break;
03876
case VK_F9:
03877
03878
03879
03880
03881
03882
03883 {
03884 COORD PopupSize;
03885
03886
if (CookedReadData->CommandHistory &&
03887 CookedReadData->CommandHistory->NumberOfCommands &&
03888 CookedReadData->ScreenInfo->ScreenBufferSize.X >=
MINIMUM_COMMAND_PROMPT_SIZE+2) {
03889 PopupSize.X =
COMMAND_NUMBER_PROMPT_LENGTH+
COMMAND_NUMBER_LENGTH;
03890 PopupSize.Y = 1;
03891
Status =
BeginPopup(CookedReadData->ScreenInfo,
03892 CookedReadData->CommandHistory,
03893 PopupSize
03894 );
03895
if (
NT_SUCCESS(
Status)) {
03896
03897
return CommandNumberPopup(CookedReadData,
03898 WaitReplyMessage,
03899 WaitingThread,
03900 WaitRoutine
03901 );
03902 }
03903 }
03904 }
03905
break;
03906
case VK_F10:
03907
if (KeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) {
03908
ClearAliases(CookedReadData->Console);
03909 }
03910
break;
03911
case VK_INSERT:
03912 CookedReadData->InsertMode = !CookedReadData->InsertMode;
03913
SetCursorMode(CookedReadData->ScreenInfo,
03914 (BOOLEAN)(CookedReadData->InsertMode != CookedReadData->Console->InsertMode));
03915
break;
03916
case VK_DELETE:
03917
if (!
AT_EOL(CookedReadData)) {
03918 COORD CursorPosition;
03919
03920 fStartFromDelim =
IS_WORD_DELIM(*CookedReadData->BufPtr);
03921
03922 del_repeat:
03923
03924
03925
03926
03927 CursorPosition = CookedReadData->ScreenInfo->BufferInfo.TextInfo.CursorPosition;
03928
03929
03930
03931
03932
03933
DeleteCommandLine(CookedReadData,
03934
FALSE);
03935
03936
03937
03938
03939 CookedReadData->BytesRead -=
sizeof(WCHAR);
03940 RtlCopyMemory(CookedReadData->BufPtr,
03941 CookedReadData->BufPtr+1,
03942 CookedReadData->BytesRead - (CookedReadData->CurrentPosition*
sizeof(WCHAR))
03943 );
03944
03945
#if defined(FE_SB)
03946
{
03947 PWCHAR buf = (PWCHAR)((
PBYTE)CookedReadData->BackupLimit +
03948 CookedReadData->BytesRead );
03949 *buf = (WCHAR)
' ';
03950 }
03951
#endif
03952
03953
03954
03955
03956
if (CookedReadData->Echo) {
03957
Status =
WriteCharsFromInput(CookedReadData->ScreenInfo,
03958 CookedReadData->BackupLimit,
03959 CookedReadData->BackupLimit,
03960 CookedReadData->BackupLimit,
03961 &CookedReadData->BytesRead,
03962 (PLONG)&CookedReadData->NumberOfVisibleChars,
03963 CookedReadData->OriginalCursorPosition.X,
03964
WC_DESTRUCTIVE_BACKSPACE |
03965
WC_KEEP_CURSOR_VISIBLE |
WC_ECHO,
03966
NULL);
03967
ASSERT(
NT_SUCCESS(
Status));
03968 }
03969
03970
03971
03972
03973
03974
if (
CONSOLE_IS_DBCS_ENABLED() && CONSOLE_IS_DBCS_CP(CookedReadData->Console)) {
03975
if (CheckBisectProcessW(CookedReadData->ScreenInfo,
03976 CookedReadData->ScreenInfo->Console->CP,
03977 CookedReadData->BackupLimit,
03978 CookedReadData->CurrentPosition+1,
03979 CookedReadData->ScreenInfo->ScreenBufferSize.X
03980 -CookedReadData->OriginalCursorPosition.X,
03981 CookedReadData->OriginalCursorPosition.X,
03982
TRUE)) {
03983 CursorPosition.X++;
03984 }
03985 CurrentPosition = CursorPosition;
03986
if (CookedReadData->Echo) {
03987
Status =
AdjustCursorPosition(CookedReadData->ScreenInfo,
03988 CurrentPosition,
03989
TRUE,
03990
NULL);
03991
ASSERT(
NT_SUCCESS(
Status));
03992 }
03993 }
03994
else {
03995
Status =
SetCursorPosition(CookedReadData->ScreenInfo,
03996 CursorPosition,
03997
TRUE
03998 );
03999
ASSERT(
NT_SUCCESS(
Status));
04000 }
04001
04002
04003
04004
if ((KeyState &
CTRL_PRESSED) && !
AT_EOL(CookedReadData) &&
04005 fStartFromDelim ^ !
IS_WORD_DELIM(*CookedReadData->BufPtr)) {
04006
DBGPRINT((
"Repeating it(%x).\n", *CookedReadData->BufPtr));
04007
goto del_repeat;
04008 }
04009 }
04010
break;
04011
default:
04012
ASSERT(
FALSE);
04013
break;
04014 }
04015 }
04016
if (UpdateCursorPosition && CookedReadData->Echo) {
04017
Status =
AdjustCursorPosition(CookedReadData->ScreenInfo,
04018 CurrentPosition,
04019
TRUE,
04020
NULL);
04021
ASSERT(
NT_SUCCESS(
Status));
04022 }
04023
return STATUS_SUCCESS;
04024 }
04025
04026 PCOMMAND RemoveCommand(
04027 IN
PCOMMAND_HISTORY CommandHistory,
04028 IN SHORT iDel)
04029 {
04030
SHORT iFirst, iLast, iDisp, nDel;
04031
PCOMMAND *ppcFirst, *ppcDel, pcmdDel;
04032
04033 iFirst = CommandHistory->FirstCommand;
04034 iLast = CommandHistory->LastAdded;
04035 iDisp = CommandHistory->LastDisplayed;
04036
04037
if (CommandHistory->NumberOfCommands == 0) {
04038
return NULL;
04039 }
04040
04041 nDel =
COMMAND_INDEX_TO_NUM(iDel, CommandHistory);
04042
if ((nDel <
COMMAND_INDEX_TO_NUM(iFirst, CommandHistory)) ||
04043 (nDel >
COMMAND_INDEX_TO_NUM(iLast, CommandHistory))) {
04044
return NULL;
04045 }
04046
04047
if (iDisp == iDel) {
04048 CommandHistory->LastDisplayed = -1;
04049 }
04050
04051 ppcFirst = &(CommandHistory->Commands[iFirst]);
04052 ppcDel = &(CommandHistory->Commands[iDel]);
04053 pcmdDel = *ppcDel;
04054
04055
if (iDel < iLast) {
04056 RtlCopyMemory(ppcDel, ppcDel+1, (iLast - iDel) *
sizeof(
PCOMMAND));
04057
if ((iDisp > iDel) && (iDisp <= iLast)) {
04058
COMMAND_IND_DEC(iDisp, CommandHistory);
04059 }
04060
COMMAND_IND_DEC(iLast, CommandHistory);
04061 }
else if (iFirst <= iDel) {
04062 RtlMoveMemory(ppcFirst+1, ppcFirst, (iDel - iFirst) *
sizeof(
PCOMMAND));
04063
if ((iDisp >= iFirst) && (iDisp < iDel)) {
04064
COMMAND_IND_INC(iDisp, CommandHistory);
04065 }
04066
COMMAND_IND_INC(iFirst, CommandHistory);
04067 }
04068
04069 CommandHistory->FirstCommand = iFirst;
04070 CommandHistory->LastAdded = iLast;
04071 CommandHistory->LastDisplayed = iDisp;
04072 CommandHistory->NumberOfCommands--;
04073
return pcmdDel;
04074 }
04075
04076
04077
SHORT
04078 FindMatchingCommand(
04079 IN
PCOMMAND_HISTORY CommandHistory,
04080 IN PWCHAR pwszIn,
04081 IN ULONG cbIn,
04082 IN SHORT CommandIndex,
04083 IN DWORD Flags
04084 )
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094 {
04095
SHORT i;
04096
04097
if (CommandHistory->NumberOfCommands == 0) {
04098
return -1;
04099 }
04100
if (!(Flags &
FMCFL_JUST_LOOKING) && (CommandHistory->Flags &
CLE_RESET)) {
04101 CommandHistory->Flags &= ~
CLE_RESET;
04102 }
else {
04103
COMMAND_IND_PREV(CommandIndex, CommandHistory);
04104 }
04105
if (cbIn == 0) {
04106
return CommandIndex;
04107 }
04108
for (i=0;i<CommandHistory->NumberOfCommands;i++) {
04109
PCOMMAND pcmdT = CommandHistory->Commands[CommandIndex];
04110
04111
if ((!(Flags &
FMCFL_EXACT_MATCH) && (cbIn <= pcmdT->
CommandLength)) ||
04112 ((
USHORT)cbIn == pcmdT->
CommandLength)) {
04113
if (!
my_wcsncmp(pcmdT->
Command, pwszIn, (
USHORT)cbIn)) {
04114
return CommandIndex;
04115 }
04116 }
04117
COMMAND_IND_PREV(CommandIndex, CommandHistory);
04118 }
04119
return -1;
04120 }
04121
04122
VOID
04123 DrawCommandListBorder(
04124 IN
PCLE_POPUP Popup,
04125 IN
PSCREEN_INFORMATION ScreenInfo
04126 )
04127 {
04128 COORD WriteCoord;
04129 ULONG Length;
04130
SHORT i;
04131
04132
04133
04134
04135 WriteCoord.X = Popup->Region.Left;
04136 WriteCoord.Y = Popup->Region.Top;
04137 Length =
POPUP_SIZE_X(Popup) + 2;
04138
FillOutput(ScreenInfo,
04139 Popup->Attributes,
04140 WriteCoord,
04141
CONSOLE_ATTRIBUTE,
04142 &Length
04143 );
04144
04145
04146
04147 Length = 1;
04148
FillOutput(ScreenInfo,
04149 #
if defined(FE_SB)
04150 ScreenInfo->LineChar[UPPER_LEFT_CORNER],
04151 #
else
04152 (WCHAR)0x250c,
04153 #endif
04154 WriteCoord,
04155
CONSOLE_REAL_UNICODE,
04156 &Length
04157 );
04158
04159
04160
04161
04162
04163 WriteCoord.X += 1;
04164 Length =
POPUP_SIZE_X(Popup);
04165
FillOutput(ScreenInfo,
04166 #
if defined(FE_SB)
04167 ScreenInfo->LineChar[HORIZONTAL_LINE],
04168 #
else
04169 (WCHAR)0x2500,
04170 #endif
04171 WriteCoord,
04172
CONSOLE_REAL_UNICODE,
04173 &Length
04174 );
04175
04176
04177
04178
04179
04180 WriteCoord.X = Popup->Region.Right;
04181 Length = 1;
04182
FillOutput(ScreenInfo,
04183 #
if defined(FE_SB)
04184 ScreenInfo->LineChar[UPPER_RIGHT_CORNER],
04185 #
else
04186 (WCHAR)0x2510,
04187 #endif
04188 WriteCoord,
04189
CONSOLE_REAL_UNICODE,
04190 &Length
04191 );
04192
04193
for (i=0;i<
POPUP_SIZE_Y(Popup);i++) {
04194 WriteCoord.Y += 1;
04195 WriteCoord.X = Popup->Region.Left;
04196
04197
04198
04199
04200
04201 Length =
POPUP_SIZE_X(Popup) + 2;
04202
FillOutput(ScreenInfo,
04203 Popup->Attributes,
04204 WriteCoord,
04205
CONSOLE_ATTRIBUTE,
04206 &Length
04207 );
04208 Length = 1;
04209
FillOutput(ScreenInfo,
04210 #
if defined(FE_SB)
04211 ScreenInfo->LineChar[VERTICAL_LINE],
04212 #
else
04213 (WCHAR)0x2502,
04214 #endif
04215 WriteCoord,
04216
CONSOLE_REAL_UNICODE,
04217 &Length
04218 );
04219 WriteCoord.X = Popup->Region.Right;
04220 Length = 1;
04221
FillOutput(ScreenInfo,
04222 #
if defined(FE_SB)
04223 ScreenInfo->LineChar[VERTICAL_LINE],
04224 #
else
04225 (WCHAR)0x2502,
04226 #endif
04227 WriteCoord,
04228
CONSOLE_REAL_UNICODE,
04229 &Length
04230 );
04231 }
04232
04233
04234
04235
04236
04237
04238
04239 WriteCoord.X = Popup->Region.Left;
04240 WriteCoord.Y = Popup->Region.Bottom;
04241 Length =
POPUP_SIZE_X(Popup) + 2;
04242
FillOutput(ScreenInfo,
04243 Popup->Attributes,
04244 WriteCoord,
04245
CONSOLE_ATTRIBUTE,
04246 &Length
04247 );
04248
04249
04250
04251
04252 Length = 1;
04253 WriteCoord.X = Popup->Region.Left;
04254
FillOutput(ScreenInfo,
04255 #
if defined(FE_SB)
04256 ScreenInfo->LineChar[BOTTOM_LEFT_CORNER],
04257 #
else
04258 (WCHAR)0x2514,
04259 #endif
04260 WriteCoord,
04261
CONSOLE_REAL_UNICODE,
04262 &Length
04263 );
04264
04265
04266
04267
04268
04269 WriteCoord.X += 1;
04270 Length =
POPUP_SIZE_X(Popup);
04271
FillOutput(ScreenInfo,
04272 #
if defined(FE_SB)
04273 ScreenInfo->LineChar[HORIZONTAL_LINE],
04274 #
else
04275 (WCHAR)0x2500,
04276 #endif
04277 WriteCoord,
04278
CONSOLE_REAL_UNICODE,
04279 &Length
04280 );
04281
04282
04283
04284
04285
04286 WriteCoord.X = Popup->Region.Right;
04287 Length = 1;
04288
FillOutput(ScreenInfo,
04289 #
if defined(FE_SB)
04290 ScreenInfo->LineChar[BOTTOM_RIGHT_CORNER],
04291 #
else
04292 (WCHAR)0x2518,
04293 #endif
04294 WriteCoord,
04295
CONSOLE_REAL_UNICODE,
04296 &Length
04297 );
04298 }
04299
04300
VOID
04301 UpdateHighlight(
04302 IN
PCLE_POPUP Popup,
04303 IN SHORT OldCurrentCommand,
04304 IN SHORT NewCurrentCommand,
04305 IN
PSCREEN_INFORMATION ScreenInfo
04306 )
04307 {
04308 COORD WriteCoord;
04309 ULONG lStringLength;
04310 WORD Attributes;
04311
SHORT TopIndex;
04312
04313
if (Popup->BottomIndex <
POPUP_SIZE_Y(Popup)) {
04314 TopIndex = 0;
04315 }
else {
04316 TopIndex = (
SHORT)(Popup->BottomIndex-
POPUP_SIZE_Y(Popup)+1);
04317 }
04318 WriteCoord.X = (
SHORT)(Popup->Region.Left+1);
04319 lStringLength =
POPUP_SIZE_X(Popup);
04320
04321 WriteCoord.Y = (
SHORT)(Popup->Region.Top+1+OldCurrentCommand-TopIndex);
04322
FillOutput(ScreenInfo,
04323 Popup->Attributes,
04324 WriteCoord,
04325
CONSOLE_ATTRIBUTE,
04326 &lStringLength
04327 );
04328
04329
04330
04331
04332
04333 WriteCoord.Y = (
SHORT)(Popup->Region.Top+1+NewCurrentCommand-TopIndex);
04334
04335 Attributes = (WORD)(((Popup->Attributes << 4) & 0xf0) |
04336 ((Popup->Attributes >> 4) & 0x0f));
04337
FillOutput(ScreenInfo,
04338 Attributes,
04339 WriteCoord,
04340
CONSOLE_ATTRIBUTE,
04341 &lStringLength
04342 );
04343 }
04344
04345
VOID
04346 DrawCommandListPopup(
04347 IN
PCLE_POPUP Popup,
04348 IN SHORT CurrentCommand,
04349 IN
PCOMMAND_HISTORY CommandHistory,
04350 IN
PSCREEN_INFORMATION ScreenInfo
04351 )
04352 {
04353 WORD Attributes;
04354 ULONG lStringLength,CommandNumberLength;
04355
CHAR CommandNumber[
COMMAND_NUMBER_SIZE];
04356 PCHAR CommandNumberPtr;
04357 COORD WriteCoord;
04358
SHORT i;
04359
04360
04361
04362
04363
04364 WriteCoord.X = (
SHORT)(Popup->Region.Left+1);
04365 WriteCoord.Y = (
SHORT)(Popup->Region.Top+1);
04366 lStringLength =
POPUP_SIZE_X(Popup);
04367
for (i=0;i<
POPUP_SIZE_Y(Popup);i++) {
04368
FillOutput(ScreenInfo,
04369 Popup->Attributes,
04370 WriteCoord,
04371
CONSOLE_ATTRIBUTE,
04372 &lStringLength
04373 );
04374
FillOutput(ScreenInfo,
04375 (WCHAR)
' ',
04376 WriteCoord,
04377
CONSOLE_FALSE_UNICODE,
04378 &lStringLength
04379 );
04380 WriteCoord.Y += 1;
04381 }
04382
04383 WriteCoord.Y = (
SHORT)(Popup->Region.Top+1);
04384
for (i=
max((
SHORT)(Popup->BottomIndex-
POPUP_SIZE_Y(Popup)+1),0);i<=Popup->BottomIndex;i++) {
04385
04386
04387
04388
04389
04390 CommandNumberPtr = _itoa(i,CommandNumber,10);
04391 CommandNumberLength = (
SHORT)lstrlenA(CommandNumberPtr);
04392 CommandNumber[CommandNumberLength] =
':';
04393 CommandNumber[CommandNumberLength+1] =
' ';
04394 CommandNumberLength+=2;
04395
if (CommandNumberLength > (ULONG)
POPUP_SIZE_X(Popup))
04396 CommandNumberLength = (ULONG)
POPUP_SIZE_X(Popup);
04397 WriteCoord.X = (
SHORT)(Popup->Region.Left+1);
04398
WriteOutputString(ScreenInfo,
04399 CommandNumberPtr,
04400 WriteCoord,
04401
CONSOLE_ASCII,
04402 &CommandNumberLength,
04403
NULL
04404 );
04405
04406
04407
04408
04409
04410 lStringLength = CommandHistory->Commands[
COMMAND_NUM_TO_INDEX(i,CommandHistory)]->CommandLength/
sizeof(WCHAR);
04411
#if defined(FE_SB)
04412
{
04413
DWORD lTmpStringLength;
04414 LONG lPopupLength;
04415 LPWSTR lpStr;
04416
04417 lTmpStringLength = lStringLength;
04418 lPopupLength =
POPUP_SIZE_X(Popup) - CommandNumberLength;
04419 lpStr = CommandHistory->Commands[
COMMAND_NUM_TO_INDEX(i,CommandHistory)]->Command;
04420
while (lTmpStringLength--) {
04421
if (IsConsoleFullWidth(ScreenInfo->Console->hDC,
04422 ScreenInfo->Console->OutputCP,*lpStr++)) {
04423 lPopupLength -= 2;
04424 }
04425
else {
04426 lPopupLength--;
04427 }
04428
if (lPopupLength <= 0) {
04429 lStringLength -= lTmpStringLength;
04430
if (lPopupLength < 0)
04431 lStringLength--;
04432
break;
04433 }
04434 }
04435 }
04436
#else
04437
if ((lStringLength+CommandNumberLength) > (ULONG)
POPUP_SIZE_X(Popup))
04438 lStringLength = (ULONG)(
POPUP_SIZE_X(Popup)-CommandNumberLength);
04439
#endif
04440
WriteCoord.X = (
SHORT)(WriteCoord.X + CommandNumberLength);
04441
#if defined(FE_SB)
04442
{
04443 PWCHAR TransBuffer;
04444
04445 TransBuffer =
ConsoleHeapAlloc(
MAKE_TAG( TMP_DBCS_TAG ),lStringLength *
sizeof(WCHAR));
04446
if (TransBuffer ==
NULL) {
04447
return;
04448 }
04449
04450 RtlCopyMemory(TransBuffer,CommandHistory->Commands[
COMMAND_NUM_TO_INDEX(i,CommandHistory)]->Command,lStringLength *
sizeof(WCHAR));
04451
WriteOutputString(ScreenInfo,
04452 TransBuffer,
04453 WriteCoord,
04454
CONSOLE_REAL_UNICODE,
04455 &lStringLength,
04456
NULL
04457 );
04458
ConsoleHeapFree(TransBuffer);
04459 }
04460
#else
04461
WriteOutputString(ScreenInfo,
04462 CommandHistory->Commands[
COMMAND_NUM_TO_INDEX(i,CommandHistory)]->Command,
04463 WriteCoord,
04464
CONSOLE_REAL_UNICODE,
04465 &lStringLength,
04466
NULL
04467 );
04468
04469
if ((ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY) &&
04470 !(ScreenInfo->Console->FullScreenFlags & CONSOLE_FULLSCREEN)) {
04471
FalseUnicodeToRealUnicode(CommandHistory->Commands[
COMMAND_NUM_TO_INDEX(i,CommandHistory)]->Command,
04472 lStringLength,
04473 ScreenInfo->Console->OutputCP);
04474 }
04475
#endif
04476
04477
04478
04479
04480
04481
if (
COMMAND_NUM_TO_INDEX(i,CommandHistory) == CurrentCommand) {
04482 WriteCoord.X = (
SHORT)(Popup->Region.Left+1);
04483
04484 Attributes = (WORD)(((Popup->Attributes << 4) & 0xf0) |
04485 ((Popup->Attributes >> 4) & 0x0f));
04486 lStringLength =
POPUP_SIZE_X(Popup);
04487
FillOutput(ScreenInfo,
04488 Attributes,
04489 WriteCoord,
04490
CONSOLE_ATTRIBUTE,
04491 &lStringLength
04492 );
04493 }
04494
04495 WriteCoord.Y += 1;
04496 }
04497 }
04498
04499
VOID
04500 UpdateCommandListPopup(
04501 IN SHORT Delta,
04502 IN OUT PSHORT CurrentCommand,
04503 IN
PCOMMAND_HISTORY CommandHistory,
04504 IN
PCLE_POPUP Popup,
04505 IN
PSCREEN_INFORMATION ScreenInfo,
04506 IN DWORD Flags
04507 )
04508 {
04509
SHORT Size;
04510
SHORT CurCmdNum;
04511
SHORT NewCmdNum;
04512
BOOL Scroll=
FALSE;
04513
04514
if (Delta == 0) {
04515
return;
04516 }
04517
Size =
POPUP_SIZE_Y(Popup);
04518
04519
if (Flags &
UCLP_WRAP) {
04520 CurCmdNum = *CurrentCommand;
04521 NewCmdNum = CurCmdNum + Delta;
04522 NewCmdNum =
COMMAND_INDEX_TO_NUM(NewCmdNum, CommandHistory);
04523 CurCmdNum =
COMMAND_INDEX_TO_NUM(CurCmdNum, CommandHistory);
04524 }
else {
04525 CurCmdNum =
COMMAND_INDEX_TO_NUM(*CurrentCommand, CommandHistory);
04526 NewCmdNum = CurCmdNum + Delta;
04527
if (NewCmdNum >= CommandHistory->NumberOfCommands) {
04528 NewCmdNum = (
SHORT)(CommandHistory->NumberOfCommands-1);
04529 }
else if (NewCmdNum < 0) {
04530 NewCmdNum = 0;
04531 }
04532 }
04533 Delta = NewCmdNum - CurCmdNum;
04534
04535
04536
04537
if (NewCmdNum <= Popup->BottomIndex-
Size) {
04538 Popup->BottomIndex += Delta;
04539
if (Popup->BottomIndex < (
SHORT)(
Size-1)) {
04540 Popup->BottomIndex = (
SHORT)(
Size-1);
04541 }
04542 Scroll =
TRUE;
04543 }
else if (NewCmdNum > Popup->BottomIndex) {
04544 Popup->BottomIndex += Delta;
04545
if (Popup->BottomIndex >= CommandHistory->NumberOfCommands) {
04546 Popup->BottomIndex = (
SHORT)(CommandHistory->NumberOfCommands-1);
04547 }
04548 Scroll =
TRUE;
04549 }
04550
04551
04552
04553
04554
04555
if (Scroll) {
04556
DrawCommandListPopup(Popup,
COMMAND_NUM_TO_INDEX(NewCmdNum,CommandHistory),CommandHistory,ScreenInfo);
04557 }
else {
04558
UpdateHighlight(Popup,
COMMAND_INDEX_TO_NUM((*CurrentCommand),CommandHistory),NewCmdNum,ScreenInfo);
04559 }
04560 *CurrentCommand =
COMMAND_NUM_TO_INDEX(NewCmdNum,CommandHistory);
04561 }
04562
04563
PCOMMAND_HISTORY
04564 FindCommandHistory(
04565 IN
PCONSOLE_INFORMATION Console,
04566 IN HANDLE ProcessHandle
04567 )
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587 {
04588
PCOMMAND_HISTORY History;
04589 PLIST_ENTRY ListHead, ListNext;
04590
04591 ListHead = &Console->CommandHistoryList;
04592 ListNext = ListHead->Flink;
04593
while (ListNext != ListHead) {
04594
History = CONTAINING_RECORD( ListNext,
COMMAND_HISTORY, ListLink );
04595 ListNext = ListNext->Flink;
04596
if (
History->ProcessHandle == ProcessHandle) {
04597
ASSERT(
History->Flags &
CLE_ALLOCATED);
04598
return History;
04599 }
04600 }
04601
return NULL;
04602 }
04603
04604
VOID
04605 FreeCommandHistory(
04606 IN
PCONSOLE_INFORMATION Console,
04607 IN HANDLE ProcessHandle
04608 )
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628 {
04629
PCOMMAND_HISTORY History;
04630
04631
History =
FindCommandHistory(Console,ProcessHandle);
04632
if (
History) {
04633
History->Flags &= ~
CLE_ALLOCATED;
04634
History->ProcessHandle =
NULL;
04635 }
04636 }
04637
04638
04639
VOID
04640 FreeCommandHistoryBuffers(
04641 IN OUT
PCONSOLE_INFORMATION Console
04642 )
04643 {
04644
PCOMMAND_HISTORY History;
04645 PLIST_ENTRY ListHead, ListNext;
04646
SHORT i;
04647
04648 ListHead = &Console->CommandHistoryList;
04649 ListNext = ListHead->Flink;
04650
while (ListNext != ListHead) {
04651
History = CONTAINING_RECORD( ListNext,
COMMAND_HISTORY, ListLink );
04652 ListNext = ListNext->Flink;
04653 RemoveEntryList(&
History->ListLink);
04654
if (
History->AppName) {
04655
ConsoleHeapFree(
History->AppName);
04656 }
04657
for (i=0;i<
History->NumberOfCommands;i++) {
04658
ConsoleHeapFree(
History->Commands[i]);
04659 }
04660
ConsoleHeapFree(
History);
04661 }
04662 }
04663
04664
VOID
04665 ResizeCommandHistoryBuffers(
04666 IN
PCONSOLE_INFORMATION Console,
04667 IN UINT NumCommands
04668 )
04669 {
04670
PCOMMAND_HISTORY History;
04671 PLIST_ENTRY ListHead, ListNext;
04672
#if defined(FE_SB)
04673
PCOOKED_READ_DATA CookedReadData;
04674
PCOMMAND_HISTORY NewHistory;
04675
#endif
04676
04677 Console->CommandHistorySize = (
SHORT)NumCommands;
04678
04679 ListHead = &Console->CommandHistoryList;
04680 ListNext = ListHead->Flink;
04681
while (ListNext != ListHead) {
04682
History = CONTAINING_RECORD( ListNext,
COMMAND_HISTORY, ListLink );
04683 ListNext = ListNext->Flink;
04684
04685
#if defined(FE_SB)
04686
NewHistory =
ReallocCommandHistory(Console,
History, NumCommands);
04687 CookedReadData = Console->lpCookedReadData;
04688
if (CookedReadData && CookedReadData->
CommandHistory ==
History) {
04689 CookedReadData->
CommandHistory = NewHistory;
04690 }
04691
#else
04692
if (!(
History->Flags &
CLE_ALLOCATED)) {
04693
ReallocCommandHistory(Console,
History, NumCommands);
04694 }
04695
#endif
04696
}
04697 }
04698
04699
VOID
04700 InitializeConsoleCommandData(
04701 IN
PCONSOLE_INFORMATION Console
04702 )
04703
04704
04705
04706
04707
04708
04709
04710
04711
04712
04713
04714
04715
04716
04717
04718
04719
04720 {
04721 Console->NumCommandHistories = 0;
04722 InitializeListHead(&Console->CommandHistoryList);
04723 }
04724
04725
VOID
04726 ResetCommandHistory(
04727 IN
PCOMMAND_HISTORY CommandHistory
04728 )
04729
04730
04731
04732
04733
04734
04735 {
04736
if (CommandHistory ==
NULL) {
04737
return;
04738 }
04739 CommandHistory->LastDisplayed = CommandHistory->LastAdded;
04740 CommandHistory->Flags |=
CLE_RESET;
04741 }
04742
04743
NTSTATUS
04744 AddCommand(
04745 IN
PCOMMAND_HISTORY CommandHistory,
04746 IN PWCHAR Command,
04747 IN USHORT Length,
04748 IN BOOL HistoryNoDup
04749 )
04750 {
04751
PCOMMAND *ppCmd;
04752
04753
04754
04755
04756
if (CommandHistory ==
NULL || CommandHistory->MaximumNumberOfCommands == 0) {
04757
return STATUS_NO_MEMORY;
04758 }
04759
ASSERT(CommandHistory->Flags &
CLE_ALLOCATED);
04760
04761
04762
04763
04764
04765
04766
04767
if (Length == 0) {
04768
return STATUS_SUCCESS;
04769 }
04770
04771
if (CommandHistory->NumberOfCommands == 0 ||
04772 CommandHistory->Commands[CommandHistory->LastAdded]->CommandLength != Length ||
04773 memcmp(CommandHistory->Commands[CommandHistory->LastAdded]->Command,Command,Length)) {
04774
04775
PCOMMAND pCmdReuse =
NULL;
04776
04777
if (HistoryNoDup) {
04778
SHORT i;
04779 i =
FindMatchingCommand(CommandHistory, Command, Length,
04780 CommandHistory->LastDisplayed,
FMCFL_EXACT_MATCH);
04781
if (i != -1) {
04782 pCmdReuse =
RemoveCommand(CommandHistory, i);
04783 }
04784 }
04785
04786
04787
04788
04789
04790
04791
if (CommandHistory->NumberOfCommands < CommandHistory->MaximumNumberOfCommands) {
04792 CommandHistory->LastAdded += 1;
04793 CommandHistory->NumberOfCommands++;
04794 }
04795
else {
04796
COMMAND_IND_INC(CommandHistory->LastAdded, CommandHistory);
04797
COMMAND_IND_INC(CommandHistory->FirstCommand, CommandHistory);
04798
ConsoleHeapFree(CommandHistory->Commands[CommandHistory->LastAdded]);
04799
if (CommandHistory->LastDisplayed == CommandHistory->LastAdded) {
04800 CommandHistory->LastDisplayed = -1;
04801 }
04802 }
04803
04804
if (CommandHistory->LastDisplayed == -1 ||
04805 CommandHistory->Commands[CommandHistory->LastDisplayed]->CommandLength != Length ||
04806 memcmp(CommandHistory->Commands[CommandHistory->LastDisplayed]->Command,Command,Length)) {
04807
ResetCommandHistory(CommandHistory);
04808 }
04809
04810
04811
04812
04813
04814 ppCmd = &CommandHistory->Commands[CommandHistory->LastAdded];
04815
if (pCmdReuse) {
04816 *ppCmd = pCmdReuse;
04817 }
else {
04818 *ppCmd = (
PCOMMAND)
ConsoleHeapAlloc(
MAKE_TAG(
HISTORY_TAG),
04819 Length -
sizeof(WCHAR) +
sizeof(
COMMAND));
04820
if (*ppCmd ==
NULL) {
04821
COMMAND_IND_PREV(CommandHistory->LastAdded, CommandHistory);
04822 CommandHistory->NumberOfCommands -= 1;
04823
return STATUS_NO_MEMORY;
04824 }
04825 (*ppCmd)->CommandLength = Length;
04826 RtlCopyMemory((*ppCmd)->Command,Command,Length);
04827 }
04828 }
04829 CommandHistory->Flags |=
CLE_RESET;
04830
return STATUS_SUCCESS;
04831 }
04832
04833
NTSTATUS
04834 RetrieveCommand(
04835 IN
PCOMMAND_HISTORY CommandHistory,
04836 IN WORD VirtualKeyCode,
04837 IN PWCHAR Buffer,
04838 IN ULONG BufferSize,
04839 OUT PULONG CommandSize
04840 )
04841 {
04842
04843
if (CommandHistory ==
NULL) {
04844
return STATUS_UNSUCCESSFUL;
04845 }
04846
ASSERT(CommandHistory->Flags &
CLE_ALLOCATED);
04847
if (CommandHistory->NumberOfCommands == 0) {
04848
return STATUS_UNSUCCESSFUL;
04849 }
04850
if (CommandHistory->NumberOfCommands == 1) {
04851 CommandHistory->LastDisplayed = 0;
04852 }
04853
else if (VirtualKeyCode == VK_UP) {
04854
04855
04856
04857
04858
04859
04860
04861
if (CommandHistory->Flags &
CLE_RESET) {
04862 CommandHistory->Flags &= ~
CLE_RESET;
04863 }
else {
04864
COMMAND_IND_PREV(CommandHistory->LastDisplayed, CommandHistory);
04865 }
04866 }
04867
else {
04868
COMMAND_IND_NEXT(CommandHistory->LastDisplayed, CommandHistory);
04869 }
04870
return RetrieveNthCommand(CommandHistory,
04871 CommandHistory->LastDisplayed,
04872
Buffer,
04873
BufferSize,
04874 CommandSize
04875 );
04876 }
04877
04878 ULONG
04879 SrvGetConsoleTitle(
04880 IN OUT PCSR_API_MSG m,
04881 IN OUT PCSR_REPLY_STATUS ReplyStatus
04882 )
04883 {
04884
PCONSOLE_GETTITLE_MSG a = (
PCONSOLE_GETTITLE_MSG)&m->u.ApiMessageData;
04885
NTSTATUS Status;
04886
PCONSOLE_INFORMATION Console;
04887
04888
Status =
ApiPreamble(a->
ConsoleHandle,
04889 &Console
04890 );
04891
if (!
NT_SUCCESS(
Status)) {
04892
return Status;
04893 }
04894
04895
if (!CsrValidateMessageBuffer(m, &a->
Title, a->
TitleLength,
sizeof(
BYTE))) {
04896
UnlockConsole(Console);
04897
return STATUS_INVALID_PARAMETER;
04898 }
04899
04900
04901
if (a->
Unicode) {
04902
if ((
USHORT)a->
TitleLength > Console->
TitleLength) {
04903 a->
TitleLength = Console->
TitleLength;
04904 }
04905 RtlCopyMemory(a->
Title,Console->
Title,a->
TitleLength);
04906 }
else {
04907
#if defined(FE_SB)
04908
a->
TitleLength = (
USHORT)
ConvertToOem(
OEMCP,
04909 Console->
Title,
04910 Console->
TitleLength /
sizeof(WCHAR),
04911 a->
Title,
04912 a->
TitleLength
04913 );
04914
#else
04915
a->
TitleLength = (
USHORT)
ConvertToOem(Console->
CP,
04916 Console->
Title,
04917 Console->
TitleLength /
sizeof(WCHAR),
04918 a->
Title,
04919 a->
TitleLength
04920 );
04921
#endif
04922
}
04923
UnlockConsole(Console);
04924
return STATUS_SUCCESS;
04925 UNREFERENCED_PARAMETER(ReplyStatus);
04926 }
04927
04928 ULONG
04929 SrvSetConsoleTitle(
04930 IN OUT PCSR_API_MSG m,
04931 IN OUT PCSR_REPLY_STATUS ReplyStatus
04932 )
04933 {
04934
PCONSOLE_SETTITLE_MSG a = (
PCONSOLE_SETTITLE_MSG)&m->u.ApiMessageData;
04935
NTSTATUS Status;
04936
PCONSOLE_INFORMATION Console;
04937 LPWSTR NewTitle;
04938
04939
Status =
ApiPreamble(a->
ConsoleHandle,
04940 &Console
04941 );
04942
if (!
NT_SUCCESS(
Status)) {
04943
return Status;
04944 }
04945
04946
if (!CsrValidateMessageBuffer(m, &a->
Title, a->
TitleLength,
sizeof(
BYTE))) {
04947
UnlockConsole(Console);
04948
return STATUS_INVALID_PARAMETER;
04949 }
04950
04951
if (!a->
Unicode) {
04952 NewTitle = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TITLE_TAG ),a->
TitleLength*
sizeof(WCHAR)+
sizeof(WCHAR));
04953
if (NewTitle ==
NULL) {
04954
UnlockConsole(Console);
04955
return (ULONG)STATUS_NO_MEMORY;
04956 }
04957
04958
04959
04960
#if defined(FE_SB)
04961
Console->
TitleLength = (
USHORT)
ConvertInputToUnicode(
OEMCP,
04962 a->
Title,
04963 a->
TitleLength,
04964 NewTitle,
04965 a->
TitleLength);
04966
#else
04967
Console->
TitleLength = (
USHORT)
ConvertInputToUnicode(Console->
CP,
04968 a->
Title,
04969 a->
TitleLength,
04970 NewTitle,
04971 a->
TitleLength);
04972
#endif
04973
Console->
TitleLength *= 2;
04974 }
else {
04975
04976
04977 NewTitle = (LPWSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TITLE_TAG ),a->
TitleLength+
sizeof(WCHAR));
04978
if (NewTitle ==
NULL) {
04979
UnlockConsole(Console);
04980
return (ULONG)STATUS_NO_MEMORY;
04981 }
04982 Console->
TitleLength = (
USHORT)a->
TitleLength;
04983 RtlCopyMemory(NewTitle,a->
Title,a->
TitleLength);
04984 }
04985 NewTitle[Console->
TitleLength/
sizeof(WCHAR)] = 0;
04986
ConsoleHeapFree(Console->
Title);
04987 Console->
Title = NewTitle;
04988
PostMessage(Console->
hWnd,
CM_UPDATE_TITLE, 0, 0);
04989
UnlockConsole(Console);
04990
return STATUS_SUCCESS;
04991 UNREFERENCED_PARAMETER(ReplyStatus);
04992 }
04993
04994
int
04995 LoadStringExW(
04996 IN HINSTANCE hModule,
04997 IN UINT wID,
04998 OUT LPWSTR lpBuffer,
04999 IN
int cchBufferMax,
05000 IN WORD wLangId
05001 )
05002 {
05003 HANDLE hResInfo;
05004 HANDLE hStringSeg;
05005 LPTSTR lpsz;
05006
int cch;
05007
05008
05009
05010
05011
if (lpBuffer ==
NULL) {
05012
return 0;
05013 }
05014
05015 cch = 0;
05016
05017
05018
05019
05020
05021
if (hResInfo = FindResourceEx(hModule,
05022 RT_STRING,
05023 (LPTSTR)((LONG)(((
USHORT)wID >> 4) + 1)),
05024 wLangId)) {
05025
05026
05027
05028
05029 hStringSeg = LoadResource(hModule, hResInfo);
05030
05031
05032
05033
05034
if (lpsz = (LPTSTR)LockResource(hStringSeg)) {
05035
05036
05037
05038
05039
05040 wID &= 0x0F;
05041
while (
TRUE) {
05042 cch = *((
UTCHAR *)lpsz++);
05043
05044
if (wID-- == 0)
break;
05045 lpsz += cch;
05046 }
05047
05048
05049
05050
05051
if (cchBufferMax == 0) {
05052 *(LPTSTR *)lpBuffer = lpsz;
05053 }
else {
05054
05055
05056
05057
05058 cchBufferMax--;
05059
05060
05061
05062
05063
if (cch > cchBufferMax)
05064 cch = cchBufferMax;
05065
05066
05067
05068
05069 RtlCopyMemory(lpBuffer, lpsz, cch*
sizeof(WCHAR));
05070 }
05071 }
05072 }
05073
05074
05075
05076
05077
if (cchBufferMax != 0) {
05078 lpBuffer[cch] = 0;
05079 }
05080
05081
return cch;
05082 }