1 /** @file
2 HII Config Access protocol implementation of RamDiskDxe driver.
3
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "RamDiskImpl.h"
17
18 CHAR16 mRamDiskStorageName[] = L"RAM_DISK_CONFIGURATION";
19
20 RAM_DISK_CONFIG_PRIVATE_DATA mRamDiskConfigPrivateDataTemplate = {
21 RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE,
22 {
23 EFI_PAGE_SIZE,
24 RAM_DISK_BOOT_SERVICE_DATA_MEMORY
25 },
26 {
27 RamDiskExtractConfig,
28 RamDiskRouteConfig,
29 RamDiskCallback
30 }
31 };
32
33 HII_VENDOR_DEVICE_PATH mRamDiskHiiVendorDevicePath = {
34 {
35 {
36 HARDWARE_DEVICE_PATH,
37 HW_VENDOR_DP,
38 {
39 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
40 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
41 }
42 },
43 RAM_DISK_FORM_SET_GUID
44 },
45 {
46 END_DEVICE_PATH_TYPE,
47 END_ENTIRE_DEVICE_PATH_SUBTYPE,
48 {
49 (UINT8) (END_DEVICE_PATH_LENGTH),
50 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
51 }
52 }
53 };
54
55
56 /**
57 This function publish the RAM disk configuration Form.
58
59 @param[in, out] ConfigPrivateData
60 Points to RAM disk configuration private data.
61
62 @retval EFI_SUCCESS HII Form is installed successfully.
63 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
64 @retval Others Other errors as indicated.
65
66 **/
67 EFI_STATUS
InstallRamDiskConfigForm(IN OUT RAM_DISK_CONFIG_PRIVATE_DATA * ConfigPrivateData)68 InstallRamDiskConfigForm (
69 IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivateData
70 )
71 {
72 EFI_STATUS Status;
73 EFI_HII_HANDLE HiiHandle;
74 EFI_HANDLE DriverHandle;
75 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
76
77 DriverHandle = NULL;
78 ConfigAccess = &ConfigPrivateData->ConfigAccess;
79 Status = gBS->InstallMultipleProtocolInterfaces (
80 &DriverHandle,
81 &gEfiDevicePathProtocolGuid,
82 &mRamDiskHiiVendorDevicePath,
83 &gEfiHiiConfigAccessProtocolGuid,
84 ConfigAccess,
85 NULL
86 );
87 if (EFI_ERROR (Status)) {
88 return Status;
89 }
90
91 ConfigPrivateData->DriverHandle = DriverHandle;
92
93 //
94 // Publish the HII package list
95 //
96 HiiHandle = HiiAddPackages (
97 &gRamDiskFormSetGuid,
98 DriverHandle,
99 RamDiskDxeStrings,
100 RamDiskHiiBin,
101 NULL
102 );
103 if (HiiHandle == NULL) {
104 gBS->UninstallMultipleProtocolInterfaces (
105 DriverHandle,
106 &gEfiDevicePathProtocolGuid,
107 &mRamDiskHiiVendorDevicePath,
108 &gEfiHiiConfigAccessProtocolGuid,
109 ConfigAccess,
110 NULL
111 );
112 return EFI_OUT_OF_RESOURCES;
113 }
114
115 ConfigPrivateData->HiiHandle = HiiHandle;
116
117 return EFI_SUCCESS;
118 }
119
120
121 /**
122 This function removes RAM disk configuration Form.
123
124 @param[in, out] ConfigPrivateData
125 Points to RAM disk configuration private data.
126
127 **/
128 VOID
UninstallRamDiskConfigForm(IN OUT RAM_DISK_CONFIG_PRIVATE_DATA * ConfigPrivateData)129 UninstallRamDiskConfigForm (
130 IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivateData
131 )
132 {
133 //
134 // Uninstall HII package list
135 //
136 if (ConfigPrivateData->HiiHandle != NULL) {
137 HiiRemovePackages (ConfigPrivateData->HiiHandle);
138 ConfigPrivateData->HiiHandle = NULL;
139 }
140
141 //
142 // Uninstall HII Config Access Protocol
143 //
144 if (ConfigPrivateData->DriverHandle != NULL) {
145 gBS->UninstallMultipleProtocolInterfaces (
146 ConfigPrivateData->DriverHandle,
147 &gEfiDevicePathProtocolGuid,
148 &mRamDiskHiiVendorDevicePath,
149 &gEfiHiiConfigAccessProtocolGuid,
150 &ConfigPrivateData->ConfigAccess,
151 NULL
152 );
153 ConfigPrivateData->DriverHandle = NULL;
154 }
155
156 FreePool (ConfigPrivateData);
157 }
158
159
160 /**
161 Unregister all registered RAM disks.
162
163 **/
164 VOID
UnregisterAllRamDisks(VOID)165 UnregisterAllRamDisks (
166 VOID
167 )
168 {
169 LIST_ENTRY *Entry;
170 LIST_ENTRY *NextEntry;
171 RAM_DISK_PRIVATE_DATA *PrivateData;
172
173 if (!IsListEmpty(&RegisteredRamDisks)) {
174 EFI_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {
175 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
176
177 gBS->UninstallMultipleProtocolInterfaces (
178 PrivateData->Handle,
179 &gEfiBlockIoProtocolGuid,
180 &PrivateData->BlockIo,
181 &gEfiBlockIo2ProtocolGuid,
182 &PrivateData->BlockIo2,
183 &gEfiDevicePathProtocolGuid,
184 (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath,
185 NULL
186 );
187
188 RemoveEntryList (&PrivateData->ThisInstance);
189
190 if (RamDiskCreateHii == PrivateData->CreateMethod) {
191 //
192 // If a RAM disk is created within HII, then the RamDiskDxe driver
193 // driver is responsible for freeing the allocated memory for the
194 // RAM disk.
195 //
196 FreePool ((VOID *)(UINTN) PrivateData->StartingAddr);
197 }
198
199 FreePool (PrivateData->DevicePath);
200 FreePool (PrivateData);
201 }
202 }
203 }
204
205
206 /**
207 This function allows a caller to extract the current configuration for one
208 or more named elements from the target driver.
209
210 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
211 @param[in] Request A null-terminated Unicode string in
212 <ConfigRequest> format.
213 @param[out] Progress On return, points to a character in the Request
214 string. Points to the string's null terminator if
215 request was successful. Points to the most recent
216 '&' before the first failing name/value pair (or
217 the beginning of the string if the failure is in
218 the first name/value pair) if the request was not
219 successful.
220 @param[out] Results A null-terminated Unicode string in
221 <ConfigAltResp> format which has all values filled
222 in for the names in the Request string. String to
223 be allocated by the called function.
224
225 @retval EFI_SUCCESS The Results is filled with the requested
226 values.
227 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
228 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
229 @retval EFI_NOT_FOUND Routing data doesn't match any storage in
230 this driver.
231
232 **/
233 EFI_STATUS
234 EFIAPI
RamDiskExtractConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN CONST EFI_STRING Request,OUT EFI_STRING * Progress,OUT EFI_STRING * Results)235 RamDiskExtractConfig (
236 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
237 IN CONST EFI_STRING Request,
238 OUT EFI_STRING *Progress,
239 OUT EFI_STRING *Results
240 )
241 {
242 if (Progress == NULL || Results == NULL) {
243 return EFI_INVALID_PARAMETER;
244 }
245 *Progress = Request;
246 return EFI_NOT_FOUND;
247 }
248
249
250 /**
251 This function processes the results of changes in configuration.
252
253 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
254 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
255 format.
256 @param[out] Progress A pointer to a string filled in with the offset of
257 the most recent '&' before the first failing
258 name/value pair (or the beginning of the string if
259 the failure is in the first name/value pair) or
260 the terminating NULL if all was successful.
261
262 @retval EFI_SUCCESS The Results is processed successfully.
263 @retval EFI_INVALID_PARAMETER Configuration is NULL.
264 @retval EFI_NOT_FOUND Routing data doesn't match any storage in
265 this driver.
266
267 **/
268 EFI_STATUS
269 EFIAPI
RamDiskRouteConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN CONST EFI_STRING Configuration,OUT EFI_STRING * Progress)270 RamDiskRouteConfig (
271 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
272 IN CONST EFI_STRING Configuration,
273 OUT EFI_STRING *Progress
274 )
275 {
276 if (Configuration == NULL || Progress == NULL) {
277 return EFI_INVALID_PARAMETER;
278 }
279
280 return EFI_NOT_FOUND;
281 }
282
283
284 /**
285 Allocate memory and register the RAM disk created within RamDiskDxe
286 driver HII.
287
288 @param[in] Size If creating raw, size of the RAM disk to create.
289 If creating from file, zero.
290 @param[in] FileHandle If creating raw, NULL. If creating from file, the
291 file handle.
292 @param[in] MemoryType Type of memory to be used to create RAM Disk.
293
294 @retval EFI_SUCCESS RAM disk is created and registered.
295 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to match the
296 size required.
297
298 **/
299 EFI_STATUS
HiiCreateRamDisk(IN UINT64 Size,IN EFI_FILE_HANDLE FileHandle,IN UINT8 MemoryType)300 HiiCreateRamDisk (
301 IN UINT64 Size,
302 IN EFI_FILE_HANDLE FileHandle,
303 IN UINT8 MemoryType
304 )
305 {
306 EFI_STATUS Status;
307 UINTN BufferSize;
308 UINT64 *StartingAddr;
309 EFI_INPUT_KEY Key;
310 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
311 RAM_DISK_PRIVATE_DATA *PrivateData;
312 EFI_FILE_INFO *FileInformation;
313
314 FileInformation = NULL;
315 StartingAddr = NULL;
316
317 if (FileHandle != NULL) {
318 //
319 // Create from file.
320 //
321 FileInformation = FileInfo (FileHandle);
322 if (NULL == FileInformation) {
323 do {
324 CreatePopUp (
325 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
326 &Key,
327 L"",
328 L"Not enough memory to get the file information!",
329 L"Press ENTER to continue ...",
330 L"",
331 NULL
332 );
333 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
334
335 return EFI_OUT_OF_RESOURCES;
336 }
337
338 //
339 // Update the size of RAM disk according to the file size.
340 //
341 Size = FileInformation->FileSize;
342 }
343
344 if (Size > (UINTN) -1) {
345 do {
346 CreatePopUp (
347 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
348 &Key,
349 L"",
350 L"The given RAM disk size is too large!",
351 L"Press ENTER to continue ...",
352 L"",
353 NULL
354 );
355 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
356
357 return EFI_OUT_OF_RESOURCES;
358 }
359
360 if (MemoryType == RAM_DISK_BOOT_SERVICE_DATA_MEMORY) {
361 Status = gBS->AllocatePool (
362 EfiBootServicesData,
363 (UINTN)Size,
364 (VOID**)&StartingAddr
365 );
366 } else if (MemoryType == RAM_DISK_RESERVED_MEMORY) {
367 Status = gBS->AllocatePool (
368 EfiReservedMemoryType,
369 (UINTN)Size,
370 (VOID**)&StartingAddr
371 );
372 } else {
373 Status = EFI_INVALID_PARAMETER;
374 }
375
376 if ((StartingAddr == NULL) || EFI_ERROR(Status)) {
377 do {
378 CreatePopUp (
379 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
380 &Key,
381 L"",
382 L"Not enough memory to create the RAM disk!",
383 L"Press ENTER to continue ...",
384 L"",
385 NULL
386 );
387 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
388
389 return EFI_OUT_OF_RESOURCES;
390 }
391
392 if (FileHandle != NULL) {
393 //
394 // Copy the file content to the RAM disk.
395 //
396 BufferSize = (UINTN) Size;
397 FileHandle->Read (
398 FileHandle,
399 &BufferSize,
400 (VOID *)(UINTN) StartingAddr
401 );
402 if (BufferSize != FileInformation->FileSize) {
403 do {
404 CreatePopUp (
405 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
406 &Key,
407 L"",
408 L"File content read error!",
409 L"Press ENTER to continue ...",
410 L"",
411 NULL
412 );
413 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
414
415 return EFI_DEVICE_ERROR;
416 }
417 }
418
419 //
420 // Register the newly created RAM disk.
421 //
422 Status = RamDiskRegister (
423 ((UINT64)(UINTN) StartingAddr),
424 Size,
425 &gEfiVirtualDiskGuid,
426 NULL,
427 &DevicePath
428 );
429 if (EFI_ERROR (Status)) {
430 do {
431 CreatePopUp (
432 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
433 &Key,
434 L"",
435 L"Fail to register the newly created RAM disk!",
436 L"Press ENTER to continue ...",
437 L"",
438 NULL
439 );
440 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
441
442 return Status;
443 }
444
445 //
446 // If RAM disk is created within HII, memory should be freed when the
447 // RAM disk is unregisterd.
448 //
449 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (RegisteredRamDisks.BackLink);
450 PrivateData->CreateMethod = RamDiskCreateHii;
451
452 return EFI_SUCCESS;
453 }
454
455
456 /**
457 This function updates the registered RAM disks list on the main form.
458
459 @param[in, out] ConfigPrivate
460 Private data for configurating hii data for RAM
461 disks.
462
463 **/
464 VOID
UpdateMainForm(IN OUT RAM_DISK_CONFIG_PRIVATE_DATA * ConfigPrivate)465 UpdateMainForm (
466 IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate
467 )
468 {
469 VOID *StartOpCodeHandle;
470 VOID *EndOpCodeHandle;
471 EFI_IFR_GUID_LABEL *StartLabel;
472 EFI_IFR_GUID_LABEL *EndLabel;
473 LIST_ENTRY *Entry;
474 UINTN Index;
475 RAM_DISK_PRIVATE_DATA *PrivateData;
476 CHAR16 *String;
477 CHAR16 RamDiskStr[128];
478 EFI_STRING_ID StringId;
479
480 //
481 // Init OpCode Handle
482 //
483 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
484 ASSERT (StartOpCodeHandle != NULL);
485
486 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
487 ASSERT (EndOpCodeHandle != NULL);
488
489 //
490 // Create Hii Extend Label OpCode as the start opcode
491 //
492 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
493 StartOpCodeHandle,
494 &gEfiIfrTianoGuid,
495 NULL,
496 sizeof (EFI_IFR_GUID_LABEL)
497 );
498 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
499 StartLabel->Number = MAIN_LABEL_LIST_START;
500
501 //
502 // Create Hii Extend Label OpCode as the end opcode
503 //
504 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
505 EndOpCodeHandle,
506 &gEfiIfrTianoGuid,
507 NULL,
508 sizeof (EFI_IFR_GUID_LABEL)
509 );
510 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
511 EndLabel->Number = MAIN_LABEL_LIST_END;
512
513 Index = 0;
514 EFI_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {
515 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
516 PrivateData->CheckBoxId = (EFI_QUESTION_ID)
517 (MAIN_CHECKBOX_QUESTION_ID_START + Index);
518 //
519 // CheckBox is unchecked by default.
520 //
521 PrivateData->CheckBoxChecked = FALSE;
522 String = RamDiskStr;
523
524 UnicodeSPrint (
525 String,
526 sizeof (RamDiskStr),
527 L" RAM Disk %d: [0x%lx, 0x%lx]\n",
528 Index,
529 PrivateData->StartingAddr,
530 PrivateData->StartingAddr + PrivateData->Size - 1
531 );
532
533 StringId = HiiSetString (ConfigPrivate->HiiHandle, 0, RamDiskStr, NULL);
534 ASSERT (StringId != 0);
535
536 HiiCreateCheckBoxOpCode (
537 StartOpCodeHandle,
538 PrivateData->CheckBoxId,
539 0,
540 0,
541 StringId,
542 STRING_TOKEN (STR_RAM_DISK_LIST_HELP),
543 EFI_IFR_FLAG_CALLBACK,
544 0,
545 NULL
546 );
547
548 Index++;
549 }
550
551 HiiUpdateForm (
552 ConfigPrivate->HiiHandle,
553 &gRamDiskFormSetGuid,
554 MAIN_FORM_ID,
555 StartOpCodeHandle,
556 EndOpCodeHandle
557 );
558
559 HiiFreeOpCodeHandle (StartOpCodeHandle);
560 HiiFreeOpCodeHandle (EndOpCodeHandle);
561 }
562
563
564 /**
565 This function processes the results of changes in configuration.
566
567 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
568 @param[in] Action Specifies the type of action taken by the browser.
569 @param[in] QuestionId A unique value which is sent to the original
570 exporting driver so that it can identify the type
571 of data to expect.
572 @param[in] Type The type of value for the question.
573 @param[in] Value A pointer to the data being sent to the original
574 exporting driver.
575 @param[out] ActionRequest On return, points to the action requested by the
576 callback function.
577
578 @retval EFI_SUCCESS The callback successfully handled the action.
579 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
580 variable and its data.
581 @retval EFI_DEVICE_ERROR The variable could not be saved.
582 @retval EFI_UNSUPPORTED The specified Action is not supported by the
583 callback.
584
585 **/
586 EFI_STATUS
587 EFIAPI
RamDiskCallback(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN EFI_BROWSER_ACTION Action,IN EFI_QUESTION_ID QuestionId,IN UINT8 Type,IN EFI_IFR_TYPE_VALUE * Value,OUT EFI_BROWSER_ACTION_REQUEST * ActionRequest)588 RamDiskCallback (
589 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
590 IN EFI_BROWSER_ACTION Action,
591 IN EFI_QUESTION_ID QuestionId,
592 IN UINT8 Type,
593 IN EFI_IFR_TYPE_VALUE *Value,
594 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
595 )
596 {
597 EFI_STATUS Status;
598 RAM_DISK_PRIVATE_DATA *PrivateData;
599 RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;
600 EFI_DEVICE_PATH_PROTOCOL *FileDevPath;
601 EFI_FILE_HANDLE FileHandle;
602 LIST_ENTRY *Entry;
603 LIST_ENTRY *NextEntry;
604
605 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
606 return EFI_INVALID_PARAMETER;
607 }
608
609 ConfigPrivate = RAM_DISK_CONFIG_PRIVATE_FROM_THIS (This);
610
611 if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
612 Status = EFI_UNSUPPORTED;
613 if (QuestionId == CREATE_RAW_SIZE_QUESTION_ID) {
614 Value->u64 = EFI_PAGE_SIZE;
615 ConfigPrivate->ConfigStore.Size = EFI_PAGE_SIZE;
616 Status = EFI_SUCCESS;
617 } else if (QuestionId == CREATE_RAW_MEMORY_TYPE_QUESTION_ID) {
618 Value->u8 = RAM_DISK_BOOT_SERVICE_DATA_MEMORY;
619 ConfigPrivate->ConfigStore.MemType = RAM_DISK_BOOT_SERVICE_DATA_MEMORY;
620 Status = EFI_SUCCESS;
621 }
622 return Status;
623 }
624
625 if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
626 (Action != EFI_BROWSER_ACTION_CHANGING) &&
627 (Action != EFI_BROWSER_ACTION_FORM_OPEN)) {
628 return EFI_UNSUPPORTED;
629 }
630
631 //
632 // Update the RAM disk list show at the main form first.
633 //
634 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
635 Status = EFI_UNSUPPORTED;
636 if (QuestionId == MAIN_GOTO_FILE_EXPLORER_ID) {
637 UpdateMainForm (ConfigPrivate);
638 Status = EFI_SUCCESS;
639 }
640 return Status;
641 }
642
643 Status = EFI_SUCCESS;
644
645 if (Action == EFI_BROWSER_ACTION_CHANGING) {
646 switch (QuestionId) {
647 case MAIN_GOTO_FILE_EXPLORER_ID:
648 Status = ChooseFile (NULL, NULL, NULL, &FileDevPath);
649 if (EFI_ERROR (Status)) {
650 break;
651 }
652
653 if (FileDevPath != NULL) {
654 //
655 // Open the file.
656 //
657 Status = OpenFileByDevicePath (
658 &FileDevPath,
659 &FileHandle,
660 EFI_FILE_MODE_READ,
661 0
662 );
663 if (EFI_ERROR (Status)) {
664 break;
665 }
666
667 //
668 // Create from file, RAM disk size is zero. It will be updated
669 // according to the file size.
670 //
671 Status = HiiCreateRamDisk (
672 0,
673 FileHandle,
674 ConfigPrivate->ConfigStore.MemType
675 );
676 if (EFI_ERROR (Status)) {
677 break;
678 }
679
680 //
681 // Refresh the registered RAM disks list.
682 //
683 UpdateMainForm (ConfigPrivate);
684 }
685 break;
686
687 default:
688 break;
689 }
690 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
691 switch (QuestionId) {
692 case MAIN_REMOVE_RD_QUESTION_ID:
693 //
694 // Remove the selected RAM disks
695 //
696 EFI_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {
697 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
698 if (PrivateData->CheckBoxChecked) {
699 RamDiskUnregister (
700 (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath
701 );
702 }
703 }
704
705 UpdateMainForm (ConfigPrivate);
706
707 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
708 break;
709
710 case CREATE_RAW_SIZE_QUESTION_ID:
711 ConfigPrivate->ConfigStore.Size = Value->u64;
712 break;
713
714 case CREATE_RAW_MEMORY_TYPE_QUESTION_ID:
715 ConfigPrivate->ConfigStore.MemType = Value->u8;
716 break;
717
718 case CREATE_RAW_SUBMIT_QUESTION_ID:
719 //
720 // Create raw, FileHandle is NULL.
721 //
722 Status = HiiCreateRamDisk (
723 ConfigPrivate->ConfigStore.Size,
724 NULL,
725 ConfigPrivate->ConfigStore.MemType
726 );
727 if (EFI_ERROR (Status)) {
728 break;
729 }
730
731 //
732 // Refresh the registered RAM disks list.
733 //
734 UpdateMainForm (ConfigPrivate);
735
736 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
737 break;
738
739 case CREATE_RAW_DISCARD_QUESTION_ID:
740 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
741 break;
742
743 default:
744 //
745 // QuestionIds for checkboxes
746 //
747 if ((QuestionId >= MAIN_CHECKBOX_QUESTION_ID_START) &&
748 (QuestionId < CREATE_RAW_RAM_DISK_FORM_ID)) {
749 EFI_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {
750 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
751 if (PrivateData->CheckBoxId == QuestionId) {
752 PrivateData->CheckBoxChecked = (BOOLEAN) (Value->u8 != 0);
753 }
754 }
755 }
756 break;
757 }
758 }
759
760 return EFI_SUCCESS;
761 }
762