TianoCore EDK2 master
Loading...
Searching...
No Matches
QemuFwCfgSimpleParser.c
Go to the documentation of this file.
1
9#include <Library/BaseLib.h>
12
13//
14// Size of the longest valid UINT64 string, including the terminating NUL.
15//
16#define UINT64_STRING_MAX_SIZE \
17 MAX (sizeof "18446744073709551615", sizeof "0xFFFFFFFFFFFFFFFF")
18
19//
20// Size of the longest valid BOOL string (see the "mTrueString" and
21// "mFalseString" arrays below), including the terminating NUL.
22//
23#define BOOL_STRING_MAX_SIZE (sizeof "disabled")
24
25//
26// Length of "\r\n", not including the terminating NUL.
27//
28#define CRLF_LENGTH (sizeof "\r\n" - 1)
29
30//
31// Words recognized as representing TRUE or FALSE.
32//
33STATIC CONST CHAR8 *CONST mTrueString[] = {
34 "true", "yes", "y", "enable", "enabled", "1"
35};
36STATIC CONST CHAR8 *CONST mFalseString[] = {
37 "false", "no", "n", "disable", "disabled", "0"
38};
39
40//
41// Helper functions.
42//
43
86RETURN_STATUS
88 IN CONST CHAR8 *FileName,
89 IN OUT UINTN *BufferSize,
90 OUT CHAR8 *Buffer
91 )
92{
93 RETURN_STATUS Status;
94 FIRMWARE_CONFIG_ITEM FwCfgItem;
95 UINTN FwCfgSize;
96
97 if (!QemuFwCfgIsAvailable ()) {
98 return RETURN_UNSUPPORTED;
99 }
100
101 Status = QemuFwCfgFindFile (FileName, &FwCfgItem, &FwCfgSize);
102 if (RETURN_ERROR (Status)) {
103 return Status;
104 }
105
106 if (FwCfgSize > *BufferSize) {
108 }
109
110 QemuFwCfgSelectItem (FwCfgItem);
111 QemuFwCfgReadBytes (FwCfgSize, Buffer);
112
113 //
114 // If Buffer is already NUL-terminated due to fw_cfg contents, we're done.
115 //
116 if ((FwCfgSize > 0) && (Buffer[FwCfgSize - 1] == '\0')) {
117 *BufferSize = FwCfgSize;
118 return RETURN_SUCCESS;
119 }
120
121 //
122 // Otherwise, append a NUL byte to Buffer (if we have room for it).
123 //
124 if (FwCfgSize == *BufferSize) {
126 }
127
128 Buffer[FwCfgSize] = '\0';
129 *BufferSize = FwCfgSize + 1;
130 return RETURN_SUCCESS;
131}
132
145STATIC
146VOID
148 IN OUT UINTN *BufferSize,
149 IN OUT CHAR8 *Buffer
150 )
151{
152 UINTN InSize, OutSize;
153
154 InSize = *BufferSize;
155 OutSize = InSize;
156
157 if ((InSize >= 3) &&
158 (Buffer[InSize - 3] == '\r') && (Buffer[InSize - 2] == '\n'))
159 {
160 OutSize = InSize - 2;
161 } else if ((InSize >= 2) && (Buffer[InSize - 2] == '\n')) {
162 OutSize = InSize - 1;
163 }
164
165 if (OutSize < InSize) {
166 Buffer[OutSize - 1] = '\0';
167 *BufferSize = OutSize;
168 }
169}
170
207STATIC
208RETURN_STATUS
210 IN CONST CHAR8 *FileName,
211 IN BOOLEAN ParseAsHex,
212 IN UINT64 Limit,
213 OUT UINT64 *Value
214 )
215{
216 UINTN Uint64StringSize;
217 CHAR8 Uint64String[UINT64_STRING_MAX_SIZE + CRLF_LENGTH];
218 RETURN_STATUS Status;
219 CHAR8 *EndPointer;
220 UINT64 Uint64;
221
222 Uint64StringSize = sizeof Uint64String;
223 Status = QemuFwCfgGetAsString (FileName, &Uint64StringSize, Uint64String);
224 if (RETURN_ERROR (Status)) {
225 return Status;
226 }
227
228 StripNewline (&Uint64StringSize, Uint64String);
229
230 if (ParseAsHex) {
231 Status = AsciiStrHexToUint64S (Uint64String, &EndPointer, &Uint64);
232 } else {
233 Status = AsciiStrDecimalToUint64S (Uint64String, &EndPointer, &Uint64);
234 }
235
236 if (RETURN_ERROR (Status)) {
237 return Status;
238 }
239
240 //
241 // Report a wire protocol error if the subject sequence is empty, or trailing
242 // garbage is present, or Limit is not honored.
243 //
244 if ((EndPointer == Uint64String) || (*EndPointer != '\0') || (Uint64 > Limit)) {
246 }
247
248 *Value = Uint64;
249 return RETURN_SUCCESS;
250}
251
252//
253// Public functions.
254//
255
256RETURN_STATUS
257EFIAPI
258QemuFwCfgSimpleParserInit (
259 VOID
260 )
261{
262 //
263 // Do nothing, just participate in constructor dependency ordering.
264 //
265 return RETURN_SUCCESS;
266}
267
268RETURN_STATUS
269EFIAPI
271 IN CONST CHAR8 *FileName,
272 OUT BOOLEAN *Value
273 )
274{
275 UINTN BoolStringSize;
276 CHAR8 BoolString[BOOL_STRING_MAX_SIZE + CRLF_LENGTH];
277 RETURN_STATUS Status;
278 UINTN Idx;
279
280 BoolStringSize = sizeof BoolString;
281 Status = QemuFwCfgGetAsString (FileName, &BoolStringSize, BoolString);
282 if (RETURN_ERROR (Status)) {
283 return Status;
284 }
285
286 StripNewline (&BoolStringSize, BoolString);
287
288 for (Idx = 0; Idx < ARRAY_SIZE (mTrueString); ++Idx) {
289 if (AsciiStriCmp (BoolString, mTrueString[Idx]) == 0) {
290 *Value = TRUE;
291 return RETURN_SUCCESS;
292 }
293 }
294
295 for (Idx = 0; Idx < ARRAY_SIZE (mFalseString); ++Idx) {
296 if (AsciiStriCmp (BoolString, mFalseString[Idx]) == 0) {
297 *Value = FALSE;
298 return RETURN_SUCCESS;
299 }
300 }
301
303}
304
305RETURN_STATUS
306EFIAPI
308 IN CONST CHAR8 *FileName,
309 IN BOOLEAN ParseAsHex,
310 OUT UINT8 *Value
311 )
312{
313 RETURN_STATUS Status;
314 UINT64 Uint64;
315
317 FileName,
318 ParseAsHex,
319 MAX_UINT8,
320 &Uint64
321 );
322 if (RETURN_ERROR (Status)) {
323 return Status;
324 }
325
326 *Value = (UINT8)Uint64;
327 return RETURN_SUCCESS;
328}
329
330RETURN_STATUS
331EFIAPI
332QemuFwCfgParseUint16 (
333 IN CONST CHAR8 *FileName,
334 IN BOOLEAN ParseAsHex,
335 OUT UINT16 *Value
336 )
337{
338 RETURN_STATUS Status;
339 UINT64 Uint64;
340
342 FileName,
343 ParseAsHex,
344 MAX_UINT16,
345 &Uint64
346 );
347 if (RETURN_ERROR (Status)) {
348 return Status;
349 }
350
351 *Value = (UINT16)Uint64;
352 return RETURN_SUCCESS;
353}
354
355RETURN_STATUS
356EFIAPI
357QemuFwCfgParseUint32 (
358 IN CONST CHAR8 *FileName,
359 IN BOOLEAN ParseAsHex,
360 OUT UINT32 *Value
361 )
362{
363 RETURN_STATUS Status;
364 UINT64 Uint64;
365
367 FileName,
368 ParseAsHex,
369 MAX_UINT32,
370 &Uint64
371 );
372 if (RETURN_ERROR (Status)) {
373 return Status;
374 }
375
376 *Value = (UINT32)Uint64;
377 return RETURN_SUCCESS;
378}
379
380RETURN_STATUS
381EFIAPI
382QemuFwCfgParseUint64 (
383 IN CONST CHAR8 *FileName,
384 IN BOOLEAN ParseAsHex,
385 OUT UINT64 *Value
386 )
387{
388 RETURN_STATUS Status;
389 UINT64 Uint64;
390
392 FileName,
393 ParseAsHex,
394 MAX_UINT64,
395 &Uint64
396 );
397 if (RETURN_ERROR (Status)) {
398 return Status;
399 }
400
401 *Value = Uint64;
402 return RETURN_SUCCESS;
403}
404
405RETURN_STATUS
406EFIAPI
407QemuFwCfgParseUintn (
408 IN CONST CHAR8 *FileName,
409 IN BOOLEAN ParseAsHex,
410 OUT UINTN *Value
411 )
412{
413 RETURN_STATUS Status;
414 UINT64 Uint64;
415
417 FileName,
418 ParseAsHex,
419 MAX_UINTN,
420 &Uint64
421 );
422 if (RETURN_ERROR (Status)) {
423 return Status;
424 }
425
426 *Value = (UINTN)Uint64;
427 return RETURN_SUCCESS;
428}
UINT64 UINTN
INTN EFIAPI AsciiStriCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:814
RETURN_STATUS EFIAPI AsciiStrHexToUint64S(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT UINT64 *Data)
Definition: SafeString.c:2527
RETURN_STATUS EFIAPI AsciiStrDecimalToUint64S(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT UINT64 *Data)
Definition: SafeString.c:2287
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define RETURN_PROTOCOL_ERROR
Definition: Base.h:1192
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define RETURN_UNSUPPORTED
Definition: Base.h:1081
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
RETURN_STATUS EFIAPI QemuFwCfgFindFile(IN CONST CHAR8 *Name, OUT FIRMWARE_CONFIG_ITEM *Item, OUT UINTN *Size)
Definition: QemuFwCfgLib.c:250
VOID EFIAPI QemuFwCfgReadBytes(IN UINTN Size, IN VOID *Buffer OPTIONAL)
Definition: QemuFwCfgNull.c:66
VOID EFIAPI QemuFwCfgSelectItem(IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem)
Definition: QemuFwCfgLib.c:33
BOOLEAN EFIAPI QemuFwCfgIsAvailable(VOID)
Definition: QemuFwCfgDxe.c:44
STATIC VOID StripNewline(IN OUT UINTN *BufferSize, IN OUT CHAR8 *Buffer)
RETURN_STATUS EFIAPI QemuFwCfgParseUint8(IN CONST CHAR8 *FileName, IN BOOLEAN ParseAsHex, OUT UINT8 *Value)
RETURN_STATUS EFIAPI QemuFwCfgParseBool(IN CONST CHAR8 *FileName, OUT BOOLEAN *Value)
STATIC RETURN_STATUS QemuFwCfgGetAsString(IN CONST CHAR8 *FileName, IN OUT UINTN *BufferSize, OUT CHAR8 *Buffer)
STATIC RETURN_STATUS QemuFwCfgParseUint64WithLimit(IN CONST CHAR8 *FileName, IN BOOLEAN ParseAsHex, IN UINT64 Limit, OUT UINT64 *Value)