devicemanager.c

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

C
503
字号
    CreateSubTitleOpCode (gStringTokenTable[Index], &UpdateData->Data);
    //
    // Add a single menu item - in this case a subtitle for the device type
    //
    UpdateData->DataCount = 1;

    //
    // Add default title for this label
    //
    Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, TRUE, UpdateData);
  }
  //
  // Add a space and an exit string.  Remember since we add things at the label and push other things beyond the
  // label down, we add this in reverse order
  //
  CreateSubTitleOpCode (STRING_TOKEN (STR_EXIT_STRING), &UpdateData->Data);
  Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, TRUE, UpdateData);
  CreateSubTitleOpCode (STR_EMPTY_STRING, &UpdateData->Data);
  Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) Count, TRUE, UpdateData);

  //
  // Get all the Hii handles
  //
  Status = BdsLibGetHiiHandles (Hii, &HandleBufferLength, &HiiHandles);
  ASSERT_EFI_ERROR (Status);

  for (Index = 1, BufferSize = 0; Index < HandleBufferLength; Index++) {
    //
    // Am not initializing Buffer since the first thing checked is the size
    // this way I can get the real buffersize in the smallest code size
    //
    Status = Hii->GetForms (Hii, Index, 0, &BufferSize, Buffer);

    if (Status != EFI_NOT_FOUND) {
      //
      // BufferSize should have the real size of the forms now
      //
      Buffer = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (Buffer != NULL);

      //
      // Am not initializing Buffer since the first thing checked is the size
      // this way I can get the real buffersize in the smallest code size
      //
      Status = Hii->GetForms (Hii, Index, 0, &BufferSize, Buffer);

      //
      // Skip EFI_HII_PACK_HEADER, advance to EFI_IFR_FORM_SET data.
      //
      FormSetData = (EFI_IFR_FORM_SET *) (Buffer + sizeof (EFI_HII_PACK_HEADER));

      //
      // If this formset belongs in the device manager, add it to the menu
      //
      if (FormSetData->Class != EFI_NON_DEVICE_CLASS) {

        StringLength  = 0x1000;
        String        = EfiLibAllocateZeroPool (StringLength);
        ASSERT (String != NULL);

        Status  = Hii->GetString (Hii, Index, FormSetData->FormSetTitle, TRUE, NULL, &StringLength, String);
        Status  = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &Token, String);

        //
        // If token value exceeded real token value - we need to add a new token values
        //
        if (Status == EFI_INVALID_PARAMETER) {
          Token     = 0;
          TokenHelp = 0;
          Status    = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &Token, String);
        }

        StringLength = 0x1000;
        if (FormSetData->Help == 0) {
          TokenHelp = 0;
        } else {
          Status = Hii->GetString (Hii, Index, FormSetData->Help, TRUE, NULL, &StringLength, String);
          if (StringLength == 0x02) {
            TokenHelp = 0;
          } else {
            Status = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &TokenHelp, String);
            if (Status == EFI_INVALID_PARAMETER) {
              TokenHelp = 0;
              Status    = Hii->NewString (Hii, NULL, FPCallbackInfo.DevMgrHiiHandle, &TokenHelp, String);
            }
          }
        }

        gBS->FreePool (String);

        CreateGotoOpCode (
          0x1000,     // Device Manager Page
          Token,      // Description String Token
          TokenHelp,  // Description Help String Token
          EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,  // Flag designating callback is active
          (UINT16) Index,                                     // Callback key value
          &UpdateData->Data                                   // Buffer to fill with op-code
          );

        //
        // In the off-chance that we have lots of extra tokens allocated to the DeviceManager
        // this ensures we are fairly re-using the tokens instead of constantly growing the token
        // storage for this one handle.  If we incremented the token value beyond what it normally
        // would use, we will fall back into the error path which seeds the token value with a 0
        // so that we can correctly add a token value.
        //
        if (TokenHelp == 0) {
          //
          // Since we didn't add help, only advance Token by 1
          //
          Token++;
        } else {
          Token     = (UINT16) (Token + 2);
          TokenHelp = (UINT16) (TokenHelp + 2);
        }
        //
        // This for loop basically will take the Class value which is a bitmask and
        // update the form for every active bit.  There will be a label at each bit
        // location.  So if someone had a device which a class of EFI_DISK_DEVICE_CLASS |
        // EFI_ON_BOARD_DEVICE_CLASS, this routine will unwind that mask and drop the menu entry
        // on each corresponding label.
        //
        for (Count = 1; Count < 0x10000; Count <<= 1) {
          //
          // This is an active bit, so update the form
          //
          if (FormSetData->Class & Count) {
            Hii->UpdateForm (
                  Hii,
                  FPCallbackInfo.DevMgrHiiHandle,
                  (EFI_FORM_LABEL) (FormSetData->Class & Count),
                  TRUE,
                  UpdateData
                  );
          }
        }
      }

      BufferSize = 0;
      //
      // Reset Buffer pointer to original location
      //
      gBS->FreePool (Buffer);
    }
  }
  //
  // Add oneof for video BIOS selection
  //
  VideoOption = BdsLibGetVariableAndSize (
                  L"VBIOS",
                  &gEfiGlobalVariableGuid,
                  &VideoOptionSize
                  );
  if (NULL == VideoOption) {
    FPCallbackInfo.Data.VideoBIOS = 0;
  } else {
    FPCallbackInfo.Data.VideoBIOS = VideoOption[0];
    gBS->FreePool (VideoOption);
  }

  ASSERT (FPCallbackInfo.Data.VideoBIOS <= 1);

  Status = gBS->AllocatePool (EfiBootServicesData, 2 * sizeof (IFR_OPTION), &IfrOptionList);
  if (IfrOptionList != NULL) {
    IfrOptionList[0].Flags        = EFI_IFR_FLAG_INTERACTIVE;
    IfrOptionList[0].Key          = SET_VIDEO_BIOS_TYPE_QUESTION_ID + 0x2000;
    IfrOptionList[0].StringToken  = STRING_TOKEN (STR_ONE_OF_PCI);
    IfrOptionList[0].Value        = 0;
    IfrOptionList[0].OptionString = NULL;
    IfrOptionList[1].Flags        = EFI_IFR_FLAG_INTERACTIVE;
    IfrOptionList[1].Key          = SET_VIDEO_BIOS_TYPE_QUESTION_ID + 0x2000;
    IfrOptionList[1].StringToken  = STRING_TOKEN (STR_ONE_OF_AGP);
    IfrOptionList[1].Value        = 1;
    IfrOptionList[1].OptionString = NULL;
    IfrOptionList[FPCallbackInfo.Data.VideoBIOS].Flags |= EFI_IFR_FLAG_DEFAULT;

    CreateOneOfOpCode (
      SET_VIDEO_BIOS_TYPE_QUESTION_ID,
      (UINT8) 1,
      STRING_TOKEN (STR_ONE_OF_VBIOS),
      STRING_TOKEN (STR_ONE_OF_VBIOS_HELP),
      IfrOptionList,
      2,
      &UpdateData->Data
      );

    UpdateData->DataCount = 4;
    Hii->UpdateForm (Hii, FPCallbackInfo.DevMgrHiiHandle, (EFI_FORM_LABEL) EFI_VBIOS_CLASS, TRUE, UpdateData);
    gBS->FreePool (IfrOptionList);
  }
  //
  // Drop the TPL level from EFI_TPL_DRIVER to EFI_TPL_APPLICATION
  //
  gBS->RestoreTPL (EFI_TPL_APPLICATION);
  
  BootDeviceMngrMenuResetRequired = FALSE;
  Status = gBrowser->SendForm (
                      gBrowser,
                      TRUE,                             // Use the database
                      &FPCallbackInfo.DevMgrHiiHandle,  // The HII Handle
                      1,
                      NULL,
                      FPCallbackInfo.CallbackHandle,
                      (UINT8 *) &FPCallbackInfo.Data,
                      NULL,
                      &BootDeviceMngrMenuResetRequired
                      );

  if (BootDeviceMngrMenuResetRequired) {
    EnableResetRequired ();
  }

  Hii->ResetStrings (Hii, FPCallbackInfo.DevMgrHiiHandle);

  //
  // We will have returned from processing a callback - user either hit ESC to exit, or selected
  // a target to display
  //
  if (gCallbackKey != 0 && gCallbackKey < 0x2000) {
    BootDeviceMngrMenuResetRequired = FALSE;
    Status = gBrowser->SendForm (
                        gBrowser,
                        TRUE,                             // Use the database
                        (EFI_HII_HANDLE *) &gCallbackKey, // The HII Handle
                        1,
                        NULL,
                        NULL,                             // This is the handle that the interface to the callback was installed on
                        NULL,
                        NULL,
                        &BootDeviceMngrMenuResetRequired
                        );

    if (BootDeviceMngrMenuResetRequired) {
      EnableResetRequired ();
    }
    //
    // Force return to Device Manager
    //
    gCallbackKey = 4;
  }

  if (gCallbackKey >= 0x2000) {
    gCallbackKey = 4;
  }

  gBS->FreePool (UpdateData);
  gBS->FreePool (HiiHandles);
  gBS->RaiseTPL (EFI_TPL_DRIVER);
  return Status;
}

⌨️ 快捷键说明

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