ReactOS  0.4.14-dev-1276-g8aa58c1
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 
14 /* Note: Move these to some smbios.h header */
15 #define SYSID_TYPE_UUID "_UUID_"
16 #define SYSID_UUID_DATA_SIZE 16
17 #include <pshpack1.h>
18 typedef struct _SYSID_UUID_ENTRY
19 {
20  UCHAR Type[6];
25 #include <poppack.h>
26 
27 /* GLOBALS ********************************************************************/
28 
33 
35 {
36  {NULL, 0, TRUE},
37  {NULL, 0, TRUE},
38  {NULL, 0, TRUE},
39  {NULL, 0, TRUE}
40 };
41 
42 /* FUNCTIONS ******************************************************************/
43 
44 VOID
46 {
47  PSYSID_UUID_ENTRY CurrentAddress;
48 
49  CurrentAddress = (PSYSID_UUID_ENTRY)0xE0000;
50  while (CurrentAddress < (PSYSID_UUID_ENTRY)0x100000)
51  {
52  if (RtlCompareMemory(&CurrentAddress->Type, SYSID_TYPE_UUID, 6) == 6)
53  {
54  RtlCopyMemory(SystemGuid, &CurrentAddress->UUID, SYSID_UUID_DATA_SIZE);
55  return;
56  }
57  CurrentAddress = (PSYSID_UUID_ENTRY)((ULONG_PTR)CurrentAddress + 1);
58  }
59 
61 }
62 
63 BOOLEAN
66  IN PUCHAR PortAddress,
67  IN BOOLEAN TerminalConnected,
68  OUT PULONG PortId)
69 {
70  /* Set default baud rate */
71  if (BaudRate == 0) BaudRate = 19200;
72 
73 #if defined(SARCH_PC98)
74  /* Check if port or address given */
75  if (PortNumber)
76  {
77  /* Pick correct address for port */
78  if (!PortAddress)
79  {
80  if (PortNumber == 1)
81  {
82  PortAddress = (PUCHAR)0x30;
83  }
84  else
85  {
86  PortAddress = (PUCHAR)0x238;
87  PortNumber = 2;
88  }
89  }
90  }
91  else
92  {
93  /* Pick correct port for address */
94  PortAddress = (PUCHAR)0x30;
95  if (CpDoesPortExist(PortAddress))
96  {
97  PortNumber = 1;
98  }
99  else
100  {
101  PortAddress = (PUCHAR)0x238;
102  if (!CpDoesPortExist(PortAddress))
103  return FALSE;
104 
105  PortNumber = 2;
106  }
107  }
108 #else
109  /* Check if port or address given */
110  if (PortNumber)
111  {
112  /* Pick correct address for port */
113  if (!PortAddress)
114  {
115  switch (PortNumber)
116  {
117  case 1:
118  PortAddress = (PUCHAR)0x3F8;
119  break;
120 
121  case 2:
122  PortAddress = (PUCHAR)0x2F8;
123  break;
124 
125  case 3:
126  PortAddress = (PUCHAR)0x3E8;
127  break;
128 
129  default:
130  PortNumber = 4;
131  PortAddress = (PUCHAR)0x2E8;
132  }
133  }
134  }
135  else
136  {
137  /* Pick correct port for address */
138  PortAddress = (PUCHAR)0x2F8;
139  if (CpDoesPortExist(PortAddress))
140  {
141  PortNumber = 2;
142  }
143  else
144  {
145  PortAddress = (PUCHAR)0x3F8;
146  if (!CpDoesPortExist(PortAddress)) return FALSE;
147  PortNumber = 1;
148  }
149  }
150 #endif
151 
152  /* Not yet supported */
154 
155  /* Check if port exists */
156  if ((CpDoesPortExist(PortAddress)) || (CpDoesPortExist(PortAddress)))
157  {
158  /* Initialize port for first time, or re-initialize if specified */
159  if (((TerminalConnected) && (Port[PortNumber - 1].Address)) ||
160  !(Port[PortNumber - 1].Address))
161  {
162  /* Initialize the port, return it */
163  CpInitialize(&Port[PortNumber - 1], PortAddress, BaudRate);
164  *PortId = PortNumber - 1;
165  return TRUE;
166  }
167  }
168 
169  return FALSE;
170 }
171 
172 VOID
174  IN UCHAR Byte)
175 {
176  CpPutByte(&Port[PortId], Byte);
177 }
178 
179 BOOLEAN
181  OUT PUCHAR Byte)
182 {
183  return CpGetByte(&Port[PortId], Byte, TRUE, FALSE) == CP_GET_SUCCESS;
184 }
185 
186 BOOLEAN
188 {
189  UCHAR Dummy;
190 
191  return CpGetByte(&Port[PortId], &Dummy, FALSE, TRUE) == CP_GET_SUCCESS;
192 }
193 
194 VOID
196  IN BOOLEAN Enable)
197 {
198  CpEnableFifo(Port[PortId].Address, Enable);
199 }
200 
201 VOID
203 {
204  ULONG PortNumber, BaudRate;
205  PUCHAR PortAddress;
206  PCHAR AnsiReset = "\x1B[m";
207  ULONG i;
208 
212 
213 #if defined(SARCH_PC98)
214  /* Pick a port address */
215  if (PortNumber)
216  {
217  if (!PortAddress)
218  {
219  if (PortNumber == 2)
221  else
223  }
224  }
225  else
226  {
227  /* No number, so no EMS */
229  return;
230  }
231 #else
232  /* Pick a port address */
233  if (PortNumber)
234  {
235  if (!PortAddress)
236  {
237  switch (PortNumber)
238  {
239  case 2:
241  break;
242 
243  case 3:
245  break;
246 
247  case 4:
249  break;
250 
251  default:
253  break;
254  }
255  }
256  }
257  else
258  {
259  /* No number, so no EMS */
261  return;
262  }
263 #endif
264 
265  /* Call arch code to initialize the port */
268  BaudRate,
269  PortNumber,
270  PortAddress,
273 
275  {
276  /* Port seems usable, set it up and get the BIOS GUID */
278 
280 
281  /* Calculate delay in us based on the baud, assume 9600 if none given */
282  if (!BaudRate)
283  {
284  BaudRate = 9600;
286  }
287 
288  WinLdrTerminalDelay = (10 * 1000 * 1000) / (BaudRate / 10) / 6;
289 
290  /* Sent an ANSI reset sequence to get the terminal up and running */
291  for (i = 0; i < strlen(AnsiReset); i++)
292  {
295  }
296  }
297 }
298 
299 VOID
301 {
302  PCHAR Settings, RedirectPort;
303 
304  /* Start fresh */
307 
308  /* Use a direction port if one was given, or use ACPI to detect one instead */
309  Settings = strstr(BootOptions, "/redirect=");
310  if (Settings)
311  {
312  RedirectPort = strstr(Settings, "com");
313  if (RedirectPort)
314  {
315  RedirectPort += sizeof("com") - 1;
317  LoaderRedirectionInformation.TerminalType = 1; // HeadlessSerialPort
318  }
319  else
320  {
321  RedirectPort = strstr(Settings, "usebiossettings");
322  if (RedirectPort)
323  {
324  UiDrawStatusText("ACPI SRT Table Not Supported...");
325  return;
326  }
327  else
328  {
331  {
333  }
334  }
335  }
336  }
337 
338  /* Use a direction baudrate if one was given */
339  Settings = strstr(BootOptions, "/redirectbaudrate=");
340  if (Settings)
341  {
342  if (strstr(Settings, "115200"))
343  {
345  }
346  else if (strstr(Settings, "57600"))
347  {
349  }
350  else if (strstr(Settings, "19200"))
351  {
353  }
354  else
355  {
357  }
358  }
359 
360  /* Enable headless support if parameters were found */
362  {
364  {
366  }
367 
369  }
370 }
371 
372 /* EOF */
signed char * PCHAR
Definition: retypes.h:7
CPPORT Port[4]
Definition: headless.c:34
#define IN
Definition: typedefs.h:39
UCHAR Type[6]
Definition: headless.c:20
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
ULONG WinLdrTerminalDeviceId
Definition: headless.c:31
Type
Definition: Type.h:6
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
unsigned char Byte
Definition: zconf.h:391
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
unsigned char * PUCHAR
Definition: retypes.h:3
HEADLESS_LOADER_BLOCK LoaderRedirectionInformation
Definition: headless.c:29
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
ULONG WinLdrTerminalDelay
Definition: headless.c:32
UCHAR Checksum
Definition: headless.c:21
struct _SYSID_UUID_ENTRY SYSID_UUID_ENTRY
#define SYSID_TYPE_UUID
Definition: headless.c:15
UCHAR UUID[SYSID_UUID_DATA_SIZE]
Definition: headless.c:23
uint32_t ULONG_PTR
Definition: typedefs.h:64
VOID WinLdrPortPutByte(IN ULONG PortId, IN UCHAR Byte)
Definition: headless.c:173
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:202
BOOLEAN NTAPI CpDoesPortExist(IN PUCHAR Address)
Definition: cport.c:227
PUCHAR PortAddress
Definition: arc.h:312
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
ULONG PortNumber
Definition: storport.c:18
USHORT Length
Definition: headless.c:22
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
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:64
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3245
VOID NTAPI CpEnableFifo(IN PUCHAR Address, IN BOOLEAN Enable)
Definition: cport.c:54
VOID NTAPI CpPutByte(IN PCPPORT Port, IN UCHAR Byte)
Definition: cport.c:306
SETTINGS Settings
Definition: charmap.c:26
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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:187
BOOLEAN WinLdrTerminalConnected
Definition: headless.c:30
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:195
VOID WinLdrSetupEms(IN PCHAR BootOptions)
Definition: headless.c:300
VOID WinLdrLoadGUID(OUT PGUID SystemGuid)
Definition: headless.c:45
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
#define CP_GET_SUCCESS
Definition: cportlib.h:18
#define SYSID_UUID_DATA_SIZE
Definition: headless.c:16
_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:261
struct _SYSID_UUID_ENTRY * PSYSID_UUID_ENTRY
Definition: headless.c:18
BOOLEAN WinLdrPortGetByte(IN ULONG PortId, OUT PUCHAR Byte)
Definition: headless.c:180
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
UCHAR IsMMIODevice
Definition: arc.h:320