ReactOS  0.4.15-dev-2100-g9e32854
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  * FILE: boot/freeldr/freeldr/windows/headless.c
5  * PURPOSE: Provides support for Windows Emergency Management Services
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <freeldr.h>
12 #include <cportlib/cportlib.h>
13 #include "ntldropts.h"
14 
15 /* Note: Move these to some smbios.h header */
16 #define SYSID_TYPE_UUID "_UUID_"
17 #define SYSID_UUID_DATA_SIZE 16
18 #include <pshpack1.h>
19 typedef struct _SYSID_UUID_ENTRY
20 {
21  UCHAR Type[6];
26 #include <poppack.h>
27 
28 /* GLOBALS ********************************************************************/
29 
34 
36 {
37  {NULL, 0, TRUE},
38  {NULL, 0, TRUE},
39  {NULL, 0, TRUE},
40  {NULL, 0, TRUE}
41 };
42 
43 /* FUNCTIONS ******************************************************************/
44 
45 VOID
47 {
48  PSYSID_UUID_ENTRY CurrentAddress;
49 
50  CurrentAddress = (PSYSID_UUID_ENTRY)0xE0000;
51  while (CurrentAddress < (PSYSID_UUID_ENTRY)0x100000)
52  {
53  if (RtlCompareMemory(&CurrentAddress->Type, SYSID_TYPE_UUID, 6) == 6)
54  {
55  RtlCopyMemory(SystemGuid, &CurrentAddress->UUID, SYSID_UUID_DATA_SIZE);
56  return;
57  }
58  CurrentAddress = (PSYSID_UUID_ENTRY)((ULONG_PTR)CurrentAddress + 1);
59  }
60 
62 }
63 
64 BOOLEAN
67  IN PUCHAR PortAddress,
68  IN BOOLEAN TerminalConnected,
69  OUT PULONG PortId)
70 {
71 #if defined(SARCH_PC98)
72  /* Set default baud rate */
73  if (BaudRate == 0) BaudRate = 9600;
74 
75  /* Check if port or address given */
76  if (PortNumber)
77  {
78  /* Pick correct address for port */
79  if (!PortAddress)
80  {
81  if (PortNumber == 1)
82  {
83  PortAddress = (PUCHAR)0x30;
84  }
85  else
86  {
87  PortAddress = (PUCHAR)0x238;
88  PortNumber = 2;
89  }
90  }
91  }
92  else
93  {
94  /* Pick correct port for address */
95  PortAddress = (PUCHAR)0x30;
96  if (CpDoesPortExist(PortAddress))
97  {
98  PortNumber = 1;
99  }
100  else
101  {
102  PortAddress = (PUCHAR)0x238;
103  if (!CpDoesPortExist(PortAddress))
104  return FALSE;
105 
106  PortNumber = 2;
107  }
108  }
109 #else
110  /* Set default baud rate */
111  if (BaudRate == 0) BaudRate = 19200;
112 
113  /* Check if port or address given */
114  if (PortNumber)
115  {
116  /* Pick correct address for port */
117  if (!PortAddress)
118  {
119  switch (PortNumber)
120  {
121  case 1:
122  PortAddress = (PUCHAR)0x3F8;
123  break;
124 
125  case 2:
126  PortAddress = (PUCHAR)0x2F8;
127  break;
128 
129  case 3:
130  PortAddress = (PUCHAR)0x3E8;
131  break;
132 
133  default:
134  PortNumber = 4;
135  PortAddress = (PUCHAR)0x2E8;
136  }
137  }
138  }
139  else
140  {
141  /* Pick correct port for address */
142  PortAddress = (PUCHAR)0x2F8;
143  if (CpDoesPortExist(PortAddress))
144  {
145  PortNumber = 2;
146  }
147  else
148  {
149  PortAddress = (PUCHAR)0x3F8;
150  if (!CpDoesPortExist(PortAddress)) return FALSE;
151  PortNumber = 1;
152  }
153  }
154 #endif
155 
156  /* Not yet supported */
158 
159  /* Check if port exists */
160  if ((CpDoesPortExist(PortAddress)) || (CpDoesPortExist(PortAddress)))
161  {
162  /* Initialize port for first time, or re-initialize if specified */
163  if (((TerminalConnected) && (Port[PortNumber - 1].Address)) ||
164  !(Port[PortNumber - 1].Address))
165  {
166  /* Initialize the port, return it */
167  CpInitialize(&Port[PortNumber - 1], PortAddress, BaudRate);
168  *PortId = PortNumber - 1;
169  return TRUE;
170  }
171  }
172 
173  return FALSE;
174 }
175 
176 VOID
178  IN UCHAR Byte)
179 {
180  CpPutByte(&Port[PortId], Byte);
181 }
182 
183 BOOLEAN
185  OUT PUCHAR Byte)
186 {
187  return CpGetByte(&Port[PortId], Byte, TRUE, FALSE) == CP_GET_SUCCESS;
188 }
189 
190 BOOLEAN
192 {
193  UCHAR Dummy;
194 
195  return CpGetByte(&Port[PortId], &Dummy, FALSE, TRUE) == CP_GET_SUCCESS;
196 }
197 
198 VOID
200  IN BOOLEAN Enable)
201 {
202  CpEnableFifo(Port[PortId].Address, Enable);
203 }
204 
205 VOID
207 {
208  ULONG PortNumber, BaudRate;
209  PUCHAR PortAddress;
210  PCSTR AnsiReset = "\x1B[m";
211  ULONG i;
212 
216 
217 #if defined(SARCH_PC98)
218  /* Pick a port address */
219  if (PortNumber)
220  {
221  if (!PortAddress)
222  {
223  if (PortNumber == 2)
225  else
227  }
228  }
229  else
230  {
231  /* No number, so no EMS */
233  return;
234  }
235 #else
236  /* Pick a port address */
237  if (PortNumber)
238  {
239  if (!PortAddress)
240  {
241  switch (PortNumber)
242  {
243  case 2:
245  break;
246 
247  case 3:
249  break;
250 
251  case 4:
253  break;
254 
255  default:
257  break;
258  }
259  }
260  }
261  else
262  {
263  /* No number, so no EMS */
265  return;
266  }
267 #endif
268 
269  /* Call arch code to initialize the port */
272  PortNumber,
273  PortAddress,
277  {
278  /* Port seems usable, set it up and get the BIOS GUID */
280 
282 
283  /* Calculate delay in us based on the baud, assume 9600 if none given */
284  if (!BaudRate)
285  {
286  BaudRate = 9600;
288  }
289 
290  WinLdrTerminalDelay = (10 * 1000 * 1000) / (BaudRate / 10) / 6;
291 
292  /* Sent an ANSI reset sequence to get the terminal up and running */
293  for (i = 0; i < strlen(AnsiReset); i++)
294  {
297  }
298  }
299 }
300 
301 VOID
303 {
304  PCSTR Option;
305 
306  /* Start fresh */
309 
310  /* Use a direction port if one was given, or use ACPI to detect one instead */
311  Option = NtLdrGetOption(BootOptions, "redirect=");
312  if (Option)
313  {
314  Option += 9;
315  if (_strnicmp(Option, "com", 3) == 0)
316  {
317  Option += 3;
320  }
321  else if (_strnicmp(Option, "usebiossettings", 15) == 0)
322  {
323  // FIXME: TODO!
324  UiDrawStatusText("ACPI SRT/SPCR Table Not Supported...");
325  return;
326  }
327  else
328  {
331  {
333  }
334  }
335  }
336 
337  /* Use a direction baudrate if one was given */
338  Option = NtLdrGetOption(BootOptions, "redirectbaudrate=");
339  if (Option)
340  {
341  Option += 17;
342  // LoaderRedirectionInformation.BaudRate = atoi(Option);
343  if (strncmp(Option, "115200", 6) == 0)
344  {
346  }
347  else if (strncmp(Option, "57600", 5) == 0)
348  {
350  }
351  else if (strncmp(Option, "19200", 5) == 0)
352  {
354  }
355  else
356  {
358  }
359  }
360 
361  /* Enable headless support if parameters were found */
363  {
365  {
367  }
368 
370  }
371 }
372 
373 /* EOF */
CPPORT Port[4]
Definition: headless.c:35
#define IN
Definition: typedefs.h:39
UCHAR Type[6]
Definition: headless.c:21
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
ULONG WinLdrTerminalDeviceId
Definition: headless.c:32
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
VOID WinLdrSetupEms(IN PCSTR BootOptions)
Definition: headless.c:302
unsigned char * PUCHAR
Definition: retypes.h:3
HEADLESS_LOADER_BLOCK LoaderRedirectionInformation
Definition: headless.c:30
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
ULONG WinLdrTerminalDelay
Definition: headless.c:33
UCHAR Checksum
Definition: headless.c:22
struct _SYSID_UUID_ENTRY SYSID_UUID_ENTRY
#define SYSID_TYPE_UUID
Definition: headless.c:16
UCHAR UUID[SYSID_UUID_DATA_SIZE]
Definition: headless.c:24
uint32_t ULONG_PTR
Definition: typedefs.h:65
VOID WinLdrPortPutByte(IN ULONG PortId, IN UCHAR Byte)
Definition: headless.c:177
USHORT NTAPI CpGetByte(IN PCPPORT Port, OUT PUCHAR Byte, IN BOOLEAN Wait, IN BOOLEAN Poll)
Definition: cport.c:256
VOID WinLdrInitializeHeadlessPort(VOID)
Definition: headless.c:206
BOOLEAN NTAPI CpDoesPortExist(IN PUCHAR Address)
Definition: cport.c:227
PUCHAR PortAddress
Definition: arc.h:312
#define FALSE
Definition: types.h:117
ULONG PortNumber
Definition: storport.c:18
USHORT Length
Definition: headless.c:23
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
UCHAR TerminalType
Definition: arc.h:321
BOOLEAN WinLdrPortInitialize(IN ULONG BaudRate, IN ULONG PortNumber, IN PUCHAR PortAddress, IN BOOLEAN TerminalConnected, OUT PULONG PortId)
Definition: headless.c:65
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3597
#define ASSERT(a)
Definition: mode.c:45
VOID NTAPI CpEnableFifo(IN PUCHAR Address, IN BOOLEAN Enable)
Definition: cport.c:54
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
Type
Definition: Type.h:6
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
VOID NTAPI CpPutByte(IN PCPPORT Port, IN UCHAR Byte)
Definition: cport.c:306
USHORT PciDeviceId
Definition: arc.h:313
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID UiDrawStatusText(PCSTR StatusText)
Definition: ui.c:249
BOOLEAN WinLdrPortPollOnly(IN ULONG PortId)
Definition: headless.c:191
BOOLEAN WinLdrTerminalConnected
Definition: headless.c:31
NTSTATUS NTAPI CpInitialize(IN PCPPORT Port, IN PUCHAR Address, IN ULONG BaudRate)
Definition: cport.c:88
VOID WinLdrEnableFifo(IN ULONG PortId, IN BOOLEAN Enable)
Definition: headless.c:199
VOID WinLdrLoadGUID(OUT PGUID SystemGuid)
Definition: headless.c:46
PCSTR NtLdrGetOption(IN PCSTR Options, IN PCSTR OptionName)
Definition: ntldropts.c:128
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
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define CP_GET_SUCCESS
Definition: cportlib.h:18
#define SYSID_UUID_DATA_SIZE
Definition: headless.c:17
unsigned char Byte
Definition: zlib.h:37
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
struct _SYSID_UUID_ENTRY * PSYSID_UUID_ENTRY
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
const char * PCSTR
Definition: typedefs.h:52
Definition: headless.c:19
BOOLEAN WinLdrPortGetByte(IN ULONG PortId, OUT PUCHAR Byte)
Definition: headless.c:184
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
UCHAR IsMMIODevice
Definition: arc.h:320