Patch by Anton Yarotsky:
authorSir Richard <sir_richard@svn.reactos.org>
Wed, 15 Sep 2010 18:30:06 +0000 (18:30 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Wed, 15 Sep 2010 18:30:06 +0000 (18:30 +0000)
[NTOSKRNL]: Implement CmdPutString command, and add log message types. Kernel version/build, processor, and RAM, now appear on EMS screen (due to InbvDisplayString), as well as loaded drivers. Next steps are to support log entries and a flag to route debug output (a ReactOS-specific feature request).

svn path=/trunk/; revision=48778

reactos/ntoskrnl/ex/hdlsterm.c
reactos/ntoskrnl/include/internal/hdl.h

index c36b058..6d52a58 100644 (file)
@@ -20,7 +20,7 @@ PHEADLESS_GLOBALS HeadlessGlobals;
 VOID
 NTAPI
 HdlspSendStringAtBaud(
-       IN PCHAR String
+       IN PUCHAR String
        )
 {
        /* Send every byte */
@@ -51,8 +51,8 @@ HdlspEnableTerminal(
         if (!HeadlessGlobals->TerminalEnabled) return STATUS_UNSUCCESSFUL;
 
                /* Cleanup the screen and reset the cursor */
-               HdlspSendStringAtBaud("\x1B[2J");
-               HdlspSendStringAtBaud("\x1B[H");
+               HdlspSendStringAtBaud((PUCHAR)"\x1B[2J");
+               HdlspSendStringAtBaud((PUCHAR)"\x1B[H");
 
                /* Enable FIFO */
                InbvPortEnableFifo(HeadlessGlobals->TerminalPort, TRUE);
@@ -109,6 +109,10 @@ HeadlessInit(
        /* Log entries are not yet supported */
        DPRINT1("FIXME: No Headless logging support\n");
 
+       /* Allocate temporary buffer */
+       HeadlessGlobals->TmpBuffer = ExAllocatePoolWithTag(NonPagedPool, 80, 'sldH');
+       if (!HeadlessGlobals->TmpBuffer) return;
+
        /* Windows seems to apply some special hacks for 9600 bps */
        if (HeadlessGlobals->TerminalBaudRate == 9600)
        {
@@ -119,6 +123,77 @@ HeadlessInit(
        HdlspEnableTerminal(TRUE);
 }
 
+VOID
+NTAPI
+HdlspPutString(
+       IN PUCHAR String
+       )
+{
+       PUCHAR Dest = HeadlessGlobals->TmpBuffer;
+       UCHAR Char = 0;
+
+       /* Scan each character */
+       while (*String != ANSI_NULL)
+       {
+               /* Check for rotate, send existing buffer and restart from where we are */
+               if (Dest >= &HeadlessGlobals->TmpBuffer[79])
+               {
+                       HeadlessGlobals->TmpBuffer[79] = ANSI_NULL;
+                       HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer);
+                       Dest = HeadlessGlobals->TmpBuffer;
+               }
+               else
+               {
+                       /* Get the current character and check for special graphical chars */
+                       Char = *String;
+                       if (Char & 0x80)
+                       {
+                               switch (Char)
+                               {
+                                       case 0xB0: case 0xB3: case 0xBA:
+                                               Char = '|';
+                                               break;
+                                       case 0xB1: case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+                                               Char = '%';
+                                               break;
+                                       case 0xB2: case 0xDB:
+                                               Char = '#';
+                                               break;
+                                       case 0xA9: case 0xAA: case 0xBB: case 0xBC: case 0xBF:
+                                       case 0xC0: case 0xC8: case 0xC9: case 0xD9: case 0xDA:
+                                               Char = '+';
+                                               break;
+                                       case 0xC4:
+                                               Char = '-';
+                                               break;
+                                       case 0xCD:
+                                               Char = '=';
+                                               break;
+                                       }
+                       }
+
+                       /* Anything else must be Unicode */
+                       if (Char & 0x80)
+                       {
+                               /* Can't do Unicode yet */
+                               UNIMPLEMENTED;
+                       }
+                       else
+                       {
+                               /* Add the modified char to the temporary buffer */
+                               *Dest++ = Char;
+                       }
+                       
+                       /* Check the next char */
+                       String++;
+               }
+       }
+
+       /* Finish and send */
+       *Dest = ANSI_NULL;
+       HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer);
+}
+
 /*
  * @unimplemented
  */
@@ -132,8 +207,107 @@ HeadlessDispatch(
     OUT PSIZE_T OutputBufferSize
        )
 {
+       NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
+       ASSERT(HeadlessGlobals != NULL);
+//     ASSERT(HeadlessGlobals->PageLockHandle != NULL);
+       
+       /* FIXME: This should be using the headless spinlock */
+       
+       /* Ignore non-reentrant commands */
+       if ((Command != HeadlessCmdAddLogEntry) &&
+               (Command != HeadlessCmdStartBugCheck) &&
+               (Command != HeadlessCmdSendBlueScreenData) &&
+               (Command != HeadlessCmdDoBugCheckProcessing))
+       {
+               if (HeadlessGlobals->ProcessingCmd) return STATUS_UNSUCCESSFUL;
+
+               /* Don't allow these commands next time */
+               HeadlessGlobals->ProcessingCmd = TRUE;
+       }
+       
+       /* Handle each command */
+       switch (Command)
+       {
+               case HeadlessCmdEnableTerminal:
+                       break;
+               case HeadlessCmdCheckForReboot:
+                       break;
+
+               case HeadlessCmdPutString:
+
+                       /* Validate the existence of an input buffer */
+                       if (!InputBuffer)
+                       {
+                               Status = STATUS_INVALID_PARAMETER;
+                               goto Reset;
+                       }
+                       
+                       /* Terminal should be on */
+                       if (HeadlessGlobals->TerminalEnabled)
+                       {
+                               /* Print each byte in the string making sure VT100 chars are used */
+                               PHEADLESS_CMD_PUT_STRING PutString = (PVOID)InputBuffer;
+                               HdlspPutString(PutString->String);
+                       }
+                       
+                       /* Return success either way */
+                       Status = STATUS_SUCCESS;
+                       break;
+               case HeadlessCmdClearDisplay:
+                       break;
+               case HeadlessCmdClearToEndOfDisplay:
+                       break;
+               case HeadlessCmdClearToEndOfLine:
+                       break;
+               case HeadlessCmdDisplayAttributesOff:
+                       break;
+               case HeadlessCmdDisplayInverseVideo:
+                       break;
+               case HeadlessCmdSetColor:
+                       break;
+               case HeadlessCmdPositionCursor:
+                       break;
+               case HeadlessCmdTerminalPoll:
+                       break;
+               case HeadlessCmdGetByte:
+                       break;
+               case HeadlessCmdGetLine:
+                       break;
+               case HeadlessCmdStartBugCheck:
+                       break;
+               case HeadlessCmdDoBugCheckProcessing:
+                       break;
+               case HeadlessCmdQueryInformation:
+                       break;
+               case HeadlessCmdAddLogEntry:
+                       break;
+               case HeadlessCmdDisplayLog:
+                       break;
+               case HeadlessCmdSetBlueScreenData:
+                       break;
+               case HeadlessCmdSendBlueScreenData:
+                       break;
+               case HeadlessCmdQueryGUID:
+                       break;
+               case HeadlessCmdPutData:
+                       break;
+               default:
+                       break;
+       }
+
+Reset:
+       /* Unset prcessing state */
+       if ((Command != HeadlessCmdAddLogEntry) &&
+               (Command != HeadlessCmdStartBugCheck) &&
+               (Command != HeadlessCmdSendBlueScreenData) &&
+               (Command != HeadlessCmdDoBugCheckProcessing))
+       {
+               ASSERT(HeadlessGlobals->ProcessingCmd == TRUE);
+               HeadlessGlobals->ProcessingCmd = FALSE;
+    }
+
        //UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
+       return STATUS_SUCCESS;
 }
 
 /* EOF */
index 5afd40f..c38aa3f 100644 (file)
 #define HDLTRACE(x, ...) DPRINT(__VA_ARGS__)
 #endif
 
+//
+// Well-known messages that Io and Pnp post to the kernel log
+//
+typedef enum _HEADLESS_LOG_MESSAGE
+{
+       HeadlessLogDriverLoad = 1,
+       HeadlessLogDriverSuccess,
+       HeadlessLogDriverFailed,
+       HeadlessLogEventFailed,
+       HeadlessLogObjectFailed,
+       HeadlessLogDirectoryFailed,
+       HeadlessLogPnpFailed,
+       HeadlessLogPnpFailed2,
+       HeadlessLogBootDriversFailed,
+       HeadlessLogNtdllFailed,
+       HeadlessLogSystemDriversFailed,
+       HeadlessLogReassignSystemRootFailed,
+       HeadlessLogProtectSystemRootFailed,
+       HeadlessLogConvertSystemRootFailed,
+       HeadlessLogConvertDeviceNameFailed,
+       HeadlessLogGroupOrderListFailed,
+       HeadlessLogGroupTableFailed
+       //
+       // There are more, but not applicable to ReactOS, I believe
+       //
+} HEADLESS_LOG_MESSAGE;
+
 //
 // Headless Log Entry
 //
@@ -123,6 +150,11 @@ typedef enum _HEADLESS_CMD
        HeadlessCmdPutData
 } HEADLESS_CMD, *PHEADLESS_CMD;
 
+typedef struct _HEADLESS_CMD_PUT_STRING
+{
+       UCHAR String[1];
+} HEADLESS_CMD_PUT_STRING, *PHEADLESS_CMD_PUT_STRING;
+
 NTSTATUS
 NTAPI
 HeadlessDispatch(