Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS text-mode setup * FILE: base/setup/usetup/cmdcons.c * PURPOSE: Recovery console * PROGRAMMER: */
#include "usetup.h"
#define NDEBUG#include <debug.h>
//#define FEATURE_HISTORY
typedef struct _CONSOLE_STATE{ SHORT maxx; SHORT maxy; BOOLEAN bInsert; BOOLEAN bExit;} CONSOLE_STATE, *PCONSOLE_STATE;
typedef struct tagCOMMAND{ LPSTR name; INT flags; INT (*func)(PCONSOLE_STATE, LPSTR); VOID (*help)(VOID);} COMMAND, *LPCOMMAND;
staticVOIDHelpCls(VOID);
staticINTCommandCls( PCONSOLE_STATE State, LPSTR param);
staticVOIDHelpDumpSector(VOID);
staticINTCommandDumpSector( PCONSOLE_STATE State, LPSTR param);
staticVOIDHelpExit(VOID);
staticINTCommandExit( PCONSOLE_STATE State, LPSTR param);
staticVOIDHelpHelp(VOID);
staticINTCommandHelp( PCONSOLE_STATE State, LPSTR param);
staticVOIDHelpPartInfo(VOID);
staticINTCommandPartInfo( PCONSOLE_STATE State, LPSTR param);
COMMANDCommands[] ={ {"cls", 0, CommandCls, HelpCls}, {"dumpsector", 0, CommandDumpSector, HelpDumpSector}, {"exit", 0, CommandExit, HelpExit}, {"help", 0, CommandHelp, HelpHelp}, {"partinfo", 0, CommandPartInfo, HelpPartInfo}, {NULL, 0, NULL}};
staticVOIDfreep( LPSTR *p){ LPSTR *q;
if (!p) return;
q = p; while (*q) RtlFreeHeap(ProcessHeap, 0, *q++);
RtlFreeHeap(ProcessHeap, 0, p);}
staticVOIDStripQuotes( LPSTR in){ LPSTR out = in;
for (; *in; in++) { if (*in != '"') *out++ = *in; }
*out = '\0';}
BOOLadd_entry( LPINT ac, LPSTR **arg, LPCSTR entry){ LPSTR q; LPSTR *oldarg;
q = RtlAllocateHeap(ProcessHeap, 0, strlen(entry) + 1); if (q == NULL) return FALSE;
strcpy(q, entry); oldarg = *arg; *arg = RtlReAllocateHeap(ProcessHeap, 0, oldarg, (*ac + 2) * sizeof(LPSTR)); if (*arg == NULL) { RtlFreeHeap(ProcessHeap, 0, q); *arg = oldarg; return FALSE; }
/* save new entry */ (*arg)[*ac] = q; (*arg)[++(*ac)] = NULL;
return TRUE;}
staticLPSTR *split( LPSTR s, LPINT args){ LPSTR *arg; LPSTR start; LPSTR q; INT ac; INT_PTR len; BOOL bQuoted;
arg = RtlAllocateHeap(ProcessHeap, 0 , sizeof(LPTSTR)); if (arg == NULL) return NULL;
*arg = NULL;
ac = 0; while (*s) { bQuoted = FALSE;
/* skip leading spaces */ while (*s && (isspace(*s) || iscntrl(*s))) ++s;
start = s;
/* the first character can be '/' */ if (*s == '/') s++;
/* skip to next word delimiter or start of next option */ while (isprint(*s)) { /* if quote (") then set bQuoted */ bQuoted ^= (*s == '\"');
/* Check if we have unquoted text */ if (!bQuoted) { /* check for separators */ if (isspace(*s) || (*s == '/')) { /* Make length at least one character */ if (s == start) s++; break; } }
s++; }
/* a word was found */ if (s != start) { len = s - start; q = RtlAllocateHeap(ProcessHeap, 0, len + 1); if (q == NULL) { freep(arg); return NULL; }
memcpy(q, start, len); q[len] = '\0';
StripQuotes(q);
if (!add_entry(&ac, &arg, q)) { RtlFreeHeap(ProcessHeap, 0, q); freep(arg); return NULL; }
RtlFreeHeap(ProcessHeap, 0, q); } }
*args = ac;
return arg;}
staticVOIDHelpCls(VOID){ CONSOLE_ConOutPrintf("CLS\n\nClears the screen.\n\n");}
staticINTCommandCls( PCONSOLE_STATE State, LPSTR param){ if (!strcmp(param, "/?")) { HelpCls(); return 0; }
CONSOLE_ClearScreen(); CONSOLE_SetCursorXY(0, 0);
return 0;}
void HexDump(PUCHAR buffer, ULONG size){ ULONG offset = 0; PUCHAR ptr;
while (offset < (size & ~15)) { ptr = (PUCHAR)((ULONG_PTR)buffer + offset); CONSOLE_ConOutPrintf("%04lx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx\n", offset, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]); offset += 16; }
if (offset < size) { ptr = (PUCHAR)((ULONG_PTR)buffer + offset); CONSOLE_ConOutPrintf("%04lx ", offset); while (offset < size) { CONSOLE_ConOutPrintf(" %02hx", *ptr); offset++; ptr++; }
CONSOLE_ConOutPrintf("\n"); }
CONSOLE_ConOutPrintf("\n");}
staticVOIDHelpDumpSector(VOID){ CONSOLE_ConOutPrintf("DUMPSECT DiskNumber Sector\n\nDumps a disk sector to the screen.\n\n");}
staticINTCommandDumpSector( PCONSOLE_STATE State, LPSTR param){ OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING PathName; HANDLE hDisk = NULL; DISK_GEOMETRY DiskGeometry; NTSTATUS Status;
LPTSTR *argv = NULL; INT argc = 0; WCHAR DriveName[40]; ULONG ulDrive;// ULONG ulSector; LARGE_INTEGER Sector, SectorCount, Offset; PUCHAR Buffer = NULL;
DPRINT1("param: %s\n", param);
if (!strcmp(param, "/?")) { HelpDumpSector(); return 0; }
argv = split(param, &argc);
DPRINT1("argc: %d\n", argc); DPRINT1("argv: %p\n", argv);
if (argc != 2) { goto done; }
DPRINT1("Device: %s\n", argv[0]); DPRINT1("Sector: %s\n", argv[1]);
ulDrive = strtoul(argv[0], NULL, 0);// ulSector = strtoul(argv[1], NULL, 0); Sector.QuadPart = _atoi64(argv[1]);
/* Build full drive name */// swprintf(DriveName, L"\\\\.\\PHYSICALDRIVE%lu", ulDrive); swprintf(DriveName, L"\\Device\\Harddisk%lu\\Partition0", ulDrive);
RtlInitUnicodeString(&PathName, DriveName);
InitializeObjectAttributes(&ObjectAttributes, &PathName, OBJ_CASE_INSENSITIVE | OBJ_INHERIT, NULL, NULL);
Status = NtOpenFile(&hDisk, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateFile failed (Status 0x%08lx)\n", Status); goto done; }
Status = NtDeviceIoControlFile(hDisk, NULL, NULL, NULL, &IoStatusBlock, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &DiskGeometry, sizeof(DISK_GEOMETRY)); if (!NT_SUCCESS(Status)) { DPRINT1("NtDeviceIoControlFile failed (Status 0x%08lx)\n", Status); goto done; }
DPRINT1("Drive number: %lu\n", ulDrive); DPRINT1("Cylinders: %I64u\nMediaType: %x\nTracksPerCylinder: %lu\n" "SectorsPerTrack: %lu\nBytesPerSector: %lu\n\n", DiskGeometry.Cylinders.QuadPart, DiskGeometry.MediaType, DiskGeometry.TracksPerCylinder, DiskGeometry.SectorsPerTrack, DiskGeometry.BytesPerSector);
DPRINT1("Sector: %I64u\n", Sector.QuadPart);
SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart * (ULONGLONG)DiskGeometry.TracksPerCylinder * (ULONGLONG)DiskGeometry.SectorsPerTrack; if (Sector.QuadPart >= SectorCount.QuadPart) { CONSOLE_ConOutPrintf("Invalid sector number! Valid range: [0 - %I64u]\n", SectorCount.QuadPart - 1); goto done; }
Buffer = RtlAllocateHeap(ProcessHeap, 0, DiskGeometry.BytesPerSector); if (Buffer == NULL) { DPRINT1("Buffer allocation failed\n"); goto done; }
Offset.QuadPart = Sector.QuadPart * DiskGeometry.BytesPerSector; DPRINT1("Offset: %I64u\n", Offset.QuadPart);
Status = NtReadFile(hDisk, NULL, NULL, NULL, &IoStatusBlock, Buffer, DiskGeometry.BytesPerSector, &Offset, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("NtReadFile failed (Status 0x%08lx)\n", Status); goto done; }
HexDump(Buffer, DiskGeometry.BytesPerSector);
done: if (Buffer != NULL) RtlFreeHeap(ProcessHeap, 0, Buffer);
if (hDisk != NULL) NtClose(hDisk);
freep(argv);
return 0;}
staticVOIDHelpExit(VOID){ CONSOLE_ConOutPrintf("EXIT\n\nExits the repair console.\n\n");}
staticINTCommandExit( PCONSOLE_STATE State, LPSTR param){ if (!strcmp(param, "/?")) { HelpExit(); return 0; }
State->bExit = TRUE;
return 0;}
staticVOIDHelpHelp(VOID){ CONSOLE_ConOutPrintf("HELP [Command]\n\nShows help on repair console commands.\n\n");}
staticINTCommandHelp( PCONSOLE_STATE State, LPSTR param){ LPCOMMAND cmdptr;
DPRINT1("param: %p %u '%s'\n", param, strlen(param), param);
if (!strcmp(param, "/?")) { HelpHelp(); return 0; }
if (param != NULL && strlen(param) > 0) { for (cmdptr = Commands; cmdptr->name != NULL; cmdptr++) { if (!_stricmp(param, cmdptr->name)) { if (cmdptr->help != NULL) { cmdptr->help(); return 0; } } } }
CONSOLE_ConOutPrintf("CLS\n"); CONSOLE_ConOutPrintf("DUMPSECTOR\n"); CONSOLE_ConOutPrintf("EXIT\n"); CONSOLE_ConOutPrintf("HELP\n"); CONSOLE_ConOutPrintf("\n");
return 0;}
staticVOIDHelpPartInfo(VOID){ CONSOLE_ConOutPrintf("PARTINFO DiskNumber\n\nDumps a partition table to the screen.\n\n");}
staticINTCommandPartInfo( PCONSOLE_STATE State, LPSTR param){ OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING PathName; HANDLE hDisk = NULL; DISK_GEOMETRY DiskGeometry; NTSTATUS Status;
LPTSTR *argv = NULL; INT argc = 0; WCHAR DriveName[40]; ULONG ulDrive, i; PDRIVE_LAYOUT_INFORMATION LayoutBuffer = NULL; PPARTITION_INFORMATION PartitionInfo;
DPRINT1("param: %s\n", param);
if (!strcmp(param, "/?")) { HelpPartInfo(); return 0; }
argv = split(param, &argc);
DPRINT1("argc: %d\n", argc); DPRINT1("argv: %p\n", argv);
if (argc != 1) { goto done; }
DPRINT1("Device: %s\n", argv[0]);
ulDrive = strtoul(argv[0], NULL, 0);
/* Build full drive name */ swprintf(DriveName, L"\\Device\\Harddisk%lu\\Partition0", ulDrive);
RtlInitUnicodeString(&PathName, DriveName);
InitializeObjectAttributes(&ObjectAttributes, &PathName, OBJ_CASE_INSENSITIVE | OBJ_INHERIT, NULL, NULL);
Status = NtOpenFile(&hDisk, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateFile failed (Status 0x%08lx)\n", Status); goto done; }
Status = NtDeviceIoControlFile(hDisk, NULL, NULL, NULL, &IoStatusBlock, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &DiskGeometry, sizeof(DISK_GEOMETRY)); if (!NT_SUCCESS(Status)) { DPRINT1("NtDeviceIoControlFile failed (Status 0x%08lx)\n", Status); goto done; }
CONSOLE_ConOutPrintf("Drive number: %lu\n", ulDrive); CONSOLE_ConOutPrintf("Cylinders: %I64u\nMediaType: %x\nTracksPerCylinder: %lu\n" "SectorsPerTrack: %lu\nBytesPerSector: %lu\n\n", DiskGeometry.Cylinders.QuadPart, DiskGeometry.MediaType, DiskGeometry.TracksPerCylinder, DiskGeometry.SectorsPerTrack, DiskGeometry.BytesPerSector);
LayoutBuffer = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, 8192); if (LayoutBuffer == NULL) { DPRINT1("LayoutBuffer allocation failed\n"); goto done; }
Status = NtDeviceIoControlFile(hDisk, NULL, NULL, NULL, &IoStatusBlock, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, 0, LayoutBuffer, 8192); if (!NT_SUCCESS(Status)) { DPRINT1("NtDeviceIoControlFile(IOCTL_DISK_GET_DRIVE_LAYOUT) failed (Status 0x%08lx)\n", Status); goto done; }
CONSOLE_ConOutPrintf("Partitions: %lu Signature: %lx\n\n", LayoutBuffer->PartitionCount, LayoutBuffer->Signature);
CONSOLE_ConOutPrintf(" # Start Size Hidden Nr Type Boot\n"); CONSOLE_ConOutPrintf("-- --------------- --------------- ------------ -- ---- ----\n");
for (i = 0; i < LayoutBuffer->PartitionCount; i++) { PartitionInfo = &LayoutBuffer->PartitionEntry[i];
CONSOLE_ConOutPrintf("%2lu %15I64u %15I64u %12lu %2lu %2x %c\n", i, PartitionInfo->StartingOffset.QuadPart / DiskGeometry.BytesPerSector, PartitionInfo->PartitionLength.QuadPart / DiskGeometry.BytesPerSector, PartitionInfo->HiddenSectors, PartitionInfo->PartitionNumber, PartitionInfo->PartitionType, PartitionInfo->BootIndicator ? '*': ' '); }
CONSOLE_ConOutPrintf("\n");
done: if (LayoutBuffer != NULL) RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
if (hDisk != NULL) NtClose(hDisk);
freep(argv);
return 0;}
staticVOIDClearCommandLine( LPSTR str, INT maxlen, SHORT orgx, SHORT orgy){ INT count;
CONSOLE_SetCursorXY(orgx, orgy); for (count = 0; count < (INT)strlen(str); count++) CONSOLE_ConOutChar(' '); memset(str, 0, maxlen); CONSOLE_SetCursorXY(orgx, orgy);}
staticBOOLReadCommand( PCONSOLE_STATE State, LPSTR str, INT maxlen){ SHORT orgx; /* origin x/y */ SHORT orgy; SHORT curx; /*current x/y cursor position*/ SHORT cury; SHORT tempscreen; INT count; /*used in some for loops*/ INT current = 0; /*the position of the cursor in the string (str)*/ INT charcount = 0;/*chars in the string (str)*/ INPUT_RECORD ir; CHAR ch; BOOL bReturn = FALSE; BOOL bCharInput;#ifdef FEATURE_HISTORY //BOOL bContinue=FALSE;/*is TRUE the second case will not be executed*/ CHAR PreviousChar;#endif
CONSOLE_GetCursorXY(&orgx, &orgy); curx = orgx; cury = orgy;
memset(str, 0, maxlen * sizeof(CHAR));
CONSOLE_SetCursorType(State->bInsert, TRUE);
do { bReturn = FALSE; CONSOLE_ConInKey(&ir);
if (ir.Event.KeyEvent.dwControlKeyState & (RIGHT_ALT_PRESSED |LEFT_ALT_PRESSED| RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED) ) { switch (ir.Event.KeyEvent.wVirtualKeyCode) {#ifdef FEATURE_HISTORY case 'K': /*add the current command line to the history*/ if (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) { if (str[0]) History(0,str);
ClearCommandLine (str, maxlen, orgx, orgy); current = charcount = 0; curx = orgx; cury = orgy; //bContinue=TRUE; break; }
case 'D': /*delete current history entry*/ if (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) { ClearCommandLine (str, maxlen, orgx, orgy); History_del_current_entry(str); current = charcount = strlen (str); ConOutPrintf("%s", str); GetCursorXY(&curx, &cury); //bContinue=TRUE; break; }
#endif /*FEATURE_HISTORY*/ } }
bCharInput = FALSE;
switch (ir.Event.KeyEvent.wVirtualKeyCode) { case VK_BACK: /* <BACKSPACE> - delete character to left of cursor */ if (current > 0 && charcount > 0) { if (current == charcount) { /* if at end of line */ str[current - 1] = L'\0'; if (CONSOLE_GetCursorX () != 0) { CONSOLE_ConOutPrintf("\b \b"); curx--; } else { CONSOLE_SetCursorXY((SHORT)(State->maxx - 1), (SHORT)(CONSOLE_GetCursorY () - 1)); CONSOLE_ConOutChar(' '); CONSOLE_SetCursorXY((SHORT)(State->maxx - 1), (SHORT)(CONSOLE_GetCursorY () - 1)); cury--; curx = State->maxx - 1; } } else { for (count = current - 1; count < charcount; count++) str[count] = str[count + 1]; if (CONSOLE_GetCursorX () != 0) { CONSOLE_SetCursorXY ((SHORT)(CONSOLE_GetCursorX () - 1), CONSOLE_GetCursorY ()); curx--; } else { CONSOLE_SetCursorXY ((SHORT)(State->maxx - 1), (SHORT)(CONSOLE_GetCursorY () - 1)); cury--; curx = State->maxx - 1; } CONSOLE_GetCursorXY(&curx, &cury); CONSOLE_ConOutPrintf("%s ", &str[current - 1]); CONSOLE_SetCursorXY(curx, cury); } charcount--; current--; } break;
case VK_INSERT: /* toggle insert/overstrike mode */ State->bInsert ^= TRUE; CONSOLE_SetCursorType(State->bInsert, TRUE); break;
case VK_DELETE: /* delete character under cursor */ if (current != charcount && charcount > 0) { for (count = current; count < charcount; count++) str[count] = str[count + 1]; charcount--; CONSOLE_GetCursorXY(&curx, &cury); CONSOLE_ConOutPrintf("%s ", &str[current]); CONSOLE_SetCursorXY(curx, cury); } break;
case VK_HOME: /* goto beginning of string */ if (current != 0) { CONSOLE_SetCursorXY(orgx, orgy); curx = orgx; cury = orgy; current = 0; } break;
case VK_END: /* goto end of string */ if (current != charcount) { CONSOLE_SetCursorXY(orgx, orgy); CONSOLE_ConOutPrintf("%s", str); CONSOLE_GetCursorXY(&curx, &cury); current = charcount; } break;
case 'M': case 'C': /* ^M does the same as return */ bCharInput = TRUE; if (!(ir.Event.KeyEvent.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))) { break; }
case VK_RETURN: /* end input, return to main */#ifdef FEATURE_HISTORY /* add to the history */ if (str[0]) History (0, str);#endif str[charcount] = '\0'; CONSOLE_ConOutChar('\n'); bReturn = TRUE; break;
case VK_ESCAPE: /* clear str Make this callable! */ ClearCommandLine (str, maxlen, orgx, orgy); curx = orgx; cury = orgy; current = charcount = 0; break;
#ifdef FEATURE_HISTORY case VK_F3: History_move_to_bottom();#endif case VK_UP:#ifdef FEATURE_HISTORY /* get previous command from buffer */ ClearCommandLine (str, maxlen, orgx, orgy); History (-1, str); current = charcount = strlen (str); if (((charcount + orgx) / maxx) + orgy > maxy - 1) orgy += maxy - ((charcount + orgx) / maxx + orgy + 1); CONSOLE_ConOutPrintf("%s", str); CONSOLE_GetCursorXY(&curx, &cury);#endif break;
case VK_DOWN:#ifdef FEATURE_HISTORY /* get next command from buffer */ ClearCommandLine (str, maxlen, orgx, orgy); History (1, str); current = charcount = strlen (str); if (((charcount + orgx) / maxx) + orgy > maxy - 1) orgy += maxy - ((charcount + orgx) / maxx + orgy + 1); CONSOLE_ConOutPrintf("%s", str); CONSOLE_GetCursorXY(&curx, &cury);#endif break;
case VK_LEFT: /* move cursor left */ if (current > 0) { current--; if (CONSOLE_GetCursorX() == 0) { CONSOLE_SetCursorXY((SHORT)(State->maxx - 1), (SHORT)(CONSOLE_GetCursorY () - 1)); curx = State->maxx - 1; cury--; } else { CONSOLE_SetCursorXY((SHORT)(CONSOLE_GetCursorX () - 1), CONSOLE_GetCursorY ()); curx--; } } break;
case VK_RIGHT: /* move cursor right */ if (current != charcount) { current++; if (CONSOLE_GetCursorX() == State->maxx - 1) { CONSOLE_SetCursorXY(0, (SHORT)(CONSOLE_GetCursorY () + 1)); curx = 0; cury++; } else { CONSOLE_SetCursorXY((SHORT)(CONSOLE_GetCursorX () + 1), CONSOLE_GetCursorY ()); curx++; } }#ifdef FEATURE_HISTORY else { LPCSTR last = PeekHistory(-1); if (last && charcount < (INT)strlen (last)) { PreviousChar = last[current]; CONSOLE_ConOutChar(PreviousChar); CONSOLE_GetCursorXY(&curx, &cury); str[current++] = PreviousChar; charcount++; } }#endif break;
default: /* This input is just a normal char */ bCharInput = TRUE;
}
ch = ir.Event.KeyEvent.uChar.UnicodeChar; if (ch >= 32 && (charcount != (maxlen - 2)) && bCharInput) { /* insert character into string... */ if (State->bInsert && current != charcount) { /* If this character insertion will cause screen scrolling, * adjust the saved origin of the command prompt. */ tempscreen = (USHORT)strlen(str + current) + curx; if ((tempscreen % State->maxx) == (State->maxx - 1) && (tempscreen / State->maxx) + cury == (State->maxy - 1)) { orgy--; cury--; }
for (count = charcount; count > current; count--) str[count] = str[count - 1]; str[current++] = ch; if (curx == State->maxx - 1) curx = 0, cury++; else curx++; CONSOLE_ConOutPrintf("%s", &str[current - 1]); CONSOLE_SetCursorXY(curx, cury); charcount++; } else { if (current == charcount) charcount++; str[current++] = ch; if (CONSOLE_GetCursorX () == State->maxx - 1 && CONSOLE_GetCursorY () == State->maxy - 1) orgy--, cury--; if (CONSOLE_GetCursorX () == State->maxx - 1) curx = 0, cury++; else curx++; CONSOLE_ConOutChar(ch); } } } while (!bReturn);
CONSOLE_SetCursorType(State->bInsert, TRUE);
return TRUE;}
staticBOOLIsDelimiter( CHAR c){ return (c == '/' || c == '=' || c == '\0' || isspace(c));}
staticVOIDDoCommand( PCONSOLE_STATE State, LPSTR line){ CHAR com[MAX_PATH]; /* the first word in the command */ LPSTR cp = com;// LPSTR cstart; LPSTR rest = line; /* pointer to the rest of the command line */// INT cl; LPCOMMAND cmdptr;
DPRINT1("DoCommand: (\'%s\')\n", line);
/* Skip over initial white space */ while (isspace(*rest)) rest++;
// cstart = rest;
/* Anything to do ? */ if (*rest) { /* Copy over 1st word as lower case */ while (!IsDelimiter(*rest)) *cp++ = tolower(*rest++);
/* Terminate first word */ *cp = '\0';
/* Skip over whitespace to rest of line */ while (isspace (*rest)) rest++;
/* Scan internal command table */ for (cmdptr = Commands; ; cmdptr++) { /* If end of table execute ext cmd */ if (cmdptr->name == NULL) { CONSOLE_ConOutPuts("Unknown command. Enter HELP to get a list of commands."); break; }
if (_stricmp(com, cmdptr->name) == 0) { cmdptr->func(State, rest); break; }
#if 0 /* The following code handles the case of commands like CD which * are recognised even when the command name and parameter are * not space separated. * * e.g dir.. * cd\freda */
/* Get length of command name */ cl = strlen(cmdptr->name);
if ((cmdptr->flags & CMD_SPECIAL) && (!strncmp (cmdptr->name, com, cl)) && (strchr("\\.-", *(com + cl)))) { /* OK its one of the specials...*/
/* Call with new rest */ cmdptr->func(State, cstart + cl); break; }#endif } }}
VOIDRecoveryConsole(VOID){ CHAR szInputBuffer[256]; CONSOLE_SCREEN_BUFFER_INFO csbi; CONSOLE_STATE State;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
/* get screen size */ State.maxx = csbi.dwSize.X; State.maxy = csbi.dwSize.Y; State.bInsert = TRUE; State.bExit = FALSE;
CONSOLE_ClearScreen(); CONSOLE_SetCursorXY(0, 0);
CONSOLE_ConOutPrintf("ReactOS Recovery Console\n\nEnter HELP to get a list of commands.\n\n");
while (!State.bExit) { /* Prompt */ CONSOLE_ConOutPrintf(">");
ReadCommand(&State, szInputBuffer, 256);DPRINT1("%s\n", szInputBuffer);
DoCommand(&State, szInputBuffer);
// Cmd = ParseCommand(NULL);// if (!Cmd)// continue;
// ExecuteCommand(Cmd);// FreeCommand(Cmd); }}
/* EOF */