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