* PROGRAMMERS: ReactOS Portable Systems Group
*/
-/* INCLUDES ******************************************************************/
+/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
#include <debug.h>
-/* GLOBALS *******************************************************************/
+/* GLOBALS ********************************************************************/
PHEADLESS_GLOBALS HeadlessGlobals;
-/* FUNCTIONS *****************************************************************/
+/* FUNCTIONS ******************************************************************/
+
+FORCEINLINE
+KIRQL
+HdlspAcquireGlobalLock(VOID)
+{
+ KIRQL OldIrql;
+
+ /* Don't acquire the lock if we are bugchecking */
+ if (!HeadlessGlobals->InBugCheck)
+ {
+ KeAcquireSpinLock(&HeadlessGlobals->SpinLock, &OldIrql);
+ }
+ else
+ {
+ OldIrql = 0xFF;
+ }
+
+ return OldIrql;
+}
+
+FORCEINLINE
+VOID
+HdlspReleaseGlobalLock(IN KIRQL OldIrql)
+{
+ /* Only release the lock if we aren't bugchecking */
+ if (OldIrql != 0xFF)
+ {
+ KeReleaseSpinLock(&HeadlessGlobals->SpinLock, OldIrql);
+ }
+ else
+ {
+ ASSERT(HeadlessGlobals->InBugCheck == TRUE);
+ }
+}
VOID
NTAPI
-HdlspSendStringAtBaud(
- IN PUCHAR String
- )
+HdlspSendStringAtBaud(IN PUCHAR String)
{
- /* Send every byte */
- while (*String++ != ANSI_NULL)
- {
- InbvPortPutByte(HeadlessGlobals->TerminalPort, *String);
- }
+ /* Send every byte */
+ while (*String != ANSI_NULL)
+ {
+ InbvPortPutByte(HeadlessGlobals->TerminalPort, *String++);
+ }
}
-NTSTATUS
+VOID
NTAPI
-HdlspEnableTerminal(
- IN BOOLEAN Enable
- )
+HdlspPutData(IN PUCHAR Data,
+ IN ULONG DataSize)
{
- /* Enable if requested, as long as this isn't a PCI serial port crashing */
- if ((Enable) &&
- !(HeadlessGlobals->TerminalEnabled) &&
- !((HeadlessGlobals->IsMMIODevice) && (HeadlessGlobals->InBugCheck)))
- {
- /* Initialize the COM port with cportlib */
- HeadlessGlobals->TerminalEnabled = InbvPortInitialize(
- HeadlessGlobals->TerminalBaudRate,
- HeadlessGlobals->TerminalPortNumber,
- HeadlessGlobals->TerminalPortAddress,
- &HeadlessGlobals->TerminalPort,
- HeadlessGlobals->IsMMIODevice);
- if (!HeadlessGlobals->TerminalEnabled) return STATUS_UNSUCCESSFUL;
-
- /* Cleanup the screen and reset the cursor */
- HdlspSendStringAtBaud((PUCHAR)"\x1B[2J");
- HdlspSendStringAtBaud((PUCHAR)"\x1B[H");
-
- /* Enable FIFO */
- InbvPortEnableFifo(HeadlessGlobals->TerminalPort, TRUE);
- }
- else if (!Enable)
- {
- /* Specific case when headless is being disabled */
- InbvPortTerminate(HeadlessGlobals->TerminalPort);
- HeadlessGlobals->TerminalPort = 0;
- HeadlessGlobals->TerminalEnabled = FALSE;
- }
- return STATUS_SUCCESS;
+ ULONG i;
+ for (i = 0; i < DataSize; i++)
+ {
+ InbvPortPutByte(HeadlessGlobals->TerminalPort, Data[i]);
+ }
}
VOID
NTAPI
-INIT_FUNCTION
-HeadlessInit(
- IN PLOADER_PARAMETER_BLOCK LoaderBlock
- )
+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);
+}
+
+NTSTATUS
+NTAPI
+HdlspEnableTerminal(IN BOOLEAN Enable)
{
- PHEADLESS_LOADER_BLOCK HeadlessBlock;
-
- HeadlessBlock = LoaderBlock->Extension->HeadlessLoaderBlock;
- if (!HeadlessBlock) return;
- if ((HeadlessBlock->PortNumber > 4) && (HeadlessBlock->UsedBiosSettings)) return;
-
- HeadlessGlobals = ExAllocatePoolWithTag(
- NonPagedPool,
- sizeof(HEADLESS_GLOBALS),
- 'sldH');
- if (!HeadlessGlobals) return;
-
- /* Zero and copy loader data */
- RtlZeroMemory(HeadlessGlobals, sizeof(HEADLESS_GLOBALS));
- HeadlessGlobals->TerminalPortNumber = HeadlessBlock->PortNumber;
- HeadlessGlobals->TerminalPortAddress = HeadlessBlock->PortAddress;
- HeadlessGlobals->TerminalBaudRate = HeadlessBlock->BaudRate;
- HeadlessGlobals->TerminalParity = HeadlessBlock->Parity;
- HeadlessGlobals->TerminalStopBits = HeadlessBlock->StopBits;
- HeadlessGlobals->UsedBiosSettings = HeadlessBlock->UsedBiosSettings;
- HeadlessGlobals->IsMMIODevice = HeadlessBlock->IsMMIODevice;
- HeadlessGlobals->TerminalType = HeadlessBlock->TerminalType;
- HeadlessGlobals->SystemGUID = HeadlessBlock->SystemGUID;
-
- /* These two are opposites of each other */
- if (HeadlessGlobals->IsMMIODevice) HeadlessGlobals->IsNonLegacyDevice = TRUE;
-
- /* Check for a PCI device, warn that this isn't supported */
- if (HeadlessBlock->PciDeviceId != PCI_INVALID_VENDORID)
- {
- DPRINT1("PCI Serial Ports not supported\n");
- }
-
- /* 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)
- {
- DPRINT1("Please use other baud rate than 9600bps for now\n");
- }
-
- /* Enable the terminal */
- HdlspEnableTerminal(TRUE);
+ /* Enable if requested, as long as this isn't a PCI serial port crashing */
+ if ((Enable) &&
+ !(HeadlessGlobals->TerminalEnabled) &&
+ !((HeadlessGlobals->IsMMIODevice) && (HeadlessGlobals->InBugCheck)))
+ {
+ /* Initialize the COM port with cportlib */
+ HeadlessGlobals->TerminalEnabled = InbvPortInitialize(HeadlessGlobals->TerminalBaudRate,
+ HeadlessGlobals->TerminalPortNumber,
+ HeadlessGlobals->TerminalPortAddress,
+ &HeadlessGlobals->TerminalPort,
+ HeadlessGlobals->IsMMIODevice);
+ if (!HeadlessGlobals->TerminalEnabled)
+ {
+ DPRINT1("Failed to initialize port through cportlib\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Cleanup the screen and reset the cursor */
+ HdlspSendStringAtBaud((PUCHAR)"\x1B[2J");
+ HdlspSendStringAtBaud((PUCHAR)"\x1B[H");
+
+ /* Enable FIFO */
+ InbvPortEnableFifo(HeadlessGlobals->TerminalPort, TRUE);
+ }
+ else if (!Enable)
+ {
+ /* Specific case when headless is being disabled */
+ InbvPortTerminate(HeadlessGlobals->TerminalPort);
+ HeadlessGlobals->TerminalPort = 0;
+ HeadlessGlobals->TerminalEnabled = FALSE;
+ }
+
+ /* All done */
+ return STATUS_SUCCESS;
}
VOID
NTAPI
-HdlspPutString(
- IN PUCHAR String
- )
+INIT_FUNCTION
+HeadlessInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
- 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);
+ PHEADLESS_LOADER_BLOCK HeadlessBlock;
+
+ /* Only initialize further if the loader found EMS enabled */
+ HeadlessBlock = LoaderBlock->Extension->HeadlessLoaderBlock;
+ if (!HeadlessBlock) return;
+
+ /* Ignore invalid EMS settings */
+ if ((HeadlessBlock->PortNumber > 4) && (HeadlessBlock->UsedBiosSettings)) return;
+
+ /* Allocate the global headless data */
+ HeadlessGlobals = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(*HeadlessGlobals),
+ 'sldH');
+ if (!HeadlessGlobals) return;
+
+ /* Zero and copy loader data */
+ RtlZeroMemory(HeadlessGlobals, sizeof(*HeadlessGlobals));
+ HeadlessGlobals->TerminalPortNumber = HeadlessBlock->PortNumber;
+ HeadlessGlobals->TerminalPortAddress = HeadlessBlock->PortAddress;
+ HeadlessGlobals->TerminalBaudRate = HeadlessBlock->BaudRate;
+ HeadlessGlobals->TerminalParity = HeadlessBlock->Parity;
+ HeadlessGlobals->TerminalStopBits = HeadlessBlock->StopBits;
+ HeadlessGlobals->UsedBiosSettings = HeadlessBlock->UsedBiosSettings;
+ HeadlessGlobals->IsMMIODevice = HeadlessBlock->IsMMIODevice;
+ HeadlessGlobals->TerminalType = HeadlessBlock->TerminalType;
+ HeadlessGlobals->SystemGUID = HeadlessBlock->SystemGUID;
+ DPRINT1("EMS on Port %lu (0x%p) at %lu bps\n",
+ HeadlessGlobals->TerminalPortNumber,
+ HeadlessGlobals->TerminalPortAddress,
+ HeadlessGlobals->TerminalBaudRate);
+
+ /* These two are opposites of each other */
+ if (HeadlessGlobals->IsMMIODevice) HeadlessGlobals->IsNonLegacyDevice = TRUE;
+
+ /* Check for a PCI device, warn that this isn't supported */
+ if (HeadlessBlock->PciDeviceId != PCI_INVALID_VENDORID)
+ {
+ DPRINT1("PCI Serial Ports not supported\n");
+ }
+
+ /* 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)
+ {
+ DPRINT1("Please use other baud rate than 9600bps for now\n");
+ }
+
+ /* Enable the terminal */
+ HdlspEnableTerminal(TRUE);
}
NTSTATUS
NTAPI
-HdlspDispatch(
- IN HEADLESS_CMD Command,
- IN PVOID InputBuffer,
- IN SIZE_T InputBufferSize,
- OUT PVOID OutputBuffer,
- OUT PSIZE_T OutputBufferSize
- )
+HdlspDispatch(IN HEADLESS_CMD Command,
+ IN PVOID InputBuffer,
+ IN SIZE_T InputBufferSize,
+ OUT PVOID OutputBuffer,
+ 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_SUCCESS;
+ KIRQL OldIrql;
+ NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
+ PHEADLESS_RSP_QUERY_INFO HeadlessInfo;
+ PHEADLESS_CMD_PUT_STRING PutString;
+ PHEADLESS_CMD_ENABLE_TERMINAL EnableTerminal;
+ PHEADLESS_CMD_SET_COLOR SetColor;
+ PHEADLESS_CMD_POSITION_CURSOR CursorPos;
+ PHEADLESS_RSP_GET_BYTE GetByte;
+ UCHAR DataBuffer[80];
+
+ ASSERT(HeadlessGlobals != NULL);
+ // ASSERT(HeadlessGlobals->PageLockHandle != NULL);
+
+ /* Ignore non-reentrant commands */
+ if ((Command != HeadlessCmdAddLogEntry) &&
+ (Command != HeadlessCmdStartBugCheck) &&
+ (Command != HeadlessCmdSendBlueScreenData) &&
+ (Command != HeadlessCmdDoBugCheckProcessing))
+ {
+ OldIrql = HdlspAcquireGlobalLock();
+
+ if (HeadlessGlobals->ProcessingCmd)
+ {
+ HdlspReleaseGlobalLock(OldIrql);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Don't allow these commands next time */
+ HeadlessGlobals->ProcessingCmd = TRUE;
+ HdlspReleaseGlobalLock(OldIrql);
+ }
+
+ /* Handle each command */
+ switch (Command)
+ {
+ case HeadlessCmdEnableTerminal:
+ {
+ /* Make sure the caller passed valid data */
+ if (!(InputBuffer) ||
+ (InputBufferSize != sizeof(*EnableTerminal)))
+ {
+ DPRINT1("Invalid buffer\n");
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ /* Go and enable it */
+ EnableTerminal = InputBuffer;
+ Status = HdlspEnableTerminal(EnableTerminal->Enable);
+ break;
+ }
+
+ case HeadlessCmdCheckForReboot:
+ break;
+
+ case HeadlessCmdPutString:
+ {
+ /* Validate the existence of an input buffer */
+ if (!InputBuffer)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ /* Terminal should be on */
+ if (HeadlessGlobals->TerminalEnabled)
+ {
+ /* Print each byte in the string making sure VT100 chars are used */
+ PutString = InputBuffer;
+ HdlspPutString(PutString->String);
+ }
+
+ /* Return success either way */
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ case HeadlessCmdClearDisplay:
+ case HeadlessCmdClearToEndOfDisplay:
+ case HeadlessCmdClearToEndOfLine:
+ case HeadlessCmdDisplayAttributesOff:
+ case HeadlessCmdDisplayInverseVideo:
+ case HeadlessCmdSetColor:
+ case HeadlessCmdPositionCursor:
+ {
+ /* By default return success */
+ Status = STATUS_SUCCESS;
+
+ /* Send the VT100 commands only if the terminal is enabled */
+ if (HeadlessGlobals->TerminalEnabled)
+ {
+ PUCHAR CommandStr = NULL;
+
+ if (Command == HeadlessCmdClearDisplay)
+ CommandStr = (PUCHAR)"\x1B[2J";
+ else if (Command == HeadlessCmdClearToEndOfDisplay)
+ CommandStr = (PUCHAR)"\x1B[0J";
+ else if (Command == HeadlessCmdClearToEndOfLine)
+ CommandStr = (PUCHAR)"\x1B[0K";
+ else if (Command == HeadlessCmdDisplayAttributesOff)
+ CommandStr = (PUCHAR)"\x1B[0m";
+ else if (Command == HeadlessCmdDisplayInverseVideo)
+ CommandStr = (PUCHAR)"\x1B[7m";
+ else if (Command == HeadlessCmdSetColor)
+ {
+ /* Make sure the caller passed valid data */
+ if (!InputBuffer ||
+ (InputBufferSize != sizeof(*SetColor)))
+ {
+ DPRINT1("Invalid buffer\n");
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ SetColor = InputBuffer;
+ Status = RtlStringCbPrintfA((PCHAR)DataBuffer, sizeof(DataBuffer),
+ "\x1B[%d;%dm",
+ SetColor->BkgdColor,
+ SetColor->TextColor);
+ if (!NT_SUCCESS(Status)) break;
+
+ CommandStr = DataBuffer;
+ }
+ else // if (Command == HeadlessCmdPositionCursor)
+ {
+ /* Make sure the caller passed valid data */
+ if (!InputBuffer ||
+ (InputBufferSize != sizeof(*CursorPos)))
+ {
+ DPRINT1("Invalid buffer\n");
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ CursorPos = InputBuffer;
+ /* Cursor position is 1-based */
+ Status = RtlStringCbPrintfA((PCHAR)DataBuffer, sizeof(DataBuffer),
+ "\x1B[%d;%dH",
+ CursorPos->CursorRow + 1,
+ CursorPos->CursorCol + 1);
+ if (!NT_SUCCESS(Status)) break;
+
+ CommandStr = DataBuffer;
+ }
+
+ /* Send the command */
+ HdlspSendStringAtBaud(CommandStr);
+ }
+
+ break;
+ }
+
+ case HeadlessCmdTerminalPoll:
+ break;
+
+ case HeadlessCmdGetByte:
+ {
+ /* Make sure the caller passed valid data */
+ if (!(OutputBuffer) ||
+ !(OutputBufferSize) ||
+ (*OutputBufferSize < sizeof(*GetByte)))
+ {
+ DPRINT1("Invalid buffer\n");
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ /* Make sure the terminal is enabled */
+ GetByte = OutputBuffer;
+ if (HeadlessGlobals->TerminalEnabled)
+ {
+ /* Poll if something is on the wire */
+ if (InbvPortPollOnly(HeadlessGlobals->TerminalPort))
+ {
+ /* If so, read it */
+ InbvPortGetByte(HeadlessGlobals->TerminalPort,
+ &GetByte->Value);
+ }
+ else
+ {
+ /* Nothing is there, return 0 */
+ GetByte->Value = 0;
+ }
+ }
+ else
+ {
+ /* Otherwise return nothing */
+ GetByte->Value = 0;
+ }
+
+ /* Return success either way */
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ case HeadlessCmdGetLine:
+ break;
+ case HeadlessCmdStartBugCheck:
+ break;
+ case HeadlessCmdDoBugCheckProcessing:
+ break;
+
+ case HeadlessCmdQueryInformation:
+ {
+ /* Make sure the caller passed valid data */
+ if (!(OutputBuffer) ||
+ !(OutputBufferSize) ||
+ (*OutputBufferSize < sizeof(*HeadlessInfo)))
+ {
+ DPRINT1("Invalid buffer\n");
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ /* If we got here, headless is enabled -- we know this much */
+ HeadlessInfo = OutputBuffer;
+ HeadlessInfo->PortType = HeadlessSerialPort;
+ HeadlessInfo->Serial.TerminalAttached = TRUE;
+ HeadlessInfo->Serial.UsedBiosSettings = HeadlessGlobals->UsedBiosSettings != 0;
+ HeadlessInfo->Serial.TerminalBaudRate = HeadlessGlobals->TerminalBaudRate;
+ HeadlessInfo->Serial.TerminalType = HeadlessGlobals->TerminalType;
+
+ /* Now check on what port/baud it's enabled on */
+ if ((HeadlessGlobals->TerminalPortNumber >= 1) ||
+ (HeadlessGlobals->UsedBiosSettings))
+ {
+ /* Get the EMS information */
+ HeadlessInfo->Serial.TerminalPort = HeadlessGlobals->
+ TerminalPortNumber;
+ HeadlessInfo->Serial.TerminalPortBaseAddress = HeadlessGlobals->
+ TerminalPortAddress;
+ }
+ else
+ {
+ /* We don't know for sure */
+ HeadlessInfo->Serial.TerminalPort = SerialPortUndefined;
+ HeadlessInfo->Serial.TerminalPortBaseAddress = 0;
+ }
+
+ /* All done */
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ case HeadlessCmdAddLogEntry:
+ break;
+ case HeadlessCmdDisplayLog:
+ break;
+
+ case HeadlessCmdSetBlueScreenData:
+ {
+ /* Validate the existence of an input buffer */
+ if (!InputBuffer)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ /* Lie so that we can get Hdl bringup a little bit further */
+ UNIMPLEMENTED;
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ case HeadlessCmdSendBlueScreenData:
+ break;
+ case HeadlessCmdQueryGUID:
+ break;
+
+ case HeadlessCmdPutData:
+ {
+ /* Validate the existence of an input buffer */
+ if (!(InputBuffer) || !(InputBufferSize))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ /* Terminal should be on */
+ if (HeadlessGlobals->TerminalEnabled)
+ {
+ /* Print each byte in the string making sure VT100 chars are used */
+ PutString = InputBuffer;
+ HdlspPutData(PutString->String, InputBufferSize);
+ }
+
+ /* Return success either way */
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ /* Unset processing state */
+ if ((Command != HeadlessCmdAddLogEntry) &&
+ (Command != HeadlessCmdStartBugCheck) &&
+ (Command != HeadlessCmdSendBlueScreenData) &&
+ (Command != HeadlessCmdDoBugCheckProcessing))
+ {
+ ASSERT(HeadlessGlobals->ProcessingCmd == TRUE);
+ HeadlessGlobals->ProcessingCmd = FALSE;
+ }
+
+ /* All done */
+ return Status;
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
-HeadlessDispatch(
- IN HEADLESS_CMD Command,
- IN PVOID InputBuffer,
- IN SIZE_T InputBufferSize,
- OUT PVOID OutputBuffer,
- OUT PSIZE_T OutputBufferSize
- )
+HeadlessDispatch(IN HEADLESS_CMD Command,
+ IN PVOID InputBuffer,
+ IN SIZE_T InputBufferSize,
+ OUT PVOID OutputBuffer,
+ OUT PSIZE_T OutputBufferSize)
{
- /* Check for stubs that will expect something even with headless off */
- if (!HeadlessGlobals)
- {
- /* Don't allow the SAC to connect */
- if (Command == HeadlessCmdEnableTerminal) return STATUS_UNSUCCESSFUL;
-
- /* Send bogus reply */
- if ((Command == HeadlessCmdQueryInformation) ||
- (Command == HeadlessCmdGetByte) ||
- (Command == HeadlessCmdGetLine) ||
- (Command == HeadlessCmdCheckForReboot) ||
- (Command == HeadlessCmdTerminalPoll))
- {
- if (!(OutputBuffer) || !(OutputBufferSize)) return STATUS_INVALID_PARAMETER;
- RtlZeroMemory(OutputBuffer, *OutputBufferSize);
- }
- return STATUS_SUCCESS;
- }
-
- /* Do the real work */
- return HdlspDispatch(
- Command,
- InputBuffer,
- InputBufferSize,
- OutputBuffer,
- OutputBufferSize);
-}
+ /* Check for stubs that will expect something even with headless off */
+ if (!HeadlessGlobals)
+ {
+ /* Don't allow the SAC to connect */
+ if (Command == HeadlessCmdEnableTerminal) return STATUS_UNSUCCESSFUL;
+
+ /* Send bogus reply */
+ if ((Command == HeadlessCmdQueryInformation) ||
+ (Command == HeadlessCmdGetByte) ||
+ (Command == HeadlessCmdGetLine) ||
+ (Command == HeadlessCmdCheckForReboot) ||
+ (Command == HeadlessCmdTerminalPoll))
+ {
+ if (!(OutputBuffer) || !(OutputBufferSize))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ RtlZeroMemory(OutputBuffer, *OutputBufferSize);
+ }
+
+ return STATUS_SUCCESS;
+ }
+
+ /* Do the real work */
+ return HdlspDispatch(Command,
+ InputBuffer,
+ InputBufferSize,
+ OutputBuffer,
+ OutputBufferSize);
+}
/* EOF */