+typedef struct {\r
+ EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType;\r
+ EFI_GUID *Guid;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION *Options;\r
+ UINTN OptionCount;\r
+} BM_COLLECT_LOAD_OPTIONS_PARAM;\r
+\r
+/**\r
+ Visitor function to collect the Platform Recovery load options or OS Recovery\r
+ load options from NV storage.\r
+\r
+ @param Name Variable name.\r
+ @param Guid Variable GUID.\r
+ @param Context The same context passed to BmForEachVariable.\r
+**/\r
+VOID\r
+BmCollectLoadOptions (\r
+ IN CHAR16 *Name,\r
+ IN EFI_GUID *Guid,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType;\r
+ UINT16 OptionNumber;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION Option;\r
+ UINTN Index;\r
+ BM_COLLECT_LOAD_OPTIONS_PARAM *Param;\r
+\r
+ Param = (BM_COLLECT_LOAD_OPTIONS_PARAM *) Context;\r
+\r
+ if (CompareGuid (Guid, Param->Guid) && (\r
+ Param->OptionType == LoadOptionTypePlatformRecovery &&\r
+ BmIsValidLoadOptionVariableName (Name, &OptionType, &OptionNumber) &&\r
+ OptionType == LoadOptionTypePlatformRecovery\r
+ )) {\r
+ Status = EfiBootManagerVariableToLoadOptionEx (Name, Guid, &Option);\r
+ if (!EFI_ERROR (Status)) {\r
+ for (Index = 0; Index < Param->OptionCount; Index++) {\r
+ if (Param->Options[Index].OptionNumber > Option.OptionNumber) {\r
+ break;\r
+ }\r
+ }\r
+ Param->Options = ReallocatePool (\r
+ Param->OptionCount * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION),\r
+ (Param->OptionCount + 1) * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION),\r
+ Param->Options\r
+ );\r
+ ASSERT (Param->Options != NULL);\r
+ CopyMem (&Param->Options[Index + 1], &Param->Options[Index], (Param->OptionCount - Index) * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));\r
+ CopyMem (&Param->Options[Index], &Option, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));\r
+ Param->OptionCount++;\r
+ }\r
+ }\r
+}\r
+\r