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