processoptions.c

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

C
1,634
字号
      AdjustNvMap (FileFormTags, MenuOption);
      NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];
    }

    Status = gRT->GetTime (&Time, NULL);
    if (EFI_ERROR (Status)) {
      return EFI_SUCCESS;
    }
    //
    // This for loop advances Index till it points immediately after a date entry.  We can then
    // subtract MenuOption->TagIndex from Index and find out relative to the start of the Date
    // structure which field we were in.  For instance, if TagIndex was 52, and we advanced Index
    // to 53 and found it to no longer point to a date operand, we were pointing to the last of 3
    // date operands.
    //
    //
    // This has BUGBUG potential....fix this - if someone wants to ask two DATE questions in a row.....code
    // against such silliness.
    //
    // Also, we want to internationalize the order of the date information.  We need to code for it as well.
    //
    for (Index = MenuOption->TagIndex; MenuOption->Tags[Index].Operand == EFI_IFR_DATE_OP; Index++)
      ;

    //
    // Count 0 = We entered on the first Date operand
    // Count 1 = We entered on the second Date operand
    // Count 2 = We entered on the third Date operand
    //
    Count = 3 - (Index - MenuOption->TagIndex);
    if (Count > 2) {
      return EFI_SUCCESS;
    }
    //
    // This is similar to numerics, except for the following:
    // We will under normal circumstances get 3 consecutive calls
    // to process this opcodes data.
    //
    *OptionString = EfiLibAllocateZeroPool ((gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow);
    ASSERT (*OptionString);

    switch (Count) {
    case 0:
      if (Selected) {
        Number = (UINT16) Time.Month;

        if (Tag->Step == 0) {
          MenuOption->OptCol++;
          Status = GetNumericInput (MenuOption, FileFormTagsHead, TRUE, Tag, DATE_NUMERIC, &Number);
        } else {
          //
          // Seed value with current setting
          //
          Tag->Value  = (UINT16) Time.Month;
          Status      = GetNumericInput (MenuOption, FileFormTagsHead, FALSE, Tag, DATE_NUMERIC, &Number);
        }

        if (!EFI_ERROR (Status)) {
          Time.Month = (UINT8) Number;
          gRT->SetTime (&Time);
        }
      }

      VariableDefinition->FakeNvRamMap[Tag->Id] = Time.Month;
      *OptionString[0]                          = LEFT_NUMERIC_DELIMITER;
      ValueToString (FormattedNumber, FALSE, (UINT64) Time.Month);
      Number = (UINT16) GetStringWidth (FormattedNumber);
      if (Number == 4) {
        FormattedNumber[2]  = FormattedNumber[1];
        FormattedNumber[1]  = FormattedNumber[0];
        FormattedNumber[0]  = L'0';
        Number              = 6;
      }

      StrnCpy (OptionString[0] + 1, FormattedNumber, Number);
      *(OptionString[0] + Number / 2) = DATE_SEPARATOR;
      EfiStrCat (OptionString[0] + (Number / 2) + 1, StringPtr);
      break;

    case 1:
      if (Selected) {
        Number = (UINT16) Time.Day;

        if (Tag->Step == 0) {
          Status = GetNumericInput (MenuOption, FileFormTagsHead, TRUE, Tag, DATE_NUMERIC, &Number);
        } else {
          //
          // Seed value with current setting
          //
          Tag->Value  = (UINT16) Time.Day;
          Status      = GetNumericInput (MenuOption, FileFormTagsHead, FALSE, Tag, DATE_NUMERIC, &Number);
        }

        if (!EFI_ERROR (Status)) {
          Time.Day = (UINT8) Number;
          gRT->SetTime (&Time);
        }
      }

      VariableDefinition->FakeNvRamMap[Tag->Id] = Time.Day;
      SetUnicodeMem (OptionString[0], 4, L' ');
      ValueToString (FormattedNumber, FALSE, (UINT64) Time.Day);
      Number = (UINT16) GetStringWidth (FormattedNumber);
      if (Number == 4) {
        FormattedNumber[2]  = FormattedNumber[1];
        FormattedNumber[1]  = FormattedNumber[0];
        FormattedNumber[0]  = L'0';
        Number              = 6;
      }

      StrnCpy (OptionString[0] + 4, FormattedNumber, Number);
      *(OptionString[0] + Number / 2 + 3) = DATE_SEPARATOR;
      EfiStrCat (OptionString[0] + (Number / 2) + 4, StringPtr);
      break;

    case 2:
      if (Selected) {
        Number = (UINT16) Time.Year;

        if (Tag->Step == 0) {
          Status = GetNumericInput (MenuOption, FileFormTagsHead, TRUE, Tag, DATE_NUMERIC, &Number);
        } else {
          //
          // Seed value with current setting
          //
          Status = GetNumericInput (MenuOption, FileFormTagsHead, FALSE, Tag, DATE_NUMERIC, &Number);
        }

        if (!EFI_ERROR (Status)) {
          Time.Year = (UINT16) Number;
          gRT->SetTime (&Time);
        }
      }

      Tag->Value  = (UINT16) Time.Year;
      VariableDefinition->FakeNvRamMap[Tag->Id]     = (UINT8) Tag->Value;
      VariableDefinition->FakeNvRamMap[Tag->Id + 1] = (UINT8) (Tag->Value >> 8);
      SetUnicodeMem (OptionString[0], 7, L' ');
      ValueToString (FormattedNumber, FALSE, (UINT64) Time.Year);
      Number = (UINT16) GetStringWidth (FormattedNumber);
      StrnCpy (OptionString[0] + 7, FormattedNumber, Number);
      *(OptionString[0] + Number / 2 + 6) = RIGHT_NUMERIC_DELIMITER;
      EfiStrCat (OptionString[0] + (Number / 2) + 7, StringPtr);
      break;
    }

    break;

  //
  // BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG
  // We need to add code to support the NVRam storage version of Date - this is the 1% case where someone
  // might want to set an alarm and actually preserve the data in NVRam so a driver can pick up the instruction
  // BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG
  //
  case EFI_IFR_TIME_OP:
    //
    // If the op-code we are looking at is larger than the latest created NvMap - we likely encountered a dynamically
    // created entry which has an expanded NvMap requirement.  We won't save this information - but we need to adjust
    // the NvMap so that we can properly display the information
    //
    if ((UINTN) (Tag->StorageStart + Tag->StorageWidth) > VariableDefinition->VariableFakeSize) {
      AdjustNvMap (FileFormTags, MenuOption);
      NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];
    }

    Status = gRT->GetTime (&Time, NULL);
    if (EFI_ERROR (Status)) {
      return EFI_SUCCESS;
    }
    //
    // This is similar to numerics, except for the following:
    // We will under normal circumstances get 3 consecutive calls
    // to process this opcodes data.
    //
    *OptionString = EfiLibAllocateZeroPool ((gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow);
    ASSERT (*OptionString);

    //
    // This for loop advances Index till it points immediately after a date entry.  We can then
    // subtract MenuOption->TagIndex from Index and find out relative to the start of the Date
    // structure which field we were in.  For instance, if TagIndex was 52, and we advanced Index
    // to 53 and found it to no longer point to a date operand, we were pointing to the last of 3
    // date operands.
    //
    for (Index = MenuOption->TagIndex; MenuOption->Tags[Index].Operand == EFI_IFR_TIME_OP; Index++)
      ;
    //
    // Count 0 = We entered on the first Date operand
    // Count 1 = We entered on the second Date operand
    // Count 2 = We entered on the third Date operand
    //
    Count = 3 - (Index - MenuOption->TagIndex);
    if (Count > 2) {
      return EFI_SUCCESS;
    }

    switch (Count) {
    case 0:
      Number = Time.Hour;
      break;

    case 1:
      Number = Time.Minute;
      break;

    case 2:
      Number = Time.Second;
    }
    //
    // Retrieve the current numeric value
    //
    if (Selected) {
      //
      // Go ask for input
      //
      if (Tag->Step == 0) {
        //
        // Manual Input
        //
        Status = GetNumericInput (MenuOption, FileFormTagsHead, TRUE, Tag, TIME_NUMERIC, &Number);
        if (!EFI_ERROR (Status)) {
          *NvRamMap       = Number;
          Time.Nanosecond = 0;
          gRT->SetTime (&Time);
        } else {
          return EFI_SUCCESS;
        }
      } else {
        //
        // Auto selection from list
        //
        Status = GetNumericInput (MenuOption, FileFormTagsHead, FALSE, Tag, TIME_NUMERIC, &Number);
        if (!EFI_ERROR (Status)) {
          *NvRamMap = Number;
        } else {
          return EFI_SUCCESS;
        }
      }

      switch (Count) {
      case 0:
        Time.Hour = (UINT8) Number;
        break;

      case 1:
        Time.Minute = (UINT8) Number;
        break;

      case 2:
        Time.Second = (UINT8) Number;
      }

      Time.Nanosecond = 0;
      gRT->SetTime (&Time);
    } else {
      switch (Count) {
      case 0:
        *OptionString[0] = LEFT_NUMERIC_DELIMITER;
        ValueToString (FormattedNumber, FALSE, (UINT64) Time.Hour);
        Number = (UINT16) GetStringWidth (FormattedNumber);
        if (Number == 4) {
          FormattedNumber[2]  = FormattedNumber[1];
          FormattedNumber[1]  = FormattedNumber[0];
          FormattedNumber[0]  = L'0';
          Number              = 6;
        }

        StrnCpy (OptionString[0] + 1, FormattedNumber, Number);
        *(OptionString[0] + Number / 2) = TIME_SEPARATOR;
        EfiStrCat (OptionString[0] + (Number / 2) + 1, StringPtr);
        break;

      case 1:
        SetUnicodeMem (OptionString[0], 4, L' ');
        ValueToString (FormattedNumber, FALSE, (UINT64) Time.Minute);
        Number = (UINT16) GetStringWidth (FormattedNumber);
        if (Number == 4) {
          FormattedNumber[2]  = FormattedNumber[1];
          FormattedNumber[1]  = FormattedNumber[0];
          FormattedNumber[0]  = L'0';
          Number              = 6;
        }

        StrnCpy (OptionString[0] + 4, FormattedNumber, Number);
        *(OptionString[0] + Number / 2 + 3) = TIME_SEPARATOR;
        EfiStrCat (OptionString[0] + (Number / 2) + 4, StringPtr);
        break;

      case 2:
        SetUnicodeMem (OptionString[0], 7, L' ');
        ValueToString (FormattedNumber, FALSE, (UINT64) Time.Second);
        Number = (UINT16) GetStringWidth (FormattedNumber);
        if (Number == 4) {
          FormattedNumber[2]  = FormattedNumber[1];
          FormattedNumber[1]  = FormattedNumber[0];
          FormattedNumber[0]  = L'0';
          Number              = 6;
        }

        StrnCpy (OptionString[0] + 7, FormattedNumber, Number);
        *(OptionString[0] + Number / 2 + 6) = RIGHT_NUMERIC_DELIMITER;
        EfiStrCat (OptionString[0] + (Number / 2) + 7, StringPtr);
        break;
      }
      //
      // BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG
      // We need to add code to support the NVRam storage version of Date - this is the 1% case where someone
      // might want to set an alarm and actually preserve the data in NVRam so a driver can pick up the instruction
      // BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG BUGBUG
      //
    }
    break;

  case EFI_IFR_STRING_OP:
    //
    // If the op-code we are looking at is larger than the latest created NvMap - we likely encountered a dynamically
    // created entry which has an expanded NvMap requirement.  We won't save this information - but we need to adjust
    // the NvMap so that we can properly display the information
    //
    if ((UINTN) (Tag->StorageStart + Tag->StorageWidth) > VariableDefinition->VariableFakeSize) {
      AdjustNvMap (FileFormTags, MenuOption);
      NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];
    }

    *OptionString = EfiLibAllocateZeroPool ((gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow);
    ASSERT (*OptionString);

⌨️ 快捷键说明

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