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