]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/UefiIfrSupportLib/UefiIfrOpCodeCreation.c
9b48a27e1927ad028932977216c053e35e618b39
[mirror_edk2.git] / MdeModulePkg / Library / UefiIfrSupportLib / UefiIfrOpCodeCreation.c
1 /** @file
2 Library Routines to create IFR independent of string data - assume tokens already exist
3 Primarily to be used for exporting op-codes at a label in pre-defined forms.
4
5
6 Copyright (c) 2007, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15
16 **/
17
18 #include "UefiIfrLibraryInternal.h"
19
20 /**
21 Check if the input question flags is a valid value.
22 The valid combination of question flags includes
23 EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY.
24
25 @param Flags The question flags to check.
26
27 @retval TRUE If the question flag is a valid combination.
28 @retval FALSE If the question flag is an invalid combination.
29
30 **/
31 BOOLEAN
32 IsValidQuestionFlags (
33 IN UINT8 Flags
34 )
35 {
36 return (BOOLEAN) (((Flags & (~QUESTION_FLAGS)) != 0) ? FALSE : TRUE);
37 }
38
39 /**
40 Check if the input value type is a valid type.
41 The valid value type is smaller or equal than EFI_IFR_TYPE_OTHER.
42
43 @param Type The value type to check.
44
45 @retval TRUE If the value type is valid.
46 @retval FALSE If the value type is invalid.
47
48 **/
49 BOOLEAN
50 IsValidValueType (
51 IN UINT8 Type
52 )
53 {
54 return (BOOLEAN) ((Type <= EFI_IFR_TYPE_OTHER) ? TRUE : FALSE);
55 }
56
57 /**
58 Check if the input numeric flags is a valid value.
59
60 @param Flags The numeric flags to check.
61
62 @retval TRUE If the numeric flags is valid.
63 @retval FALSE If the numeric flags is invalid.
64
65 **/
66 BOOLEAN
67 IsValidNumricFlags (
68 IN UINT8 Flags
69 )
70 {
71 if ((Flags & ~(EFI_IFR_NUMERIC_SIZE | EFI_IFR_DISPLAY)) != 0) {
72 return FALSE;
73 }
74
75 if ((Flags & EFI_IFR_DISPLAY) > EFI_IFR_DISPLAY_UINT_HEX) {
76 return FALSE;
77 }
78
79 return TRUE;
80 }
81
82 /**
83 Check if the checkbox flags is a valid value.
84
85 @param Flags The checkbox flags to check.
86
87 @retval TRUE If the checkbox flags is valid.
88 @retval FALSE If the checkbox flags is invalid.
89
90 **/
91 BOOLEAN
92 IsValidCheckboxFlags (
93 IN UINT8 Flags
94 )
95 {
96 return (BOOLEAN) ((Flags <= EFI_IFR_CHECKBOX_DEFAULT_MFG) ? TRUE : FALSE);
97 }
98
99 /**
100 Create EFI_IFR_END_OP opcode.
101
102 If Data is NULL or Data->Data is NULL, then ASSERT.
103
104 @param Data Destination for the created opcode binary
105
106 @retval EFI_SUCCESS Opcode is created successfully.
107 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
108
109 **/
110 EFI_STATUS
111 EFIAPI
112 CreateEndOpCode (
113 IN OUT EFI_HII_UPDATE_DATA *Data
114 )
115 {
116 EFI_IFR_END End;
117 UINT8 *LocalBuffer;
118
119 ASSERT (Data != NULL && Data->Data != NULL);
120
121 if (Data->Offset + sizeof (EFI_IFR_END) > Data->BufferSize) {
122 return EFI_BUFFER_TOO_SMALL;
123 }
124
125 End.Header.Length = sizeof (EFI_IFR_END);
126 End.Header.OpCode = EFI_IFR_END_OP;
127 End.Header.Scope = 0;
128
129 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
130 //
131 // CopyMem is used for EFI_IFR_END to cover the unaligned address access.
132 //
133 CopyMem (LocalBuffer, &End, sizeof (EFI_IFR_END));
134 Data->Offset += sizeof (EFI_IFR_END);
135
136 return EFI_SUCCESS;
137 }
138
139 /**
140 Create EFI_IFR_DEFAULT_OP opcode.
141
142 If Data is NULL or Data->Data is NULL, then ASSERT.
143
144 @param Value Value for the default
145 @param Type Type for the default
146 @param Data Destination for the created opcode binary
147
148 @retval EFI_SUCCESS Opcode is created successfully.
149 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
150 @retval EFI_INVALID_PARAMETER The type is not valid.
151
152 **/
153 EFI_STATUS
154 EFIAPI
155 CreateDefaultOpCode (
156 IN EFI_IFR_TYPE_VALUE *Value,
157 IN UINT8 Type,
158 IN OUT EFI_HII_UPDATE_DATA *Data
159 )
160 {
161 EFI_IFR_DEFAULT Default;
162 UINT8 *LocalBuffer;
163
164 ASSERT (Data != NULL && Data->Data != NULL);
165
166 if ((Value == NULL) || !IsValidValueType (Type)) {
167 return EFI_INVALID_PARAMETER;
168 }
169
170 if (Data->Offset + sizeof (EFI_IFR_DEFAULT) > Data->BufferSize) {
171 return EFI_BUFFER_TOO_SMALL;
172 }
173
174 Default.Header.OpCode = EFI_IFR_DEFAULT_OP;
175 Default.Header.Length = sizeof (EFI_IFR_DEFAULT);
176 Default.Header.Scope = 0;
177 Default.Type = Type;
178 Default.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
179 CopyMem (&Default.Value, Value, sizeof(EFI_IFR_TYPE_VALUE));
180
181 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
182 //
183 // CopyMem is used for EFI_IFR_DEFAULT to cover the unaligned address access.
184 //
185 CopyMem (LocalBuffer, &Default, sizeof (EFI_IFR_DEFAULT));
186 Data->Offset += sizeof (EFI_IFR_DEFAULT);
187
188 return EFI_SUCCESS;
189 }
190
191 /**
192 Create EFI_IFR_ACTION_OP opcode.
193
194 If Data is NULL or Data->Data is NULL, then ASSERT.
195
196 @param QuestionId Question ID
197 @param Prompt String ID for Prompt
198 @param Help String ID for Help
199 @param QuestionFlags Flags in Question Header
200 @param QuestionConfig String ID for configuration
201 @param Data Destination for the created opcode binary
202
203 @retval EFI_SUCCESS Opcode is created successfully.
204 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
205 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
206
207 **/
208 EFI_STATUS
209 EFIAPI
210 CreateActionOpCode (
211 IN EFI_QUESTION_ID QuestionId,
212 IN EFI_STRING_ID Prompt,
213 IN EFI_STRING_ID Help,
214 IN UINT8 QuestionFlags,
215 IN EFI_STRING_ID QuestionConfig,
216 IN OUT EFI_HII_UPDATE_DATA *Data
217 )
218 {
219 EFI_IFR_ACTION Action;
220 UINT8 *LocalBuffer;
221
222 ASSERT (Data != NULL && Data->Data != NULL);
223
224 if (!IsValidQuestionFlags (QuestionFlags)) {
225 return EFI_INVALID_PARAMETER;
226 }
227
228 if (Data->Offset + sizeof (EFI_IFR_ACTION) > Data->BufferSize) {
229 return EFI_BUFFER_TOO_SMALL;
230 }
231
232 Action.Header.OpCode = EFI_IFR_ACTION_OP;
233 Action.Header.Length = sizeof (EFI_IFR_ACTION);
234 Action.Header.Scope = 0;
235 Action.Question.QuestionId = QuestionId;
236 Action.Question.Header.Prompt = Prompt;
237 Action.Question.Header.Help = Help;
238 Action.Question.VarStoreId = INVALID_VARSTORE_ID;
239 Action.Question.Flags = QuestionFlags;
240 Action.QuestionConfig = QuestionConfig;
241
242 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
243 //
244 // CopyMem is used for EFI_IFR_ACTION to cover the unaligned address access.
245 //
246 CopyMem (LocalBuffer, &Action, sizeof (EFI_IFR_ACTION));
247 Data->Offset += sizeof (EFI_IFR_ACTION);
248
249 return EFI_SUCCESS;
250 }
251
252 /**
253 Create EFI_IFR_SUBTITLE_OP opcode.
254
255 If Data is NULL or Data->Data is NULL, then ASSERT.
256
257 @param Prompt String ID for Prompt
258 @param Help String ID for Help
259 @param Flags Subtitle opcode flags
260 @param Scope Subtitle Scope bit
261 @param Data Destination for the created opcode binary
262
263 @retval EFI_SUCCESS Opcode is created successfully.
264 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
265
266 **/
267 EFI_STATUS
268 EFIAPI
269 CreateSubTitleOpCode (
270 IN EFI_STRING_ID Prompt,
271 IN EFI_STRING_ID Help,
272 IN UINT8 Flags,
273 IN UINT8 Scope,
274 IN OUT EFI_HII_UPDATE_DATA *Data
275 )
276 {
277 EFI_IFR_SUBTITLE Subtitle;
278 UINT8 *LocalBuffer;
279
280 ASSERT (Data != NULL && Data->Data != NULL);
281
282 if (Data->Offset + sizeof (EFI_IFR_SUBTITLE) > Data->BufferSize) {
283 return EFI_BUFFER_TOO_SMALL;
284 }
285
286 Subtitle.Header.OpCode = EFI_IFR_SUBTITLE_OP;
287 Subtitle.Header.Length = sizeof (EFI_IFR_SUBTITLE);
288 Subtitle.Header.Scope = Scope;
289 Subtitle.Statement.Prompt = Prompt;
290 Subtitle.Statement.Help = Help;
291 Subtitle.Flags = Flags;
292
293 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
294 //
295 // CopyMem is used for EFI_IFR_SUBTITLE to cover the unaligned address access.
296 //
297 CopyMem (LocalBuffer, &Subtitle, sizeof (EFI_IFR_SUBTITLE));
298 Data->Offset += sizeof (EFI_IFR_SUBTITLE);
299
300 return EFI_SUCCESS;
301 }
302
303
304 /**
305 Create EFI_IFR_TEXT_OP opcode.
306
307 If Data is NULL or Data->Data is NULL, then ASSERT.
308
309 @param Prompt String ID for Prompt
310 @param Help String ID for Help
311 @param TextTwo String ID for text two
312 @param Data Destination for the created opcode binary
313
314 @retval EFI_SUCCESS Opcode is created successfully.
315 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
316
317 **/
318 EFI_STATUS
319 EFIAPI
320 CreateTextOpCode (
321 IN EFI_STRING_ID Prompt,
322 IN EFI_STRING_ID Help,
323 IN EFI_STRING_ID TextTwo,
324 IN OUT EFI_HII_UPDATE_DATA *Data
325 )
326 {
327 EFI_IFR_TEXT Text;
328 UINT8 *LocalBuffer;
329
330 ASSERT (Data != NULL && Data->Data != NULL);
331
332 if (Data->Offset + sizeof (EFI_IFR_TEXT) > Data->BufferSize) {
333 return EFI_BUFFER_TOO_SMALL;
334 }
335
336 Text.Header.OpCode = EFI_IFR_TEXT_OP;
337 Text.Header.Length = sizeof (EFI_IFR_TEXT);
338 Text.Header.Scope = 0;
339 Text.Statement.Prompt = Prompt;
340 Text.Statement.Help = Help;
341 Text.TextTwo = TextTwo;
342
343 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
344 //
345 // CopyMem is used for EFI_IFR_TEXT to cover the unaligned address access.
346 //
347 CopyMem (LocalBuffer, &Text, sizeof (EFI_IFR_TEXT));
348 Data->Offset += sizeof (EFI_IFR_TEXT);
349
350 return EFI_SUCCESS;
351 }
352
353 /**
354 Create EFI_IFR_REF_OP opcode.
355
356 If Data is NULL or Data->Data is NULL, then ASSERT.
357
358 @param FormId Destination Form ID
359 @param Prompt String ID for Prompt
360 @param Help String ID for Help
361 @param QuestionFlags Flags in Question Header
362 @param QuestionId Question ID
363 @param Data Destination for the created opcode binary
364
365 @retval EFI_SUCCESS Opcode is created successfully.
366 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
367 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
368
369 **/
370 EFI_STATUS
371 EFIAPI
372 CreateGotoOpCode (
373 IN EFI_FORM_ID FormId,
374 IN EFI_STRING_ID Prompt,
375 IN EFI_STRING_ID Help,
376 IN UINT8 QuestionFlags,
377 IN EFI_QUESTION_ID QuestionId,
378 IN OUT EFI_HII_UPDATE_DATA *Data
379 )
380 {
381 EFI_IFR_REF Goto;
382 UINT8 *LocalBuffer;
383
384 ASSERT (Data != NULL && Data->Data != NULL);
385
386 if (!IsValidQuestionFlags (QuestionFlags)) {
387 return EFI_INVALID_PARAMETER;
388 }
389
390 if (Data->Offset + sizeof (EFI_IFR_REF) > Data->BufferSize) {
391 return EFI_BUFFER_TOO_SMALL;
392 }
393
394 Goto.Header.OpCode = EFI_IFR_REF_OP;
395 Goto.Header.Length = sizeof (EFI_IFR_REF);
396 Goto.Header.Scope = 0;
397 Goto.Question.Header.Prompt = Prompt;
398 Goto.Question.Header.Help = Help;
399 Goto.Question.VarStoreId = INVALID_VARSTORE_ID;
400 Goto.Question.QuestionId = QuestionId;
401 Goto.Question.Flags = QuestionFlags;
402 Goto.FormId = FormId;
403
404 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
405 //
406 // CopyMem is used for EFI_IFR_REF to cover the unaligned address access.
407 //
408 CopyMem (LocalBuffer, &Goto, sizeof (EFI_IFR_REF));
409 Data->Offset += sizeof (EFI_IFR_REF);
410
411 return EFI_SUCCESS;
412 }
413
414 /**
415 Create EFI_IFR_ONE_OF_OPTION_OP opcode.
416
417 If Data is NULL or Data->Data is NULL, then ASSERT.
418
419 @param OptionCount The number of options.
420 @param OptionsList The list of Options.
421 @param Type The data type.
422 @param Data Destination for the created opcode binary
423
424 @retval EFI_SUCCESS Opcode is created successfully.
425 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
426 @retval EFI_INVALID_PARAMETER If OptionCount is not zero but OptionsList is NULL.
427
428 **/
429 EFI_STATUS
430 EFIAPI
431 CreateOneOfOptionOpCode (
432 IN UINTN OptionCount,
433 IN IFR_OPTION *OptionsList,
434 IN UINT8 Type,
435 IN OUT EFI_HII_UPDATE_DATA *Data
436 )
437 {
438 UINTN Index;
439 UINT8 *LocalBuffer;
440 EFI_IFR_ONE_OF_OPTION OneOfOption;
441
442 ASSERT (Data != NULL && Data->Data != NULL);
443
444 if ((OptionCount != 0) && (OptionsList == NULL)) {
445 return EFI_INVALID_PARAMETER;
446 }
447
448 if (Data->Offset + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) > Data->BufferSize) {
449 return EFI_BUFFER_TOO_SMALL;
450 }
451
452 for (Index = 0; Index < OptionCount; Index++) {
453 OneOfOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;
454 OneOfOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);
455 OneOfOption.Header.Scope = 0;
456
457 OneOfOption.Option = OptionsList[Index].StringToken;
458 OneOfOption.Value = OptionsList[Index].Value;
459 OneOfOption.Flags = (UINT8) (OptionsList[Index].Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG));
460 OneOfOption.Type = Type;
461
462 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
463 //
464 // CopyMem is used for EFI_IFR_ONF_OF_OPTION to cover the unaligned address access.
465 //
466 CopyMem (LocalBuffer, &OneOfOption, sizeof (EFI_IFR_ONE_OF_OPTION));
467 Data->Offset += sizeof (EFI_IFR_ONE_OF_OPTION);
468 }
469
470 return EFI_SUCCESS;
471 }
472
473 /**
474 Create EFI_IFR_ONE_OF_OP opcode.
475
476 If Data is NULL or Data->Data is NULL, then ASSERT.
477
478 @param QuestionId Question ID
479 @param VarStoreId Storage ID
480 @param VarOffset Offset in Storage
481 @param Prompt String ID for Prompt
482 @param Help String ID for Help
483 @param QuestionFlags Flags in Question Header
484 @param OneOfFlags Flags for oneof opcode
485 @param OptionsList List of options
486 @param OptionCount Number of options in option list
487 @param Data Destination for the created opcode binary
488
489 @retval EFI_SUCCESS Opcode is created successfully.
490 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
491 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
492
493 **/
494 EFI_STATUS
495 EFIAPI
496 CreateOneOfOpCode (
497 IN EFI_QUESTION_ID QuestionId,
498 IN EFI_VARSTORE_ID VarStoreId,
499 IN UINT16 VarOffset,
500 IN EFI_STRING_ID Prompt,
501 IN EFI_STRING_ID Help,
502 IN UINT8 QuestionFlags,
503 IN UINT8 OneOfFlags,
504 IN IFR_OPTION *OptionsList,
505 IN UINTN OptionCount,
506 IN OUT EFI_HII_UPDATE_DATA *Data
507 )
508 {
509 UINTN Length;
510 EFI_IFR_ONE_OF OneOf;
511 UINT8 *LocalBuffer;
512
513 ASSERT (Data != NULL && Data->Data != NULL);
514
515 if (!IsValidNumricFlags (OneOfFlags) ||
516 !IsValidQuestionFlags (QuestionFlags) ||
517 ((OptionCount != 0) && (OptionsList == NULL))) {
518 return EFI_INVALID_PARAMETER;
519 }
520
521 Length = sizeof (EFI_IFR_ONE_OF) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);
522 if (Data->Offset + Length > Data->BufferSize) {
523 return EFI_BUFFER_TOO_SMALL;
524 }
525
526 OneOf.Header.OpCode = EFI_IFR_ONE_OF_OP;
527 OneOf.Header.Length = sizeof (EFI_IFR_ONE_OF);
528 OneOf.Header.Scope = 1;
529 OneOf.Question.Header.Prompt = Prompt;
530 OneOf.Question.Header.Help = Help;
531 OneOf.Question.QuestionId = QuestionId;
532 OneOf.Question.VarStoreId = VarStoreId;
533 OneOf.Question.VarStoreInfo.VarOffset = VarOffset;
534 OneOf.Question.Flags = QuestionFlags;
535 OneOf.Flags = OneOfFlags;
536 ZeroMem ((VOID *) &OneOf.data, sizeof (MINMAXSTEP_DATA));
537
538 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
539 //
540 // CopyMem is used for EFI_IFR_ONF_OF to cover the unaligned address access.
541 //
542 CopyMem (LocalBuffer, &OneOf, sizeof (EFI_IFR_ONE_OF));
543 Data->Offset += sizeof (EFI_IFR_ONE_OF);
544
545 CreateOneOfOptionOpCode (OptionCount, OptionsList, (UINT8) (OneOfFlags & EFI_IFR_NUMERIC_SIZE), Data);
546
547 CreateEndOpCode (Data);
548
549 return EFI_SUCCESS;
550 }
551
552 /**
553 Create EFI_IFR_ORDERED_LIST_OP opcode.
554
555 If Data is NULL or Data->Data is NULL, then ASSERT.
556
557 @param QuestionId Question ID
558 @param VarStoreId Storage ID
559 @param VarOffset Offset in Storage
560 @param Prompt String ID for Prompt
561 @param Help String ID for Help
562 @param QuestionFlags Flags in Question Header
563 @param OrderedListFlags Flags for ordered list opcode
564 @param DataType Type for option value
565 @param MaxContainers Maximum count for options in this ordered list
566 @param OptionsList List of options
567 @param OptionCount Number of options in option list
568 @param Data Destination for the created opcode binary
569
570 @retval EFI_SUCCESS Opcode is created successfully.
571 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
572 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
573
574 **/
575 EFI_STATUS
576 EFIAPI
577 CreateOrderedListOpCode (
578 IN EFI_QUESTION_ID QuestionId,
579 IN EFI_VARSTORE_ID VarStoreId,
580 IN UINT16 VarOffset,
581 IN EFI_STRING_ID Prompt,
582 IN EFI_STRING_ID Help,
583 IN UINT8 QuestionFlags,
584 IN UINT8 OrderedListFlags,
585 IN UINT8 DataType,
586 IN UINT8 MaxContainers,
587 IN IFR_OPTION *OptionsList,
588 IN UINTN OptionCount,
589 IN OUT EFI_HII_UPDATE_DATA *Data
590 )
591 {
592 UINTN Length;
593 EFI_IFR_ORDERED_LIST OrderedList;
594 UINT8 *LocalBuffer;
595
596 ASSERT (Data != NULL && Data->Data != NULL);
597
598 if (!IsValidQuestionFlags (QuestionFlags) ||
599 ((OptionCount != 0) && (OptionsList == NULL))) {
600 return EFI_INVALID_PARAMETER;
601 }
602
603 if ((OrderedListFlags != 0) &&
604 (OrderedListFlags != EFI_IFR_UNIQUE_SET) &&
605 (OrderedListFlags != EFI_IFR_NO_EMPTY_SET)) {
606 return EFI_INVALID_PARAMETER;
607 }
608
609 Length = sizeof (EFI_IFR_ORDERED_LIST) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);
610 if (Data->Offset + Length > Data->BufferSize) {
611 return EFI_BUFFER_TOO_SMALL;
612 }
613
614 OrderedList.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;
615 OrderedList.Header.Length = sizeof (EFI_IFR_ORDERED_LIST);
616 OrderedList.Header.Scope = 1;
617 OrderedList.Question.Header.Prompt = Prompt;
618 OrderedList.Question.Header.Help = Help;
619 OrderedList.Question.QuestionId = QuestionId;
620 OrderedList.Question.VarStoreId = VarStoreId;
621 OrderedList.Question.VarStoreInfo.VarOffset = VarOffset;
622 OrderedList.Question.Flags = QuestionFlags;
623 OrderedList.MaxContainers = MaxContainers;
624 OrderedList.Flags = OrderedListFlags;
625
626 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
627 //
628 // CopyMem is used for EFI_IFR_ORDERED_LIST to cover the unaligned address access.
629 //
630 CopyMem (LocalBuffer, &OrderedList, sizeof (EFI_IFR_ORDERED_LIST));
631 Data->Offset += sizeof (EFI_IFR_ORDERED_LIST);
632
633 CreateOneOfOptionOpCode (OptionCount, OptionsList, DataType, Data);
634
635 CreateEndOpCode (Data);
636
637 return EFI_SUCCESS;
638 }
639
640 /**
641 Create EFI_IFR_CHECKBOX_OP opcode.
642
643 If Data is NULL or Data->Data is NULL, then ASSERT.
644
645 @param QuestionId Question ID
646 @param VarStoreId Storage ID
647 @param VarOffset Offset in Storage
648 @param Prompt String ID for Prompt
649 @param Help String ID for Help
650 @param QuestionFlags Flags in Question Header
651 @param CheckBoxFlags Flags for checkbox opcode
652 @param Data Destination for the created opcode binary
653
654 @retval EFI_SUCCESS Opcode is created successfully.
655 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
656 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
657
658 **/
659 EFI_STATUS
660 EFIAPI
661 CreateCheckBoxOpCode (
662 IN EFI_QUESTION_ID QuestionId,
663 IN EFI_VARSTORE_ID VarStoreId,
664 IN UINT16 VarOffset,
665 IN EFI_STRING_ID Prompt,
666 IN EFI_STRING_ID Help,
667 IN UINT8 QuestionFlags,
668 IN UINT8 CheckBoxFlags,
669 IN OUT EFI_HII_UPDATE_DATA *Data
670 )
671 {
672 EFI_IFR_CHECKBOX CheckBox;
673 UINT8 *LocalBuffer;
674
675 ASSERT (Data != NULL && Data->Data != NULL);
676
677 if (!IsValidQuestionFlags (QuestionFlags) || !IsValidCheckboxFlags (CheckBoxFlags)) {
678 return EFI_INVALID_PARAMETER;
679 }
680
681 if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) {
682 return EFI_BUFFER_TOO_SMALL;
683 }
684
685 CheckBox.Header.OpCode = EFI_IFR_CHECKBOX_OP;
686 CheckBox.Header.Length = sizeof (EFI_IFR_CHECKBOX);
687 CheckBox.Header.Scope = 0;
688 CheckBox.Question.QuestionId = QuestionId;
689 CheckBox.Question.VarStoreId = VarStoreId;
690 CheckBox.Question.VarStoreInfo.VarOffset = VarOffset;
691 CheckBox.Question.Header.Prompt = Prompt;
692 CheckBox.Question.Header.Help = Help;
693 CheckBox.Question.Flags = QuestionFlags;
694 CheckBox.Flags = CheckBoxFlags;
695
696 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
697 //
698 // CopyMem is used for EFI_IFR_CHECKBOX to cover the unaligned address access.
699 //
700 CopyMem (LocalBuffer, &CheckBox, sizeof (EFI_IFR_CHECKBOX));
701 Data->Offset += sizeof (EFI_IFR_CHECKBOX);
702
703 return EFI_SUCCESS;
704 }
705
706 /**
707 Create EFI_IFR_NUMERIC_OP opcode.
708
709 If Data is NULL or Data->Data is NULL, then ASSERT.
710
711 @param QuestionId Question ID
712 @param VarStoreId Storage ID
713 @param VarOffset Offset in Storage
714 @param Prompt String ID for Prompt
715 @param Help String ID for Help
716 @param QuestionFlags Flags in Question Header
717 @param NumericFlags Flags for numeric opcode
718 @param Minimum Numeric minimum value
719 @param Maximum Numeric maximum value
720 @param Step Numeric step for edit
721 @param Default Numeric default value
722 @param Data Destination for the created opcode binary
723
724 @retval EFI_SUCCESS Opcode is created successfully.
725 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
726 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
727
728 **/
729 EFI_STATUS
730 EFIAPI
731 CreateNumericOpCode (
732 IN EFI_QUESTION_ID QuestionId,
733 IN EFI_VARSTORE_ID VarStoreId,
734 IN UINT16 VarOffset,
735 IN EFI_STRING_ID Prompt,
736 IN EFI_STRING_ID Help,
737 IN UINT8 QuestionFlags,
738 IN UINT8 NumericFlags,
739 IN UINT64 Minimum,
740 IN UINT64 Maximum,
741 IN UINT64 Step,
742 IN UINT64 Default,
743 IN OUT EFI_HII_UPDATE_DATA *Data
744 )
745 {
746 EFI_STATUS Status;
747 EFI_IFR_NUMERIC Numeric;
748 MINMAXSTEP_DATA MinMaxStep;
749 EFI_IFR_TYPE_VALUE DefaultValue;
750 UINT8 *LocalBuffer;
751
752 ASSERT (Data != NULL && Data->Data != NULL);
753
754 if (!IsValidQuestionFlags (QuestionFlags) || !IsValidNumricFlags (NumericFlags)) {
755 return EFI_INVALID_PARAMETER;
756 }
757
758 if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) {
759 return EFI_BUFFER_TOO_SMALL;
760 }
761
762 Numeric.Header.OpCode = EFI_IFR_NUMERIC_OP;
763 Numeric.Header.Length = sizeof (EFI_IFR_NUMERIC);
764 Numeric.Header.Scope = 1;
765 Numeric.Question.QuestionId = QuestionId;
766 Numeric.Question.VarStoreId = VarStoreId;
767 Numeric.Question.VarStoreInfo.VarOffset = VarOffset;
768 Numeric.Question.Header.Prompt = Prompt;
769 Numeric.Question.Header.Help = Help;
770 Numeric.Question.Flags = QuestionFlags;
771 Numeric.Flags = NumericFlags;
772
773 switch (NumericFlags & EFI_IFR_NUMERIC_SIZE) {
774 case EFI_IFR_NUMERIC_SIZE_1:
775 MinMaxStep.u8.MinValue = (UINT8) Minimum;
776 MinMaxStep.u8.MaxValue = (UINT8) Maximum;
777 MinMaxStep.u8.Step = (UINT8) Step;
778 break;
779
780 case EFI_IFR_NUMERIC_SIZE_2:
781 MinMaxStep.u16.MinValue = (UINT16) Minimum;
782 MinMaxStep.u16.MaxValue = (UINT16) Maximum;
783 MinMaxStep.u16.Step = (UINT16) Step;
784 break;
785
786 case EFI_IFR_NUMERIC_SIZE_4:
787 MinMaxStep.u32.MinValue = (UINT32) Minimum;
788 MinMaxStep.u32.MaxValue = (UINT32) Maximum;
789 MinMaxStep.u32.Step = (UINT32) Step;
790 break;
791
792 case EFI_IFR_NUMERIC_SIZE_8:
793 MinMaxStep.u64.MinValue = Minimum;
794 MinMaxStep.u64.MaxValue = Maximum;
795 MinMaxStep.u64.Step = Step;
796 break;
797 }
798
799 CopyMem (&Numeric.data, &MinMaxStep, sizeof (MINMAXSTEP_DATA));
800
801 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
802 //
803 // CopyMem is used for EFI_IFR_NUMERIC to cover the unaligned address access.
804 //
805 CopyMem (LocalBuffer, &Numeric, sizeof (EFI_IFR_NUMERIC));
806 Data->Offset += sizeof (EFI_IFR_NUMERIC);
807
808 DefaultValue.u64 = Default;
809 Status = CreateDefaultOpCode (&DefaultValue, (UINT8) (NumericFlags & EFI_IFR_NUMERIC_SIZE), Data);
810 if (EFI_ERROR(Status)) {
811 return Status;
812 }
813
814 CreateEndOpCode (Data);
815
816 return EFI_SUCCESS;
817 }
818
819 /**
820 Create EFI_IFR_STRING_OP opcode.
821
822 If Data is NULL or Data->Data is NULL, then ASSERT.
823
824 @param QuestionId Question ID
825 @param VarStoreId Storage ID
826 @param VarOffset Offset in Storage
827 @param Prompt String ID for Prompt
828 @param Help String ID for Help
829 @param QuestionFlags Flags in Question Header
830 @param StringFlags Flags for string opcode
831 @param MinSize String minimum length
832 @param MaxSize String maximum length
833 @param Data Destination for the created opcode binary
834
835 @retval EFI_SUCCESS Opcode is created successfully.
836 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
837 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
838
839 **/
840 EFI_STATUS
841 EFIAPI
842 CreateStringOpCode (
843 IN EFI_QUESTION_ID QuestionId,
844 IN EFI_VARSTORE_ID VarStoreId,
845 IN UINT16 VarOffset,
846 IN EFI_STRING_ID Prompt,
847 IN EFI_STRING_ID Help,
848 IN UINT8 QuestionFlags,
849 IN UINT8 StringFlags,
850 IN UINT8 MinSize,
851 IN UINT8 MaxSize,
852 IN OUT EFI_HII_UPDATE_DATA *Data
853 )
854 {
855 EFI_IFR_STRING String;
856 UINT8 *LocalBuffer;
857
858 ASSERT (Data != NULL && Data->Data != NULL);
859
860 if (!IsValidQuestionFlags (QuestionFlags) || (StringFlags & ~EFI_IFR_STRING_MULTI_LINE) != 0) {
861 return EFI_INVALID_PARAMETER;
862 }
863
864 if (Data->Offset + sizeof (EFI_IFR_STRING) > Data->BufferSize) {
865 return EFI_BUFFER_TOO_SMALL;
866 }
867
868 String.Header.OpCode = EFI_IFR_STRING_OP;
869 String.Header.Length = sizeof (EFI_IFR_STRING);
870 String.Header.Scope = 0;
871 String.Question.Header.Prompt = Prompt;
872 String.Question.Header.Help = Help;
873 String.Question.QuestionId = QuestionId;
874 String.Question.VarStoreId = VarStoreId;
875 String.Question.VarStoreInfo.VarOffset = VarOffset;
876 String.Question.Flags = QuestionFlags;
877 String.MinSize = MinSize;
878 String.MaxSize = MaxSize;
879 String.Flags = StringFlags;
880
881 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
882 //
883 // CopyMem is used for EFI_IFR_STRING to cover the unaligned address access.
884 //
885 CopyMem (LocalBuffer, &String, sizeof (EFI_IFR_STRING));
886 Data->Offset += sizeof (EFI_IFR_STRING);
887
888 return EFI_SUCCESS;
889 }
890
891