processoptions.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,634 行 · 第 1/5 页
C
1,634 行
if (Selected) {
StringPtr = EfiLibAllocateZeroPool (Tag->Maximum);
ASSERT (StringPtr);
Status = ReadString (MenuOption, StringPtr);
if (!EFI_ERROR (Status)) {
EfiCopyMem (gPreviousValue, NvRamMap, MenuOption->ThisTag->StorageWidth);
EfiCopyMem (&VariableDefinition->NvRamMap[Tag->StorageStart], StringPtr, Tag->StorageWidth);
UpdateStatusBar (NV_UPDATE_REQUIRED, Tag->Flags, TRUE);
}
gBS->FreePool (StringPtr);
return Status;
} else {
for (Index = 0; Index < gOptionBlockWidth; Index++) {
if (VariableDefinition->NvRamMap[Tag->StorageStart + (Index * 2)] != 0x0000) {
EfiCopyMem (OptionString[0] + Index, &VariableDefinition->NvRamMap[Tag->StorageStart + (Index * 2)], 2);
} else {
if (Index == 0) {
*(OptionString[0] + Index) = '_';
*(OptionString[0] + 1 + Index) = 0;
}
break;
}
}
return Status;
}
case EFI_IFR_PASSWORD_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];
}
if (Selected) {
StringPtr = EfiLibAllocateZeroPool (Tag->Maximum);
ASSERT (StringPtr);
//
// If interactive, read the password and do the appropriate callbacks in that routine.
// Since interactive passwords assume to handle the password data in a separate variable
// storage, we don't need to do more than what is below for password callbacks
//
if (Tag->Flags & EFI_IFR_FLAG_INTERACTIVE) {
MenuOption->Tags[0].CallbackHandle = FileFormTags->FormTags.Tags[0].CallbackHandle;
Status = ReadPassword (MenuOption, TRUE, Tag, PageData, FALSE, FileFormTags, StringPtr);
EfiZeroMem (StringPtr, Tag->Maximum);
if (EFI_ERROR (Status)) {
if (Status == EFI_NOT_READY) {
gBS->FreePool (StringPtr);
return EFI_SUCCESS;
}
}
Status = ReadPassword (MenuOption, TRUE, Tag, PageData, TRUE, FileFormTags, StringPtr);
gBS->FreePool (StringPtr);
return EFI_SUCCESS;
}
for (Index = 0; Index < Tag->Maximum; Index++) {
if (VariableDefinition->NvRamMap[Tag->StorageStart + Index] != 0x00) {
//
// There is something there! Prompt for password
//
Status = ReadPassword (MenuOption, TRUE, Tag, PageData, FALSE, FileFormTags, StringPtr);
if (EFI_ERROR (Status)) {
gBS->FreePool (StringPtr);
return EFI_SUCCESS;
}
if (Tag->Encoding == 1) {
EncodePassword (StringPtr, (UINT8) Tag->Maximum);
Status = EfiCompareMem (StringPtr, &VariableDefinition->NvRamMap[Tag->StorageStart], Tag->Maximum);
} else {
Status = EfiCompareMem (StringPtr, &VariableDefinition->NvRamMap[Tag->StorageStart], Tag->Maximum);
}
if (Status != 0) {
gBS->FreePool (StringPtr);
return EFI_SUCCESS;
} else {
break;
}
}
}
//
// Clean the string
//
EfiZeroMem (StringPtr, Tag->Maximum);
//
// No password set! Go ahead and prompt the user for a password.
//
Status = ReadPassword (MenuOption, FALSE, Tag, PageData, FALSE, FileFormTags, StringPtr);
if (EFI_ERROR (Status)) {
//
// User couldn't figure out how to type two identical passwords
//
gBS->FreePool (StringPtr);
return EFI_SUCCESS;
}
//
// Very simple example of how one MIGHT do password encoding
//
if (Tag->Encoding == 1) {
EncodePassword (StringPtr, (UINT8) Tag->Maximum);
}
TmpNvRamMap = EfiLibAllocatePool (VariableDefinition->VariableSize);
ASSERT (TmpNvRamMap != NULL);
Count = VariableDefinition->VariableSize;
if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {
Status = FormCallback->NvRead (
FormCallback,
VariableDefinition->VariableName,
&VariableDefinition->Guid,
NULL,
&Count,
(VOID *) TmpNvRamMap
);
} else {
Status = gRT->GetVariable (
VariableDefinition->VariableName,
&VariableDefinition->Guid,
NULL,
&Count,
(VOID *) TmpNvRamMap
);
}
EfiCopyMem (&VariableDefinition->NvRamMap[Tag->StorageStart], StringPtr, Tag->StorageWidth);
EfiCopyMem (&TmpNvRamMap[Tag->StorageStart], StringPtr, Tag->StorageWidth);
if ((FormCallback != NULL) && (FormCallback->NvWrite != NULL)) {
Status = FormCallback->NvWrite (
FormCallback,
VariableDefinition->VariableName,
&VariableDefinition->Guid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
VariableDefinition->VariableSize,
(VOID *) TmpNvRamMap,
&gResetRequired
);
} else {
Status = gRT->SetVariable (
VariableDefinition->VariableName,
&VariableDefinition->Guid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
VariableDefinition->VariableSize,
(VOID *) TmpNvRamMap
);
}
gBS->FreePool (TmpNvRamMap);
gBS->FreePool (StringPtr);
break;
}
default:
break;
}
return EFI_SUCCESS;
}
VOID
ProcessHelpString (
IN CHAR16 *StringPtr,
OUT CHAR16 **FormattedString,
IN UINTN RowCount
)
{
UINTN CurrIndex;
UINTN PrevIndex;
UINTN SearchIndex;
UINTN PrevSearchIndex;
UINTN StringCount;
UINTN PageCount;
StringCount = 0;
PrevIndex = 0;
CurrIndex = gHelpBlockWidth - 1;
if (*FormattedString != NULL) {
gBS->FreePool (*FormattedString);
*FormattedString = NULL;
}
for (; CurrIndex > PrevIndex; CurrIndex--) {
//
// In the case where the string ended and a new one is immediately after it
// we need to check for the null-terminator and reset the CurrIndex
//
SearchIndex = CurrIndex;
PrevSearchIndex = PrevIndex;
for (; SearchIndex > PrevSearchIndex; PrevSearchIndex++) {
if ((StringPtr[PrevSearchIndex] == CHAR_NULL) || (StringPtr[PrevSearchIndex] == CHAR_LINEFEED)) {
CurrIndex = PrevSearchIndex;
break;
}
if (StringPtr[PrevSearchIndex] == CHAR_CARRIAGE_RETURN) {
if (StringPtr[PrevSearchIndex + 1] == CHAR_LINEFEED) {
//
// Found a "\n",advance to the next new line.
//
CurrIndex = PrevSearchIndex + 1;
break;
} else {
//
// Found a "\r",return to the start of the current line.
//
PrevIndex = PrevSearchIndex + 1;
CurrIndex = PrevSearchIndex + gHelpBlockWidth;
continue;
}
}
}
//
// End of the string, thus stop counting.
//
if (StringPtr[CurrIndex] == CHAR_NULL) {
StringCount++;
break;
}
//
// The premise is that for every HELP_BLOCK_WIDTH we rewind
// until we find the first space. That is the delimiter for
// the string, and we will then advance our CurrIndex another
// HELP_BLOCK_WIDTH and continue the process breaking the larger
// string into chunks that fit within the HELP_BLOCK_WIDTH requirements.
//
if (StringPtr[CurrIndex] == CHAR_SPACE) {
//
// How many strings have been found?
//
StringCount++;
PrevIndex = CurrIndex + 1;
CurrIndex = CurrIndex + gHelpBlockWidth;
}
//
// Found a Linefeed, advance to the next line.
//
if (StringPtr[CurrIndex] == CHAR_LINEFEED) {
StringCount++;
PrevIndex = CurrIndex + 1;
CurrIndex = CurrIndex + gHelpBlockWidth;
}
}
//
// endfor
//
// Round the value up one (doesn't hurt)
//
StringCount++;
//
// Determine the number of pages this help string occupies
//
PageCount = StringCount / RowCount;
if (StringCount % RowCount > 0) {
PageCount++;
}
//
// Convert the PageCount into lines so we can allocate the correct buffer size
//
StringCount = PageCount * RowCount;
//
// We now know how many strings we will have, so we can allocate the
// space required for the array or strings.
//
*FormattedString = EfiLibAllocateZeroPool ((StringCount) * (gHelpBlockWidth + 1) * 2);
ASSERT (*FormattedString);
StringCount = 0;
PrevIndex = 0;
CurrIndex = gHelpBlockWidth - 1;
for (; CurrIndex > PrevIndex; CurrIndex--) {
//
// In the case where the string ended and a new one is immediately after it
// we need to check for the null-terminator and reset the CurrIndex
//
SearchIndex = CurrIndex;
PrevSearchIndex = PrevIndex;
for (; SearchIndex > PrevSearchIndex; PrevSearchIndex++) {
if ((StringPtr[PrevSearchIndex] == CHAR_NULL) || (StringPtr[PrevSearchIndex] == CHAR_LINEFEED)) {
CurrIndex = PrevSearchIndex;
break;
}
if (StringPtr[PrevSearchIndex] == CHAR_CARRIAGE_RETURN) {
if (StringPtr[PrevSearchIndex + 1] == CHAR_LINEFEED) {
//
// Found a "\n",advance to the next new line.
//
CurrIndex = PrevSearchIndex + 1;
break;
} else {
//
// Found a "\r",return to the start of the current line.
//
PrevIndex = PrevSearchIndex + 1;
CurrIndex = PrevSearchIndex + gHelpBlockWidth;
continue;
}
}
}
//
// End of the string, thus stop counting.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?