/** This function create a currently loaded Boot Option from the BMM. It then appends this Boot Option to the end of the "BootOrder" list. It also append this Boot Opotion to the end of BootOptionMenu. @param CallbackData The BMM context data. @param NvRamMap The file explorer formset internal state. @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation. @retval EFI_SUCCESS If function completes successfully. **/ EFI_STATUS Var_UpdateBootOption ( IN BMM_CALLBACK_DATA *CallbackData, IN FILE_EXPLORER_NV_DATA *NvRamMap ) { UINT16 *BootOrderList; UINT16 *NewBootOrderList; UINTN BootOrderListSize; UINT16 BootString[10]; VOID *Buffer; UINTN BufferSize; UINT8 *Ptr; UINT16 Index; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; BOOLEAN OptionalDataExist; EFI_STATUS Status; OptionalDataExist = FALSE; Index = BOpt_GetBootOptionNumber () ; UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index); if (NvRamMap->BootDescriptionData[0] == 0x0000) { StrCpy (NvRamMap->BootDescriptionData, BootString); } BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->BootDescriptionData); BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList); if (NvRamMap->BootOptionalData[0] != 0x0000) { OptionalDataExist = TRUE; BufferSize += StrSize (NvRamMap->BootOptionalData); } Buffer = AllocateZeroPool (BufferSize); if (NULL == Buffer) { return EFI_OUT_OF_RESOURCES; } NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = FALSE; NewLoadContext->LoadOptionSize = BufferSize; Ptr = (UINT8 *) Buffer; NewLoadContext->LoadOption = Ptr; *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE; NewLoadContext->Attributes = *((UINT32 *) Ptr); NewLoadContext->IsActive = TRUE; NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT); Ptr += sizeof (UINT32); *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList); NewLoadContext->FilePathListLength = *((UINT16 *) Ptr); Ptr += sizeof (UINT16); CopyMem ( Ptr, NvRamMap->BootDescriptionData, StrSize (NvRamMap->BootDescriptionData) ); NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData)); ASSERT (NewLoadContext->Description != NULL); NewMenuEntry->DisplayString = NewLoadContext->Description; CopyMem ( NewLoadContext->Description, (VOID *) Ptr, StrSize (NvRamMap->BootDescriptionData) ); Ptr += StrSize (NvRamMap->BootDescriptionData); CopyMem ( Ptr, CallbackData->LoadContext->FilePathList, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); ASSERT (NewLoadContext->FilePathList != NULL); CopyMem ( NewLoadContext->FilePathList, (VOID *) Ptr, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->OptionNumber = Index; NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionStrDepository ); NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->DisplayString, NULL); NewMenuEntry->HelpStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionHelpStrDepository ); NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->HelpString, NULL); if (OptionalDataExist) { Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList); CopyMem (Ptr, NvRamMap->BootOptionalData, StrSize (NvRamMap->BootOptionalData)); } Status = gRT->SetVariable ( BootString, &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, BufferSize, Buffer ); if (!EFI_ERROR (Status)) { BootOrderList = BdsLibGetVariableAndSize ( L"BootOrder", &gEfiGlobalVariableGuid, &BootOrderListSize ); ASSERT (BootOrderList != NULL); NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16)); ASSERT (NewBootOrderList != NULL); CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize); NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index; if (BootOrderList != NULL) { FreePool (BootOrderList); } Status = gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, BootOrderListSize + sizeof (UINT16), NewBootOrderList ); if (!EFI_ERROR (Status)) { FreePool (NewBootOrderList); NewBootOrderList = NULL; InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link); BootOptionMenu.MenuNumber++; NvRamMap->BootDescriptionData[0] = 0x0000; NvRamMap->BootOptionalData[0] = 0x0000; } } return EFI_SUCCESS; }
/** This function create a currently loaded Drive Option from the BMM. It then appends this Driver Option to the end of the "DriverOrder" list. It append this Driver Opotion to the end of DriverOptionMenu. @param CallbackData The BMM context data. @param HiiHandle The HII handle associated with the BMM formset. @param DescriptionData The description of this driver option. @param OptionalData The optional load option. @param ForceReconnect If to force reconnect. @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation. @retval EFI_SUCCESS If function completes successfully. **/ EFI_STATUS Var_UpdateDriverOption ( IN BMM_CALLBACK_DATA *CallbackData, IN EFI_HII_HANDLE HiiHandle, IN UINT16 *DescriptionData, IN UINT16 *OptionalData, IN UINT8 ForceReconnect ) { UINT16 Index; UINT16 *DriverOrderList; UINT16 *NewDriverOrderList; UINT16 DriverString[12]; UINTN DriverOrderListSize; VOID *Buffer; UINTN BufferSize; UINT8 *Ptr; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; BOOLEAN OptionalDataExist; EFI_STATUS Status; OptionalDataExist = FALSE; Index = BOpt_GetDriverOptionNumber (); UnicodeSPrint ( DriverString, sizeof (DriverString), L"Driver%04x", Index ); if (*DescriptionData == 0x0000) { StrCpyS (DescriptionData, 12, DriverString); } BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescriptionData); BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList); if (*OptionalData != 0x0000) { OptionalDataExist = TRUE; BufferSize += StrSize (OptionalData); } Buffer = AllocateZeroPool (BufferSize); if (NULL == Buffer) { return EFI_OUT_OF_RESOURCES; } NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { FreePool (Buffer); return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = FALSE; NewLoadContext->LoadOptionSize = BufferSize; Ptr = (UINT8 *) Buffer; NewLoadContext->LoadOption = Ptr; *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE | (ForceReconnect << 1); NewLoadContext->Attributes = *((UINT32 *) Ptr); NewLoadContext->IsActive = TRUE; NewLoadContext->ForceReconnect = (BOOLEAN) ((NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT)?1:0); Ptr += sizeof (UINT32); *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList); NewLoadContext->FilePathListLength = *((UINT16 *) Ptr); Ptr += sizeof (UINT16); CopyMem ( Ptr, DescriptionData, StrSize (DescriptionData) ); NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData)); ASSERT (NewLoadContext->Description != NULL); NewMenuEntry->DisplayString = NewLoadContext->Description; CopyMem ( NewLoadContext->Description, (VOID *) Ptr, StrSize (DescriptionData) ); Ptr += StrSize (DescriptionData); CopyMem ( Ptr, CallbackData->LoadContext->FilePathList, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); ASSERT (NewLoadContext->FilePathList != NULL); CopyMem ( NewLoadContext->FilePathList, (VOID *) Ptr, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewMenuEntry->HelpString = FileDevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->OptionNumber = Index; NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, DriverOptionStrDepository ); NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL); NewMenuEntry->HelpStringToken = GetStringTokenFromDepository ( CallbackData, DriverOptionHelpStrDepository ); NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL); if (OptionalDataExist) { Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList); CopyMem ( Ptr, OptionalData, StrSize (OptionalData) ); } Status = gRT->SetVariable ( DriverString, &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, BufferSize, Buffer ); if (!EFI_ERROR (Status)) { DriverOrderList = BdsLibGetVariableAndSize ( L"DriverOrder", &gEfiGlobalVariableGuid, &DriverOrderListSize ); NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16)); ASSERT (NewDriverOrderList != NULL); if (DriverOrderList != NULL) { CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize); EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid); } NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index; Status = gRT->SetVariable ( L"DriverOrder", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, DriverOrderListSize + sizeof (UINT16), NewDriverOrderList ); if (DriverOrderList != NULL) { FreePool (DriverOrderList); } DriverOrderList = NULL; FreePool (NewDriverOrderList); if (!EFI_ERROR (Status)) { InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link); DriverOptionMenu.MenuNumber++; // // Update "change boot order" page used data, append the new add boot // option at the end. // Index = 0; while (CallbackData->BmmFakeNvData.DriverOptionOrder[Index] != 0) { Index++; } CallbackData->BmmFakeNvData.DriverOptionOrder[Index] = (UINT32) (NewMenuEntry->OptionNumber + 1); *DescriptionData = 0x0000; *OptionalData = 0x0000; } } return EFI_SUCCESS; }
EFI_STATUS BOpt_FindFiles ( IN BMM_CALLBACK_DATA *CallbackData, IN BM_MENU_ENTRY *MenuEntry ) /*++ Routine Description Find files under current directory All files and sub-directories in current directory will be stored in DirectoryMenu for future use. Arguments: FileOption -- Pointer for Dir to explore Returns: TRUE -- Get files from current dir successfully FALSE -- Can't get files from current dir --*/ { EFI_FILE_HANDLE NewDir; EFI_FILE_HANDLE Dir; EFI_FILE_INFO *DirInfo; UINTN BufferSize; UINTN DirBufferSize; BM_MENU_ENTRY *NewMenuEntry; BM_FILE_CONTEXT *FileContext; BM_FILE_CONTEXT *NewFileContext; UINTN Pass; EFI_STATUS Status; UINTN OptionNumber; FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext; Dir = FileContext->FHandle; OptionNumber = 0; // // Open current directory to get files from it // Status = Dir->Open ( Dir, &NewDir, FileContext->FileName, EFI_FILE_READ_ONLY, 0 ); if (!FileContext->IsRoot) { Dir->Close (Dir); } if (EFI_ERROR (Status)) { return Status; } DirInfo = EfiLibFileInfo (NewDir); if (!DirInfo) { return EFI_NOT_FOUND; } if (!(DirInfo->Attribute & EFI_FILE_DIRECTORY)) { return EFI_INVALID_PARAMETER; } FileContext->DevicePath = EfiFileDevicePath ( FileContext->Handle, FileContext->FileName ); DirBufferSize = sizeof (EFI_FILE_INFO) + 1024; DirInfo = EfiAllocateZeroPool (DirBufferSize); if (!DirInfo) { return EFI_OUT_OF_RESOURCES; } // // Get all files in current directory // Pass 1 to get Directories // Pass 2 to get files that are EFI images // for (Pass = 1; Pass <= 2; Pass++) { NewDir->SetPosition (NewDir, 0); for (;;) { BufferSize = DirBufferSize; Status = NewDir->Read (NewDir, &BufferSize, DirInfo); if (EFI_ERROR (Status) || BufferSize == 0) { break; } if ((DirInfo->Attribute & EFI_FILE_DIRECTORY && Pass == 2) || (!(DirInfo->Attribute & EFI_FILE_DIRECTORY) && Pass == 1) ) { // // Pass 1 is for Directories // Pass 2 is for file names // continue; } if (!(BOpt_IsEfiImageName (DirInfo->FileName) || DirInfo->Attribute & EFI_FILE_DIRECTORY)) { // // Slip file unless it is a directory entry or a .EFI file // continue; } NewMenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext; NewFileContext->Handle = FileContext->Handle; NewFileContext->FileName = BOpt_AppendFileName ( FileContext->FileName, DirInfo->FileName ); NewFileContext->FHandle = NewDir; NewFileContext->DevicePath = EfiFileDevicePath ( NewFileContext->Handle, NewFileContext->FileName ); NewMenuEntry->HelpString = NULL; MenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, FileOptionStrDepository ); NewFileContext->IsDir = (BOOLEAN) ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY); if (NewFileContext->IsDir) { BufferSize = EfiStrLen (DirInfo->FileName) * 2 + 6; NewMenuEntry->DisplayString = EfiAllocateZeroPool (BufferSize); SPrint ( NewMenuEntry->DisplayString, BufferSize, L"<%s>", DirInfo->FileName ); } else { NewMenuEntry->DisplayString = EfiStrDuplicate (DirInfo->FileName); } NewFileContext->IsRoot = FALSE; NewFileContext->IsLoadFile = FALSE; NewFileContext->IsRemovableMedia = FALSE; NewMenuEntry->OptionNumber = OptionNumber; OptionNumber++; InsertTailList (&DirectoryMenu.Head, &NewMenuEntry->Link); } } DirectoryMenu.MenuNumber = OptionNumber; SafeFreePool (DirInfo); return EFI_SUCCESS; }
EFI_STATUS BOpt_GetBootOptions ( IN BMM_CALLBACK_DATA *CallbackData ) /*++ Routine Description: Build the BootOptionMenu according to BootOrder Variable. This Routine will access the Boot#### to get EFI_LOAD_OPTION Arguments: None Returns: The number of the Var Boot#### --*/ { UINTN Index; UINT16 BootString[10]; UINT8 *LoadOptionFromVar; UINT8 *LoadOption; UINTN BootOptionSize; BOOLEAN BootNextFlag; UINT16 *BootOrderList; UINTN BootOrderListSize; UINT16 *BootNext; UINTN BootNextSize; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; UINT8 *LoadOptionPtr; UINTN StringSize; UINTN OptionalDataSize; UINT8 *LoadOptionEnd; EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINTN MenuCount; UINT8 *Ptr; MenuCount = 0; BootOrderListSize = 0; BootNextSize = 0; BootOrderList = NULL; BootNext = NULL; LoadOptionFromVar = NULL; BOpt_FreeMenu (&BootOptionMenu); InitializeListHead (&BootOptionMenu.Head); // // Get the BootOrder from the Var // BootOrderList = BdsLibGetVariableAndSize ( L"BootOrder", &gEfiGlobalVariableGuid, &BootOrderListSize ); // // Get the BootNext from the Var // BootNext = BdsLibGetVariableAndSize ( L"BootNext", &gEfiGlobalVariableGuid, &BootNextSize ); if (BootNext) { if (BootNextSize != sizeof (UINT16)) { SafeFreePool (BootNext); BootNext = NULL; } } for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) { SPrint (BootString, sizeof (BootString), L"Boot%04x", BootOrderList[Index]); // // Get all loadoptions from the VAR // LoadOptionFromVar = BdsLibGetVariableAndSize ( BootString, &gEfiGlobalVariableGuid, &BootOptionSize ); if (!LoadOptionFromVar) { continue; } LoadOption = EfiAllocateZeroPool (BootOptionSize); if (!LoadOption) { continue; } EfiCopyMem (LoadOption, LoadOptionFromVar, BootOptionSize); SafeFreePool (LoadOptionFromVar); if (BootNext) { BootNextFlag = (BOOLEAN) (*BootNext == BootOrderList[Index]); } else { BootNextFlag = FALSE; } if (0 == (*((UINT32 *) LoadOption) & LOAD_OPTION_ACTIVE)) { SafeFreePool (LoadOption); continue; } // // BUGBUG: could not return EFI_OUT_OF_RESOURCES here directly. // the buffer allocated already should be freed before returning. // NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; LoadOptionPtr = LoadOption; LoadOptionEnd = LoadOption + BootOptionSize; NewMenuEntry->OptionNumber = BootOrderList[Index]; NewLoadContext->LoadOptionModified = FALSE; NewLoadContext->Deleted = FALSE; NewLoadContext->IsBootNext = BootNextFlag; // // Is a Legacy Device? // Ptr = (UINT8 *) LoadOption; // // Attribute = *(UINT32 *)Ptr; // Ptr += sizeof (UINT32); // // FilePathSize = *(UINT16 *)Ptr; // Ptr += sizeof (UINT16); // // Description = (CHAR16 *)Ptr; // Ptr += EfiStrSize ((CHAR16 *) Ptr); // // Now Ptr point to Device Path // DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr; if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) { NewLoadContext->IsLegacy = TRUE; } else { NewLoadContext->IsLegacy = FALSE; } // // LoadOption is a pointer type of UINT8 // for easy use with following LOAD_OPTION // embedded in this struct // NewLoadContext->LoadOption = LoadOption; NewLoadContext->LoadOptionSize = BootOptionSize; NewLoadContext->Attributes = *(UINT32 *) LoadOptionPtr; NewLoadContext->IsActive = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_ACTIVE); NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT); LoadOptionPtr += sizeof (UINT32); NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr; LoadOptionPtr += sizeof (UINT16); StringSize = EfiStrSize ((UINT16 *) LoadOptionPtr); NewLoadContext->Description = EfiAllocateZeroPool (StringSize); ASSERT (NewLoadContext->Description != NULL); EfiCopyMem ( NewLoadContext->Description, (UINT16 *) LoadOptionPtr, StringSize ); NewMenuEntry->DisplayString = NewLoadContext->Description; LoadOptionPtr += StringSize; NewLoadContext->FilePathList = EfiAllocateZeroPool (NewLoadContext->FilePathListLength); ASSERT (NewLoadContext->FilePathList != NULL); EfiCopyMem ( NewLoadContext->FilePathList, (EFI_DEVICE_PATH_PROTOCOL *) LoadOptionPtr, NewLoadContext->FilePathListLength ); NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionStrDepository ); NewMenuEntry->HelpStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionHelpStrDepository ); LoadOptionPtr += NewLoadContext->FilePathListLength; if (LoadOptionPtr < LoadOptionEnd) { OptionalDataSize = BootOptionSize - sizeof (UINT32) - sizeof (UINT16) - StringSize - NewLoadContext->FilePathListLength; NewLoadContext->OptionalData = EfiAllocateZeroPool (OptionalDataSize); ASSERT (NewLoadContext->OptionalData != NULL); EfiCopyMem ( NewLoadContext->OptionalData, LoadOptionPtr, OptionalDataSize ); NewLoadContext->OptionalDataSize = OptionalDataSize; } InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link); MenuCount++; } SafeFreePool (BootNext); SafeFreePool (BootOrderList); BootOptionMenu.MenuNumber = MenuCount; return MenuCount; }
EFI_STATUS BOpt_GetDriverOptions ( IN BMM_CALLBACK_DATA *CallbackData ) /*++ Routine Description: Build up all DriverOptionMenu Arguments: Returns: The Option Number --*/ { UINTN Index; UINT16 DriverString[12]; UINT8 *LoadOptionFromVar; UINT8 *LoadOption; UINTN DriverOptionSize; UINT16 *DriverOrderList; UINTN DriverOrderListSize; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; UINT8 *LoadOptionPtr; UINTN StringSize; UINTN OptionalDataSize; UINT8 *LoadOptionEnd; DriverOrderListSize = 0; DriverOrderList = NULL; DriverOptionSize = 0; LoadOptionFromVar = NULL; BOpt_FreeMenu (&DriverOptionMenu); InitializeListHead (&DriverOptionMenu.Head); // // Get the DriverOrder from the Var // DriverOrderList = BdsLibGetVariableAndSize ( L"DriverOrder", &gEfiGlobalVariableGuid, &DriverOrderListSize ); for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) { SPrint ( DriverString, sizeof (DriverString), L"Driver%04x", DriverOrderList[Index] ); // // Get all loadoptions from the VAR // LoadOptionFromVar = BdsLibGetVariableAndSize ( DriverString, &gEfiGlobalVariableGuid, &DriverOptionSize ); if (!LoadOptionFromVar) { continue; } LoadOption = EfiAllocateZeroPool (DriverOptionSize); if (!LoadOption) { continue; } EfiCopyMem (LoadOption, LoadOptionFromVar, DriverOptionSize); SafeFreePool (LoadOptionFromVar); NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; LoadOptionPtr = LoadOption; LoadOptionEnd = LoadOption + DriverOptionSize; NewMenuEntry->OptionNumber = DriverOrderList[Index]; NewLoadContext->LoadOptionModified = FALSE; NewLoadContext->Deleted = FALSE; NewLoadContext->IsLegacy = FALSE; // // LoadOption is a pointer type of UINT8 // for easy use with following LOAD_OPTION // embedded in this struct // NewLoadContext->LoadOption = LoadOption; NewLoadContext->LoadOptionSize = DriverOptionSize; NewLoadContext->Attributes = *(UINT32 *) LoadOptionPtr; NewLoadContext->IsActive = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_ACTIVE); NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT); LoadOptionPtr += sizeof (UINT32); NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr; LoadOptionPtr += sizeof (UINT16); StringSize = EfiStrSize ((UINT16 *) LoadOptionPtr); NewLoadContext->Description = EfiAllocateZeroPool (StringSize); ASSERT (NewLoadContext->Description != NULL); EfiCopyMem ( NewLoadContext->Description, (UINT16 *) LoadOptionPtr, StringSize ); NewMenuEntry->DisplayString = NewLoadContext->Description; LoadOptionPtr += StringSize; NewLoadContext->FilePathList = EfiAllocateZeroPool (NewLoadContext->FilePathListLength); ASSERT (NewLoadContext->FilePathList != NULL); EfiCopyMem ( NewLoadContext->FilePathList, (EFI_DEVICE_PATH_PROTOCOL *) LoadOptionPtr, NewLoadContext->FilePathListLength ); NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, DriverOptionStrDepository ); NewMenuEntry->HelpStringToken = GetStringTokenFromDepository ( CallbackData, DriverOptionHelpStrDepository ); LoadOptionPtr += NewLoadContext->FilePathListLength; if (LoadOptionPtr < LoadOptionEnd) { OptionalDataSize = DriverOptionSize - sizeof (UINT32) - sizeof (UINT16) - StringSize - NewLoadContext->FilePathListLength; NewLoadContext->OptionalData = EfiAllocateZeroPool (OptionalDataSize); ASSERT (NewLoadContext->OptionalData != NULL); EfiCopyMem ( NewLoadContext->OptionalData, LoadOptionPtr, OptionalDataSize ); NewLoadContext->OptionalDataSize = OptionalDataSize; } InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link); } SafeFreePool (DriverOrderList); DriverOptionMenu.MenuNumber = Index; return EFI_SUCCESS; }