ReactOS 0.4.16-dev-2473-gb34a1f1
headless.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * PURPOSE: Provides support for Windows Emergency Management Services
5 * COPYRIGHT: Copyright 2010 ReactOS Portable Systems Group
6 * Copyright 2022-2026 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <freeldr.h>
12#include <cportlib/cportlib.h>
13#include <cportlib/uartinfo.h>
14#include "ntldropts.h"
15
16#include <debug.h> // For _WARN()
17
18/* Note: Move these to some smbios.h header */
19#define SYSID_TYPE_UUID "_UUID_"
20#define SYSID_UUID_DATA_SIZE 16
21#include <pshpack1.h>
22typedef struct _SYSID_UUID_ENTRY
23{
29#include <poppack.h>
30
31/* GLOBALS ********************************************************************/
32
37
39{
40 {NULL, 0, TRUE},
41 {NULL, 0, TRUE},
42 {NULL, 0, TRUE},
43 {NULL, 0, TRUE}
44};
45
46/* FUNCTIONS ******************************************************************/
47
48VOID
50 _Out_ PGUID SystemGuid)
51{
52#if (defined(_M_IX86) || defined(_M_AMD64)) && !defined(UEFIBOOT)
53 PSYSID_UUID_ENTRY CurrentAddress;
54
55 CurrentAddress = (PSYSID_UUID_ENTRY)0xE0000;
56 while (CurrentAddress < (PSYSID_UUID_ENTRY)0x100000)
57 {
58 if (RtlCompareMemory(&CurrentAddress->Type, SYSID_TYPE_UUID, 6) == 6)
59 {
60 RtlCopyMemory(SystemGuid, &CurrentAddress->UUID, SYSID_UUID_DATA_SIZE);
61 return;
62 }
63 CurrentAddress = (PSYSID_UUID_ENTRY)((ULONG_PTR)CurrentAddress + 1);
64 }
65#else
66 _WARN("WinLdrLoadGUID needs SMBIOS table reading implementation on this platform!");
67#endif
68
70}
71
72/* NOTE: This function mirrors nt!inbvport.c:InbvPortInitialize() */
75 _In_ ULONG BaudRate,
77 _In_ PUCHAR PortAddress,
78 _In_ BOOLEAN TerminalConnected,
79 _Out_ PULONG PortId)
80{
81 /* Set the default baud rate */
82 if (BaudRate == 0)
83 BaudRate = DEFAULT_BAUD_RATE;
84
85 /* Check if the port or address is given */
86 if (PortNumber)
87 {
88 /* Pick correct address for port */
89 if (!PortAddress)
90 {
91 if (PortNumber < 1 || PortNumber > MAX_COM_PORTS)
93 PortAddress = UlongToPtr(BaseArray[PortNumber]);
94 }
95 }
96 else
97 {
98 /* Pick correct port for address */
99#if defined(SARCH_PC98)
100 static const ULONG TestPorts[] = {1, 2};
101#else
102 static const ULONG TestPorts[] = {2, 1};
103#endif
104 PortAddress = UlongToPtr(BaseArray[TestPorts[0]]);
105 if (CpDoesPortExist(PortAddress))
106 {
107 PortNumber = TestPorts[0];
108 }
109 else
110 {
111 PortAddress = UlongToPtr(BaseArray[TestPorts[1]]);
112 if (!CpDoesPortExist(PortAddress))
113 return FALSE;
114 PortNumber = TestPorts[1];
115 }
116 }
117
118 /* Not yet supported */
120
121 /* Check if port exists */
122 if (CpDoesPortExist(PortAddress))
123 {
124 /* Initialize port for the first time, or re-initialize if specified */
125 if (!!TerminalConnected == (Port[PortNumber - 1].Address != NULL))
126 {
127 /* Initialize the port and return it */
128 CpInitialize(&Port[PortNumber - 1], PortAddress, BaudRate);
129 *PortId = PortNumber - 1;
130 return TRUE;
131 }
132 }
133
134 return FALSE;
135}
136
137VOID
139 _In_ ULONG PortId,
141{
142 CpPutByte(&Port[PortId], Byte);
143}
144
147 _In_ ULONG PortId,
149{
150 return CpGetByte(&Port[PortId], Byte, TRUE, FALSE) == CP_GET_SUCCESS;
151}
152
155 _In_ ULONG PortId)
156{
157 UCHAR Dummy;
158
159 return CpGetByte(&Port[PortId], &Dummy, FALSE, TRUE) == CP_GET_SUCCESS;
160}
161
162VOID
164 _In_ ULONG PortId,
166{
168}
169
170VOID
172{
173 ULONG PortNumber, BaudRate;
174 PUCHAR PortAddress;
175 PCSTR AnsiReset = "\x1B[m";
176 ULONG i;
177
181
182 /* Pick a port address */
183 if (PortNumber)
184 {
185 if (!PortAddress)
186 {
187 if (PortNumber < 1 || PortNumber > MAX_COM_PORTS)
188 PortNumber = 1;
190 }
191 }
192 else
193 {
194 /* No number, so no EMS */
196 return;
197 }
198
199 /* Call arch code to initialize the port */
203 PortAddress,
207 {
208 /* Port seems usable, set it up and get the BIOS GUID */
210
212
213 /* Calculate delay in us based on the baud, assume 9600 if none given */
214 if (!BaudRate)
215 {
216 BaudRate = 9600;
218 }
219
220 WinLdrTerminalDelay = (10 * 1000 * 1000) / (BaudRate / 10) / 6;
221
222 /* Send an ANSI reset sequence to get the terminal up and running */
223 for (i = 0; i < strlen(AnsiReset); i++)
224 {
227 }
228 }
229}
230
231VOID
233 _In_ PCSTR BootOptions)
234{
235 PCSTR Option;
236
237 /* Start fresh */
240
241 /* Use a direction port if one was given, or use ACPI to detect one instead */
242 Option = NtLdrGetOption(BootOptions, "redirect=");
243 if (Option)
244 {
245 Option += 9;
246 if (_strnicmp(Option, "com", 3) == 0)
247 {
248 Option += 3;
251 }
252 else if (_strnicmp(Option, "usebiossettings", 15) == 0)
253 {
254 // FIXME: TODO!
255 UiDrawStatusText("ACPI SRT/SPCR Table Not Supported...");
256 return;
257 }
258 else
259 {
260#ifdef _WIN64
261#define strtoulptr strtoull
262#else
263#define strtoulptr strtoul
264#endif
268 }
269 }
270
271 /* Use a direction baudrate if one was given */
272 Option = NtLdrGetOption(BootOptions, "redirectbaudrate=");
273 if (Option)
274 {
275 Option += 17;
276 // LoaderRedirectionInformation.BaudRate = atoi(Option);
277 if (strncmp(Option, "115200", 6) == 0)
278 {
280 }
281 else if (strncmp(Option, "57600", 5) == 0)
282 {
284 }
285 else if (strncmp(Option, "19200", 5) == 0)
286 {
288 }
289 else
290 {
292 }
293 }
294
295 /* Enable headless support if parameters were found */
297 {
299 {
301 }
302
304 }
305}
306
307/* EOF */
Type
Definition: Type.h:7
unsigned char BOOLEAN
Definition: actypes.h:127
#define _WARN(msg)
Definition: debug.h:135
VOID UiDrawStatusText(PCSTR StatusText)
Definition: ui.c:286
USHORT NTAPI CpGetByte(_Inout_ PCPPORT Port, _Out_ PUCHAR Byte, _In_ BOOLEAN Wait, _In_ BOOLEAN Poll)
Definition: cport.c:82
#define CP_GET_SUCCESS
Definition: cportlib.h:17
VOID NTAPI CpPutByte(_Inout_ PCPPORT Port, _In_ UCHAR Byte)
Definition: cport.c:93
NTSTATUS NTAPI CpInitialize(_Inout_ PCPPORT Port, _In_ PUCHAR Address, _In_ ULONG BaudRate)
Definition: cport.c:59
BOOLEAN NTAPI CpDoesPortExist(_In_ PUCHAR Address)
Definition: cport.c:33
VOID NTAPI CpEnableFifo(_In_ PUCHAR Address, _In_ BOOLEAN Enable)
Definition: cport.c:41
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
unsigned char Byte
Definition: zlib.h:37
_ACRTIMP int __cdecl atoi(const char *)
Definition: string.c:1715
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP int __cdecl strncmp(const char *, const char *, size_t)
Definition: string.c:3330
#define UlongToPtr(u)
Definition: config.h:106
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
CPPORT Port[4]
Definition: headless.c:38
#define strtoulptr
VOID WinLdrSetupEms(_In_ PCSTR BootOptions)
Definition: headless.c:232
#define SYSID_UUID_DATA_SIZE
Definition: headless.c:20
struct _SYSID_UUID_ENTRY SYSID_UUID_ENTRY
VOID WinLdrPortPutByte(_In_ ULONG PortId, _In_ UCHAR Byte)
Definition: headless.c:138
VOID WinLdrInitializeHeadlessPort(VOID)
Definition: headless.c:171
VOID WinLdrLoadGUID(_Out_ PGUID SystemGuid)
Definition: headless.c:49
#define SYSID_TYPE_UUID
Definition: headless.c:19
BOOLEAN WinLdrPortInitialize(_In_ ULONG BaudRate, _In_ ULONG PortNumber, _In_ PUCHAR PortAddress, _In_ BOOLEAN TerminalConnected, _Out_ PULONG PortId)
Definition: headless.c:74
VOID WinLdrEnableFifo(_In_ ULONG PortId, _In_ BOOLEAN Enable)
Definition: headless.c:163
ULONG WinLdrTerminalDeviceId
Definition: headless.c:35
struct _SYSID_UUID_ENTRY * PSYSID_UUID_ENTRY
HEADLESS_LOADER_BLOCK LoaderRedirectionInformation
Definition: headless.c:33
BOOLEAN WinLdrPortGetByte(_In_ ULONG PortId, _Out_ PUCHAR Byte)
Definition: headless.c:146
ULONG WinLdrTerminalDelay
Definition: headless.c:36
BOOLEAN WinLdrPortPollOnly(_In_ ULONG PortId)
Definition: headless.c:154
BOOLEAN WinLdrTerminalConnected
Definition: headless.c:34
#define MAX_COM_PORTS
Definition: machpc.c:29
#define ASSERT(a)
Definition: mode.c:44
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
PCSTR NtLdrGetOption(IN PCSTR Options, IN PCSTR OptionName)
Definition: ntldropts.c:128
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
ULONG PortNumber
Definition: storport.c:18
UCHAR IsMMIODevice
Definition: arc.h:443
PUCHAR PortAddress
Definition: arc.h:435
USHORT PciDeviceId
Definition: arc.h:436
UCHAR TerminalType
Definition: arc.h:444
Definition: headless.c:23
UCHAR Checksum
Definition: headless.c:25
UCHAR UUID[SYSID_UUID_DATA_SIZE]
Definition: headless.c:27
USHORT Length
Definition: headless.c:26
UCHAR Type[6]
Definition: headless.c:24
uint32_t * PULONG
Definition: typedefs.h:59
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define DEFAULT_BAUD_RATE
Definition: uartinfo.h:24
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3603
unsigned char UCHAR
Definition: xmlstorage.h:181