Author: ekohl Date: Sat Dec 20 21:58:22 2014 New Revision: 65778
URL: http://svn.reactos.org/svn/reactos?rev=65778&view=rev Log: [USETUP] Start implementing the recovery console: CLS, EXIT and HELP have been implemented. I also added a DUMPSECTOR command that enables us to dump disk sectors to the screen. For example "DUMPSECTOR 0 63" dumps disk 0 sector 63 to the screen.
Added: trunk/reactos/base/setup/usetup/cmdcons.c (with props) trunk/reactos/base/setup/usetup/cmdcons.h (with props) Modified: trunk/reactos/base/setup/usetup/CMakeLists.txt trunk/reactos/base/setup/usetup/interface/consup.c trunk/reactos/base/setup/usetup/interface/consup.h trunk/reactos/base/setup/usetup/interface/usetup.c trunk/reactos/base/setup/usetup/native/utils/console.c trunk/reactos/base/setup/usetup/usetup.h
Modified: trunk/reactos/base/setup/usetup/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/CMakeList... ============================================================================== --- trunk/reactos/base/setup/usetup/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/base/setup/usetup/CMakeLists.txt [iso-8859-1] Sat Dec 20 21:58:22 2014 @@ -18,6 +18,7 @@ bootsup.c cabinet.c chkdsk.c + cmdcons.c drivesup.c filesup.c filequeue.c
Added: trunk/reactos/base/setup/usetup/cmdcons.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/cmdcons.c... ============================================================================== --- trunk/reactos/base/setup/usetup/cmdcons.c (added) +++ trunk/reactos/base/setup/usetup/cmdcons.c [iso-8859-1] Sat Dec 20 21:58:22 2014 @@ -0,0 +1,978 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/cmdcons.c + * PURPOSE: Recovery console + * PROGRAMMER: Eric Kohl + */ + +#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); +} COMMAND, *LPCOMMAND; + + +static +INT +CommandCls( + PCONSOLE_STATE State, + LPSTR param); + +static +INT +CommandDumpSector( + PCONSOLE_STATE State, + LPSTR param); + +static +INT +CommandExit( + PCONSOLE_STATE State, + LPSTR param); + +static +INT +CommandHelp( + PCONSOLE_STATE State, + LPSTR param); + +COMMAND +Commands[] = +{ + {"cls", 0, CommandCls}, + {"dumpsector", 0, CommandDumpSector}, + {"exit", 0, CommandExit}, + {"help", 0, CommandHelp}, + {NULL, 0, NULL} +}; + + +static +VOID +freep( + LPSTR *p) +{ + LPSTR *q; + + if (!p) + return; + + q = p; + while (*q) + RtlFreeHeap(ProcessHeap, 0, *q++); + + RtlFreeHeap(ProcessHeap, 0, p); +} + + +static +VOID +StripQuotes( + LPSTR in) +{ + LPSTR out = in; + + for (; *in; in++) + { + if (*in != '"') + *out++ = *in; + } + + *out = '\0'; +} + + +BOOL +add_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; +} + +static +LPSTR * +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; +} + + +static +INT +CommandCls( + PCONSOLE_STATE State, + LPSTR param) +{ +#if 0 + HANDLE hOutput; + COORD coPos; + DWORD dwWritten; + +#if 0 + if (!strncmp(param, "/?", 2)) + { + ConOutResPaging(TRUE,STRING_CLS_HELP); + return 0; + } +#endif + + coPos.X = 0; + coPos.Y = 0; + + hOutput = GetStdHandle(STD_OUTPUT_HANDLE); + FillConsoleOutputAttribute(hOutput, csbi.wAttributes, + State->maxx * State->maxy, + coPos, &dwWritten); + FillConsoleOutputCharacter(hOutput, ' ', + State->maxx * State->maxy, + coPos, &dwWritten); + SetConsoleCursorPosition(hOutput, coPos); +#endif + + 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"); +} + +static +INT +CommandDumpSector( + 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 (!strncmp(param, "/?", 2)) + { + CONSOLE_ConOutPrintf("DUMPSECT DiskNumber Sector\n\nDumps a disk sector to the screen.\n\n"); + 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 * + DiskGeometry.TracksPerCylinder, + 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; +} + + +static +INT +CommandExit( + PCONSOLE_STATE State, + LPSTR param) +{ +#if 0 + if (!strncmp(param, "/?", 2)) + { + ConOutResPaging(TRUE,STRING_EXIT_HELP); + /* Just make sure */ + bExit = FALSE; + /* Dont exit */ + return 0; + } +#endif + + State->bExit = TRUE; + + return 0; +} + + +static +INT +CommandHelp( + PCONSOLE_STATE State, + LPSTR param) +{ + CONSOLE_ConOutPrintf("CLS\n"); + CONSOLE_ConOutPrintf("DUMPSECTOR\n"); + CONSOLE_ConOutPrintf("EXIT\n"); + CONSOLE_ConOutPrintf("HELP\n"); + CONSOLE_ConOutPrintf("\n"); + + return 0; +} + + +static +VOID +ClearCommandLine( + 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); +} + + +static +BOOL +ReadCommand( + 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++] = '\n'; + 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 = 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; +} + + +static +BOOL +IsDelimiter( + CHAR c) +{ + return (c == '/' || c == '=' || c == '\0' || isspace(c)); +} + + +static +VOID +DoCommand( + 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 (strcmp(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 + } + } +} + + +VOID +RecoveryConsole(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 */
Propchange: trunk/reactos/base/setup/usetup/cmdcons.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/base/setup/usetup/cmdcons.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/cmdcons.h... ============================================================================== --- trunk/reactos/base/setup/usetup/cmdcons.h (added) +++ trunk/reactos/base/setup/usetup/cmdcons.h [iso-8859-1] Sat Dec 20 21:58:22 2014 @@ -0,0 +1,12 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/cmdcons.h + * PURPOSE: Recovery console + * PROGRAMMER: Eric Kohl + */ + +VOID +RecoveryConsole(VOID); + +/* EOF */
Propchange: trunk/reactos/base/setup/usetup/cmdcons.h ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/base/setup/usetup/interface/consup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/interface... ============================================================================== --- trunk/reactos/base/setup/usetup/interface/consup.c [iso-8859-1] (original) +++ trunk/reactos/base/setup/usetup/interface/consup.c [iso-8859-1] Sat Dec 20 21:58:22 2014 @@ -134,6 +134,19 @@ return FlushConsoleInputBuffer(StdInput); }
+VOID +CONSOLE_GetCursorXY( + PSHORT x, + PSHORT y) +{ + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + + *x = csbi.dwCursorPosition.X; + *y = csbi.dwCursorPosition.Y; +} + SHORT CONSOLE_GetCursorX(VOID) {
Modified: trunk/reactos/base/setup/usetup/interface/consup.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/interface... ============================================================================== --- trunk/reactos/base/setup/usetup/interface/consup.h [iso-8859-1] (original) +++ trunk/reactos/base/setup/usetup/interface/consup.h [iso-8859-1] Sat Dec 20 21:58:22 2014 @@ -79,6 +79,11 @@ BOOL CONSOLE_Flush(VOID);
+VOID +CONSOLE_GetCursorXY( + PSHORT x, + PSHORT y); + SHORT CONSOLE_GetCursorX(VOID);
Modified: trunk/reactos/base/setup/usetup/interface/usetup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/interface... ============================================================================== --- trunk/reactos/base/setup/usetup/interface/usetup.c [iso-8859-1] (original) +++ trunk/reactos/base/setup/usetup/interface/usetup.c [iso-8859-1] Sat Dec 20 21:58:22 2014 @@ -30,6 +30,7 @@
#include "bootsup.h" #include "chkdsk.h" +#include "cmdcons.h" #include "format.h" #include "drivesup.h" #include "settings.h" @@ -989,7 +990,7 @@ } else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */ { - return INTRO_PAGE; + return RECOVERY_PAGE; } else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */ @@ -4133,7 +4134,7 @@ CONSOLE_SetCursorType(TRUE, FALSE);
Page = START_PAGE; - while (Page != REBOOT_PAGE) + while (Page != REBOOT_PAGE && Page != RECOVERY_PAGE) { CONSOLE_ClearScreen(); CONSOLE_Flush(); @@ -4281,10 +4282,14 @@ Page = QuitPage(&Ir); break;
+ case RECOVERY_PAGE: case REBOOT_PAGE: break; } } + + if (Page == RECOVERY_PAGE) + RecoveryConsole();
FreeConsole();
Modified: trunk/reactos/base/setup/usetup/native/utils/console.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/native/ut... ============================================================================== --- trunk/reactos/base/setup/usetup/native/utils/console.c [iso-8859-1] (original) +++ trunk/reactos/base/setup/usetup/native/utils/console.c [iso-8859-1] Sat Dec 20 21:58:22 2014 @@ -285,19 +285,44 @@ COORD *pCoord; PCHAR pText; NTSTATUS Status; - ULONG i; +// ULONG i; + + UNICODE_STRING UnicodeString; + OEM_STRING OemString; + ULONG OemLength; + + UnicodeString.Length = nLength * sizeof(WCHAR); + UnicodeString.MaximumLength = nLength * sizeof(WCHAR); + UnicodeString.Buffer = (LPWSTR)lpCharacter; + + OemLength = RtlUnicodeStringToOemSize(&UnicodeString); +
Buffer = (CHAR*)RtlAllocateHeap(ProcessHeap, 0, - nLength + sizeof(COORD)); + OemLength + sizeof(COORD)); +// nLength + sizeof(COORD)); + if (Buffer== NULL) + return FALSE; + pCoord = (COORD *)Buffer; pText = (PCHAR)(pCoord + 1);
*pCoord = dwWriteCoord;
+ OemString.Length = 0; + OemString.MaximumLength = OemLength; + OemString.Buffer = pText; + + Status = RtlUnicodeStringToOemString(&OemString, + &UnicodeString, + FALSE); + if (!NT_SUCCESS(Status)) + goto done; + /* FIXME: use real unicode->oem conversion */ - for (i = 0; i < nLength; i++) - pText[i] = (CHAR)lpCharacter[i]; +// for (i = 0; i < nLength; i++) +// pText[i] = (CHAR)lpCharacter[i];
Status = NtDeviceIoControlFile(hConsoleOutput, NULL, @@ -310,6 +335,7 @@ Buffer, nLength + sizeof(COORD));
+done: RtlFreeHeap(ProcessHeap, 0, Buffer); if (!NT_SUCCESS(Status)) return FALSE;
Modified: trunk/reactos/base/setup/usetup/usetup.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/usetup.h?... ============================================================================== --- trunk/reactos/base/setup/usetup/usetup.h [iso-8859-1] (original) +++ trunk/reactos/base/setup/usetup/usetup.h [iso-8859-1] Sat Dec 20 21:58:22 2014 @@ -153,6 +153,7 @@ QUIT_PAGE, FLUSH_PAGE, REBOOT_PAGE, /* virtual page */ + RECOVERY_PAGE, /* virtual page */ } PAGE_NUMBER, *PPAGE_NUMBER; #endif