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/CMakeLis…
==============================================================================
--- 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.…
==============================================================================
--- 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.…
==============================================================================
--- 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/interfac…
==============================================================================
--- 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/interfac…
==============================================================================
--- 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/interfac…
==============================================================================
--- 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/u…
==============================================================================
--- 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