variable.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,280 行 · 第 1/3 页

C
1,280
字号

  Status            = EFI_SUCCESS;
  CurrentFakeNVMap  = CallbackData->BmmFakeNvData;
  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
    NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
    if (NULL == NewMenuEntry) {
      return EFI_NOT_FOUND;
    }

    NewLoadContext              = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
    NewLoadContext->IsBootNext  = FALSE;
  }

  if (CurrentFakeNVMap->BootNext == BootOptionMenu.MenuNumber) {
    EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
    return EFI_SUCCESS;
  }

  NewMenuEntry = BOpt_GetMenuEntry (
                  &BootOptionMenu,
                  CurrentFakeNVMap->BootNext
                  );
  if (NULL == NewMenuEntry) {
    return EFI_NOT_FOUND;
  }

  NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
  Status = gRT->SetVariable (
                  L"BootNext",
                  &gEfiGlobalVariableGuid,
                  VAR_FLAG,
                  sizeof (UINT16),
                  &NewMenuEntry->OptionNumber
                  );
  NewLoadContext->IsBootNext              = TRUE;
  CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;
  return Status;
}

EFI_STATUS
Var_UpdateBootOrder (
  IN BMM_CALLBACK_DATA            *CallbackData
  )
{
  EFI_STATUS  Status;
  UINT16      Index;
  UINT16      *BootOrderList;
  UINT16      *NewBootOrderList;
  UINTN       BootOrderListSize;
  UINT8       *Map;

  BootOrderList     = NULL;
  BootOrderListSize = 0;

  //
  // First check whether BootOrder is present in current configuration
  //
  BootOrderList = BdsLibGetVariableAndSize (
                    L"BootOrder",
                    &gEfiGlobalVariableGuid,
                    &BootOrderListSize
                    );

  NewBootOrderList = EfiAllocateZeroPool (BootOrderListSize);
  if (!NewBootOrderList) {
    return EFI_OUT_OF_RESOURCES;
  }

  Map = EfiAllocateZeroPool (BootOrderListSize / sizeof (UINT16));
  if (!Map) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // If exists, delete it to hold new BootOrder
  //
  if (BootOrderList) {
    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
  }

  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
    NewBootOrderList[Index] = CallbackData->BmmFakeNvData->OptionOrder[Index] - 1;
  }

  Status = gRT->SetVariable (
                  L"BootOrder",
                  &gEfiGlobalVariableGuid,
                  VAR_FLAG,
                  BootOrderListSize,
                  NewBootOrderList
                  );
  SafeFreePool (BootOrderList);
  SafeFreePool (NewBootOrderList);
  SafeFreePool (Map);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  BOpt_FreeMenu (&BootOptionMenu);
  BOpt_GetBootOptions (CallbackData);

  return EFI_SUCCESS;

}

EFI_STATUS
Var_UpdateDriverOrder (
  IN BMM_CALLBACK_DATA            *CallbackData
  )
{
  EFI_STATUS  Status;
  UINT16      Index;
  UINT16      *DriverOrderList;
  UINT16      *NewDriverOrderList;
  UINTN       DriverOrderListSize;

  DriverOrderList     = NULL;
  DriverOrderListSize = 0;

  //
  // First check whether DriverOrder is present in current configuration
  //
  DriverOrderList = BdsLibGetVariableAndSize (
                      L"DriverOrder",
                      &gEfiGlobalVariableGuid,
                      &DriverOrderListSize
                      );

  NewDriverOrderList = EfiAllocateZeroPool (DriverOrderListSize);

  if (!NewDriverOrderList) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // If exists, delete it to hold new DriverOrder
  //
  if (DriverOrderList) {
    EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
  }

  for (Index = 0; Index < DriverOrderListSize; Index++) {
    NewDriverOrderList[Index] = CallbackData->BmmFakeNvData->OptionOrder[Index] - 1;
  }

  Status = gRT->SetVariable (
                  L"DriverOrder",
                  &gEfiGlobalVariableGuid,
                  VAR_FLAG,
                  DriverOrderListSize,
                  NewDriverOrderList
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  SafeFreePool (DriverOrderList);

  BOpt_FreeMenu (&DriverOptionMenu);
  BOpt_GetDriverOptions (CallbackData);
  return EFI_SUCCESS;
}

EFI_STATUS
Var_UpdateBBSOption (
  IN BMM_CALLBACK_DATA            *CallbackData
  )
{
  UINTN                       Index;
  UINTN                       Index2;
  VOID                        *BootOptionVar;
  CHAR16                      VarName[100];
  UINTN                       OptionSize;
  UINT16                      FilePathSize;
  UINT8                       *Ptr;
  EFI_STATUS                  Status;
  CHAR16                      DescString[100];
  UINTN                       NewOptionSize;
  UINT8                       *NewOptionPtr;
  UINT8                       *TempPtr;
  UINT32                      *Attribute;

  BM_MENU_OPTION              *OptionMenu;
  BM_LEGACY_DEVICE_CONTEXT    *LegacyDeviceContext;
  UINT8                       *LegacyDev;
  UINT8                       *VarData;
  UINTN                       VarSize;
  BM_MENU_ENTRY               *NewMenuEntry;
  BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;
  UINT8                       *OriginalPtr;
  UINT8                       *DisMap;
  UINTN                       Pos;
  UINTN                       Bit;
  UINT16                      *NewOrder;
  UINT16                      Tmp;

  LegacyDeviceContext = NULL;
  DisMap              = NULL;
  NewOrder            = NULL;

  if (FORM_SET_FD_ORDER_ID == CallbackData->BmmPreviousPageId) {
    OptionMenu            = (BM_MENU_OPTION *) &LegacyFDMenu;
    LegacyDev             = CallbackData->BmmFakeNvData->LegacyFD;
    CallbackData->BbsType = BBS_FLOPPY;
  } else {
    if (FORM_SET_HD_ORDER_ID == CallbackData->BmmPreviousPageId) {
      OptionMenu            = (BM_MENU_OPTION *) &LegacyHDMenu;
      LegacyDev             = CallbackData->BmmFakeNvData->LegacyHD;
      CallbackData->BbsType = BBS_HARDDISK;
    } else {
      if (FORM_SET_CD_ORDER_ID == CallbackData->BmmPreviousPageId) {
        OptionMenu            = (BM_MENU_OPTION *) &LegacyCDMenu;
        LegacyDev             = CallbackData->BmmFakeNvData->LegacyCD;
        CallbackData->BbsType = BBS_CDROM;
      } else {
        if (FORM_SET_NET_ORDER_ID == CallbackData->BmmPreviousPageId) {
          OptionMenu            = (BM_MENU_OPTION *) &LegacyNETMenu;
          LegacyDev             = CallbackData->BmmFakeNvData->LegacyNET;
          CallbackData->BbsType = BBS_EMBED_NETWORK;
        } else {
          OptionMenu            = (BM_MENU_OPTION *) &LegacyBEVMenu;
          LegacyDev             = CallbackData->BmmFakeNvData->LegacyBEV;
          CallbackData->BbsType = BBS_BEV_DEVICE;
        }
      }
    }
  }

  DisMap  = CallbackData->BmmOldFakeNVData.DisableMap;
  Status  = EFI_SUCCESS;

  //
  // Find the first device's context
  // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
  // because we just use it to fill the desc string, and user can not see the string in UI
  //
  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
    NewMenuEntry        = BOpt_GetMenuEntry (OptionMenu, Index);
    LegacyDeviceContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;
    if (0xFF != LegacyDev[0] && LegacyDev[0] == LegacyDeviceContext->Index) {
      DEBUG ((EFI_D_ERROR, "DescStr: %s\n", LegacyDeviceContext->Description));
      break;
    }
  }
  //
  // Update the Variable "LegacyDevOrder"
  //
  VarData = (UINT8 *) BdsLibGetVariableAndSize (
                        VarLegacyDevOrder,
                        &EfiLegacyDevOrderGuid,
                        &VarSize
                        );

  if (NULL == VarData) {
    return EFI_NOT_FOUND;
  }

  OriginalPtr = VarData;
  DevOrder    = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;

  while (VarData < VarData + VarSize) {
    if (DevOrder->BbsType == CallbackData->BbsType) {
      break;
    }

    VarData += sizeof (BBS_TYPE);
    VarData += *(UINT16 *) VarData;
    DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
  }

  if (VarData >= VarData + VarSize) {
    SafeFreePool (OriginalPtr);
    return EFI_NOT_FOUND;
  }

  NewOrder = (UINT16 *) EfiAllocateZeroPool (DevOrder->Length - sizeof (UINT16));
  if (NULL == NewOrder) {
    SafeFreePool (VarData);
    return EFI_OUT_OF_RESOURCES;
  }

  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
    if (0xFF == LegacyDev[Index]) {
      break;
    }

    NewOrder[Index] = LegacyDev[Index];
  }
  //
  // Only the enable/disable state of each boot device with same device type can be changed,
  // so we can count on the index information in DevOrder.
  // DisMap bit array is the only reliable source to check a device's en/dis state,
  // so we use DisMap to set en/dis state of each item in NewOrder array
  //
  for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {
    Tmp = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index2 * sizeof (UINT16));
    Tmp &= 0xFF;
    Pos = Tmp / 8;
    Bit = 7 - (Tmp % 8);
    if (DisMap[Pos] & (1 << Bit)) {
      NewOrder[Index] = (UINT16) (0xFF00 | Tmp);
      Index++;
    }
  }

  EfiCopyMem (
    (UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16),
    NewOrder,
    DevOrder->Length - sizeof (UINT16)
    );
  SafeFreePool (NewOrder);

  Status = gRT->SetVariable (
                  VarLegacyDevOrder,
                  &EfiLegacyDevOrderGuid,
                  VAR_FLAG,
                  VarSize,
                  OriginalPtr
                  );

  SafeFreePool (OriginalPtr);

  //
  // Update Optional Data of Boot####
  //
  BootOptionVar = GetLegacyBootOptionVar (CallbackData->BbsType, &Index, &OptionSize);

  if (NULL != BootOptionVar) {
    EfiCopyMem (
      DescString,
      LegacyDeviceContext->Description,
      EfiStrSize (LegacyDeviceContext->Description)
      );

    NewOptionSize = sizeof (UINT32) + sizeof (UINT16) + EfiStrSize (DescString) + sizeof (BBS_TABLE) + sizeof (UINT16);

    SPrint (VarName, 100, L"Boot%04x", Index);

    Ptr       = BootOptionVar;

    Attribute = (UINT32 *) Ptr;
    *Attribute |= LOAD_OPTION_ACTIVE;
    if (0xFF == LegacyDev[0]) {
      //
      // Disable this legacy boot option
      //
      *Attribute &= ~LOAD_OPTION_ACTIVE;
    }

    Ptr += sizeof (UINT32);

    FilePathSize = *(UINT16 *) Ptr;
    Ptr += sizeof (UINT16);

    NewOptionSize += FilePathSize;

    NewOptionPtr = EfiAllocateZeroPool (NewOptionSize);
    if (NULL == NewOptionPtr) {
      return EFI_OUT_OF_RESOURCES;
    }

    TempPtr = NewOptionPtr;

    //
    // Copy previous option data to new option except the description string
    //
    EfiCopyMem (
      TempPtr,
      BootOptionVar,
      sizeof (UINT32) + sizeof (UINT16)
      );

    TempPtr += (sizeof (UINT32) + sizeof (UINT16));

    EfiCopyMem (
      TempPtr,
      DescString,
      EfiStrSize (DescString)
      );

    TempPtr += EfiStrSize (DescString);

    //
    // Description = (CHAR16 *)Ptr;
    //
    Ptr += EfiStrSize ((CHAR16 *) Ptr);

    EfiCopyMem (
      TempPtr,
      Ptr,
      FilePathSize
      );

    TempPtr += FilePathSize;

    //
    // DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
    //
    Ptr += FilePathSize;

    //
    // Now Ptr point to optional data, i.e. Bbs Table
    //
    EfiCopyMem (
      TempPtr,
      LegacyDeviceContext->BbsTable,
      sizeof (BBS_TABLE)
      );

    TempPtr += sizeof (BBS_TABLE);
    *((UINT16 *) TempPtr) = (UINT16) LegacyDeviceContext->Index;

    Status = gRT->SetVariable (
                    VarName,
                    &gEfiGlobalVariableGuid,
                    VAR_FLAG,
                    NewOptionSize,
                    NewOptionPtr
                    );

    SafeFreePool (NewOptionPtr);
    SafeFreePool (BootOptionVar);
  }

  BOpt_GetBootOptions (CallbackData);
  return Status;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?