EFI_STATUS UpdateMeasure ( EFI_HANDLE Handle, IN UINT16 *Token, IN UINT16 *Host, EFI_HANDLE HandleNew, IN UINT16 *TokenNew, IN UINT16 *HostNew ) /*++ Routine Description: Update measure. Arguments: Handle - A pointer of an efi handle. Token - A pointer to the token. Host - A pointer to the host. HandleNew - A pointer of an new efi handle. TokenNew - A pointer to the new token. HostNew - A pointer to the new host. Returns: Status code. EFI_NOT_FOUND - The speicified gauge data node not found. EFI_SUCCESS - Update successfully. --*/ { EFI_STATUS Status; EFI_GAUGE_DATA *GaugeData; EFI_PERFORMANCE_PROTOCOL *Perf; Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf); if (EFI_ERROR (Status)) { return Status; } GaugeData = Perf->GetGauge (Perf, Handle, Token, Host, NULL); if (!GaugeData) { return EFI_NOT_FOUND; } GaugeData->Handle = HandleNew; if (HostNew != NULL) { EfiStrCpy (GaugeData->Host, HostNew); } else { EfiStrCpy (GaugeData->Host, L""); } if (TokenNew != NULL) { EfiStrCpy (GaugeData->Token, TokenNew); } else { EfiStrCpy (GaugeData->Token, L""); } return EFI_SUCCESS; }
EFI_PERF_DATA_LIST * CreateDataNode ( IN EFI_HANDLE Handle, IN UINT16 *Token, IN UINT16 *Host ) /*++ Routine Description: Create a EFI_PERF_DATA_LIST data node. Arguments: Handle - Handle of gauge data Token - Token of gauge data Host - Host of gauge data Returns: Pointer to a data node created. --*/ { EFI_PERF_DATA_LIST *Node; // // Al\ a new image structure // Node = EfiLibAllocateZeroPool (sizeof (EFI_PERF_DATA_LIST)); if (Node != NULL) { Node->Signature = EFI_PERFORMANCE_DATA_SIGNATURE; Node->GaugeData.Handle = Handle; if (Token != NULL) { EfiStrCpy ((Node->GaugeData).Token, Token); } if (Host != NULL) { EfiStrCpy ((Node->GaugeData).Host, Host); } if (Handle != NULL) { GetNameFromHandle (Handle, Node->GaugeData.PdbFileName); } } return Node; }
CHAR16 * StslStrDuplicate ( IN CHAR16 *String ) { EFI_STATUS Status; CHAR16 *Buffer; if (String == NULL) { return NULL; } Status = gBS->AllocatePool ( EfiBootServicesData, (EfiStrLen (String) + 1) * sizeof(CHAR16), &Buffer ); if (EFI_ERROR (Status)) { return NULL; } EfiStrCpy (Buffer, String); return Buffer; }
VOID AddName ( IN SERIAL_DEV *SerialDevice, IN EFI_INTERFACE_DEFINITION_FOR_ISA_IO *IsaIo ) /*++ Routine Description: Add the component name for the serial io device Arguments: SerialDevice - A pointer to the SERIAL_DEV instance. IsaIo - A pointer to the EFI_ISA_IO_PROTOCOL or EFI_LIGHT_ISA_IO_PROTOCOL instance. Returns: None --*/ { CHAR16 SerialPortName[sizeof (SERIAL_PORT_NAME)]; EfiStrCpy (SerialPortName, L"ISA Serial Port # "); SerialPortName[sizeof (SERIAL_PORT_NAME) - 2] = (CHAR16) (L'0' + (UINT8) IsaIo->ResourceList->Device.UID); EfiLibAddUnicodeString ( LANGUAGE_CODE_ENGLISH, gIsaSerialComponentName.SupportedLanguages, &SerialDevice->ControllerNameTable, (CHAR16 *) SerialPortName ); }
EFI_STATUS EFIAPI TrlSetConfig ( IN EFI_TRL_PRIVATE_INTERFACE *This, EFI_DEVICE_PATH_PROTOCOL *DevicePath, CHAR16 *FileName ) /*++ Routine Description: One private interface function of the TestRecoveryLibrary to set config. Arguments: This - the private interface instance structure. DevicePath - device path of the reset record file. FileName - filename of the reset record file. Returns: EFI_SUCCESS - set config successfully. EFI_OUT_OF_RESOURCES - not enough memory. EFI_INVALID_PARAMETER - invalid parameters. --*/ { EFI_STATUS Status; TEST_RECOVERY_PRIVATE_DATA *Private; Private = TEST_RECOVERY_PRIVATE_DATA_FROM_PI (This); TrlFreePointer (Private); if ((DevicePath == NULL) || (FileName == NULL)) { return EFI_INVALID_PARAMETER; } // // DevicePath & FileName // Private->DevicePath = EfiDuplicateDevicePath (DevicePath); if (Private->DevicePath == NULL) { TrlFreePointer (Private); return EFI_OUT_OF_RESOURCES; } Status = gBS->AllocatePool ( EfiBootServicesData, (EfiStrLen (FileName) + 1) * 2, &(Private->FileName) ); if (EFI_ERROR (Status)) { TrlFreePointer (Private); return Status; } EfiStrCpy (Private->FileName, FileName); return EFI_SUCCESS; }
VOID EfiStrCat ( IN CHAR16 *Destination, IN CHAR16 *Source ) /*++ Routine Description: Concatinate Source on the end of Destination Arguments: Destination - String to added to the end of. Source - String to concatinate. Returns: NONE --*/ { EfiStrCpy (Destination + EfiStrLen (Destination), Source); }
EFI_STATUS AddString ( IN VOID *StringBuffer, IN CHAR16 *Language, IN CHAR16 *String, IN OUT STRING_REF *StringToken ) /*++ Routine Description: Add a string to the incoming buffer and return the token and offset data Arguments: StringBuffer - The incoming buffer Language - Currrent language String - The string to be added StringToken - The index where the string placed Returns: EFI_OUT_OF_RESOURCES - No enough buffer to allocate EFI_SUCCESS - String successfully added to the incoming buffer --*/ { EFI_HII_STRING_PACK *StringPack; EFI_HII_STRING_PACK *StringPackBuffer; VOID *NewBuffer; RELOFST *PackSource; RELOFST *PackDestination; UINT8 *Source; UINT8 *Destination; UINTN Index; BOOLEAN Finished; StringPack = (EFI_HII_STRING_PACK *) StringBuffer; Finished = FALSE; // // Pre-allocate a buffer sufficient for us to work on. // We will use it as a destination scratch pad to build data on // and when complete shift the data back to the original buffer // NewBuffer = EfiLibAllocateZeroPool (DEFAULT_STRING_BUFFER_SIZE); if (NewBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } StringPackBuffer = (EFI_HII_STRING_PACK *) NewBuffer; // // StringPack is terminated with a length 0 entry // for (; StringPack->Header.Length != 0;) { // // If this stringpack's language is same as CurrentLanguage, use it // if (EfiCompareMem ((VOID *) ((CHAR8 *) (StringPack) + StringPack->LanguageNameString), Language, 3) == 0) { // // We have some data in this string pack, copy the string package up to the string data // EfiCopyMem (&StringPackBuffer->Header, &StringPack->Header, sizeof (StringPack)); // // These are references in the structure to tokens, need to increase them by the space occupied by an additional StringPointer // StringPackBuffer->LanguageNameString = (UINT16) (StringPackBuffer->LanguageNameString + (UINT16) sizeof (RELOFST)); StringPackBuffer->PrintableLanguageName = (UINT16) (StringPackBuffer->PrintableLanguageName + (UINT16) sizeof (RELOFST)); PackSource = (RELOFST *) (StringPack + 1); PackDestination = (RELOFST *) (StringPackBuffer + 1); for (Index = 0; PackSource[Index] != 0x0000; Index++) { // // Copy the stringpointers from old to new buffer // remember that we are adding a string, so the string offsets will all go up by sizeof (RELOFST) // PackDestination[Index] = (UINT16) (PackDestination[Index] + sizeof (RELOFST)); } // // Add a new stringpointer in the new buffer since we are adding a string. Null terminate it // PackDestination[Index] = (UINT16)(PackDestination[Index-1] + EfiStrSize((CHAR16 *)((CHAR8 *)(StringPack) + PackSource[Index-1]))); PackDestination[Index + 1] = (UINT16) 0; // // Index is the token value for the new string // *StringToken = (UINT16) Index; // // Source now points to the beginning of the old buffer strings // Destination now points to the beginning of the new buffer strings // Source = (UINT8 *) &PackSource[Index + 1]; Destination = (UINT8 *) &PackDestination[Index + 2]; // // This should copy all the strings from the old buffer to the new buffer // for (; Index != 0; Index--) { // // Copy Source string to destination buffer // EfiStrCpy ((CHAR16 *) Destination, (CHAR16 *) Source); // // Adjust the source/destination to the next string location // Destination = Destination + EfiStrSize ((CHAR16 *) Source); Source = Source + EfiStrSize ((CHAR16 *) Source); } // // This copies the new string to the destination buffer // EfiStrCpy ((CHAR16 *) Destination, (CHAR16 *) String); // // Adjust the size of the changed string pack by adding the size of the new string // along with the size of the additional offset entry for the new string // StringPackBuffer->Header.Length = (UINT32) ((UINTN) StringPackBuffer->Header.Length + EfiStrSize (String) + sizeof (RELOFST)); // // Advance the buffers to point to the next spots. // StringPackBuffer = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPackBuffer) + StringPackBuffer->Header.Length); StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length); Finished = TRUE; continue; } // // This isn't the language of the stringpack we were asked to add a string to // so we need to copy it to the new buffer. // EfiCopyMem (&StringPackBuffer->Header, &StringPack->Header, StringPack->Header.Length); // // Advance the buffers to point to the next spots. // StringPackBuffer = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPackBuffer) + StringPack->Header.Length); StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length); } // // If we didn't copy the new data to a stringpack yet // if (!Finished) { PackDestination = (RELOFST *) (StringPackBuffer + 1); // // Pointing to a new string pack location // StringPackBuffer->Header.Length = (UINT32) ( sizeof (EFI_HII_STRING_PACK) - sizeof (EFI_STRING) + sizeof (RELOFST) + sizeof (RELOFST) + EfiStrSize (Language) + EfiStrSize (String) ); StringPackBuffer->Header.Type = EFI_HII_STRING; StringPackBuffer->LanguageNameString = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer); StringPackBuffer->PrintableLanguageName = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer); StringPackBuffer->Attributes = 0; PackDestination[0] = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer); PackDestination[1] = (UINT16) (PackDestination[0] + EfiStrSize (Language)); PackDestination[2] = (UINT16) 0; // // The first string location will be set to destination. The minimum number of strings // associated with a stringpack will always be token 0 stored as the languagename (e.g. ENG, SPA, etc) // and token 1 as the new string being added and and null entry for the stringpointers // Destination = (CHAR8 *) &PackDestination[3]; // // Copy the language name string to the new buffer // EfiStrCpy ((CHAR16 *) Destination, Language); // // Advance the destination to the new empty spot // Destination = Destination + EfiStrSize (Language); // // Copy the string to the new buffer // EfiStrCpy ((CHAR16 *) Destination, String); // // Since we are starting with a new string pack - we know the new string is token 1 // *StringToken = (UINT16) 1; } // // Zero out the original buffer and copy the updated data in the new buffer to the old buffer // EfiZeroMem (StringBuffer, DEFAULT_STRING_BUFFER_SIZE); EfiCopyMem (StringBuffer, NewBuffer, DEFAULT_STRING_BUFFER_SIZE); // // Free the newly created buffer since we don't need it anymore // gBS->FreePool (NewBuffer); return EFI_SUCCESS; }
EFI_STATUS ReadString ( IN UI_MENU_OPTION *MenuOption, IN CHAR16 *Prompt, OUT CHAR16 *StringPtr ) /*++ Routine Description: Get string or password input from user. Arguments: MenuOption - Pointer to the current input menu. Prompt - The prompt string shown on popup window. StringPtr - Destination for use input string. Returns: EFI_SUCCESS - If string input is read successfully EFI_DEVICE_ERROR - If operation fails --*/ { EFI_STATUS Status; EFI_INPUT_KEY Key; CHAR16 NullCharacter; UINTN ScreenSize; CHAR16 Space[2]; CHAR16 KeyPad[2]; CHAR16 *TempString; CHAR16 *BufferedString; UINTN Index; UINTN Count; UINTN Start; UINTN Top; UINTN DimensionsWidth; UINTN DimensionsHeight; BOOLEAN CursorVisible; UINTN Minimum; UINTN Maximum; FORM_BROWSER_STATEMENT *Question; BOOLEAN IsPassword; DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn; DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow; NullCharacter = CHAR_NULL; ScreenSize = GetStringWidth (Prompt) / sizeof (CHAR16); Space[0] = L' '; Space[1] = CHAR_NULL; Question = MenuOption->ThisTag; Minimum = (UINTN) Question->Minimum; Maximum = (UINTN) Question->Maximum; if (Question->Operand == EFI_IFR_PASSWORD_OP) { IsPassword = TRUE; } else { IsPassword = FALSE; } TempString = EfiLibAllocateZeroPool ((Maximum + 1)* sizeof (CHAR16)); ASSERT (TempString); if (ScreenSize < (Maximum + 1)) { ScreenSize = Maximum + 1; } if ((ScreenSize + 2) > DimensionsWidth) { ScreenSize = DimensionsWidth - 2; } BufferedString = EfiLibAllocateZeroPool (ScreenSize * 2); ASSERT (BufferedString); Start = (DimensionsWidth - ScreenSize - 2) / 2 + gScreenDimensions.LeftColumn + 1; Top = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1; // // Display prompt for string // CreatePopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); CursorVisible = gST->ConOut->Mode->CursorVisible; gST->ConOut->EnableCursor (gST->ConOut, TRUE); do { Status = WaitForKeyStroke (&Key); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); switch (Key.UnicodeChar) { case CHAR_NULL: switch (Key.ScanCode) { case SCAN_LEFT: break; case SCAN_RIGHT: break; case SCAN_ESC: gBS->FreePool (TempString); gBS->FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_DEVICE_ERROR; default: break; } break; case CHAR_CARRIAGE_RETURN: if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) { gBS->FreePool (TempString); gBS->FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_SUCCESS; } else { // // Simply create a popup to tell the user that they had typed in too few characters. // To save code space, we can then treat this as an error and return back to the menu. // do { CreateDialog (4, TRUE, 0, NULL, &Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); gBS->FreePool (TempString); gBS->FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_DEVICE_ERROR; } break; case CHAR_BACKSPACE: if (StringPtr[0] != CHAR_NULL) { for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) { TempString[Index] = StringPtr[Index]; } // // Effectively truncate string by 1 character // TempString[Index - 1] = CHAR_NULL; EfiStrCpy (StringPtr, TempString); } default: // // If it is the beginning of the string, don't worry about checking maximum limits // if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) { StrnCpy (StringPtr, &Key.UnicodeChar, 1); StrnCpy (TempString, &Key.UnicodeChar, 1); } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) { KeyPad[0] = Key.UnicodeChar; KeyPad[1] = CHAR_NULL; EfiStrCat (StringPtr, KeyPad); EfiStrCat (TempString, KeyPad); } // // If the width of the input string is now larger than the screen, we nee to // adjust the index to start printing portions of the string // SetUnicodeMem (BufferedString, ScreenSize - 1, L' '); PrintStringAt (Start + 1, Top + 3, BufferedString); if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; } else { Index = 0; } if (IsPassword) { gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3); } for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { BufferedString[Count] = StringPtr[Index]; if (IsPassword) { PrintChar (L'*'); } } if (!IsPassword) { PrintStringAt (Start + 1, Top + 3, BufferedString); } break; } gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3); } while (TRUE); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return Status; }
CHAR16 * BOpt_AppendFileName ( IN CHAR16 *Str1, IN CHAR16 *Str2 ) /*++ Routine Description Append file name to existing file name. Arguments: Str1 - existing file name Str2 - file name to be appended Returns: Allocate a new string to hold the appended result. Caller is responsible to free the returned string. --*/ { UINTN Size1; UINTN Size2; CHAR16 *Str; CHAR16 *Ptr; CHAR16 *LastSlash; Size1 = EfiStrSize (Str1); Size2 = EfiStrSize (Str2); Str = EfiAllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); ASSERT (Str != NULL); EfiStrCat (Str, Str1); if (!((*Str == '\\') && (*(Str + 1) == 0))) { EfiStrCat (Str, L"\\"); } EfiStrCat (Str, Str2); Ptr = Str; LastSlash = Str; while (*Ptr != 0) { if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) != 0) { // // Convert \Name\..\ to \ // DO NOT convert the .. if it is at the end of the string. This will // break the .. behavior in changing directories. // EfiStrCpy (LastSlash, Ptr + 3); Ptr = LastSlash; } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') { // // Convert a \.\ to a \ // EfiStrCpy (Ptr, Ptr + 2); Ptr = LastSlash; } else if (*Ptr == '\\') { LastSlash = Ptr; } Ptr++; } return Str; }
EFI_STATUS EFIAPI StslRecordAssertion ( IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL *This, IN EFI_TEST_ASSERTION Type, IN EFI_GUID EventId, IN CHAR16 *Description, IN CHAR16 *Detail, ... ) /*++ Routine Description: Records the test result. Arguments: This - Standard test library protocol instance. Type - Test result. EventId - GUID for the checkpoint. Description - Simple description for the checkpoint. Detail - Format string for the detail test information. Returns: EFI_SUCCESS - record the assertion successfully. EFI_BAD_BUFFER_SIZE - the Description string is too long. EFI_INVALID_PARAMETER - invalid Type. --*/ { EFI_STATUS Status; VA_LIST Marker; CHAR16 Buffer[EFI_MAX_PRINT_BUFFER]; CHAR16 AssertionType[10]; STANDARD_TEST_PRIVATE_DATA *Private; Private = STANDARD_TEST_PRIVATE_DATA_FROM_STSL (This); // // Check the parameter // if (EfiStrLen (Description) + 14 > EFI_MAX_PRINT_BUFFER) { return EFI_BAD_BUFFER_SIZE; } // // Write log file detail data // switch (Type) { case EFI_TEST_ASSERTION_PASSED: EfiStrCpy (AssertionType, L"PASS"); Private->PassCount ++; break; case EFI_TEST_ASSERTION_WARNING: EfiStrCpy (AssertionType, L"WARNING"); Private->WarningCount ++; break; case EFI_TEST_ASSERTION_FAILED: EfiStrCpy (AssertionType, L"FAILURE"); Private->FailCount ++; break; default: return EFI_INVALID_PARAMETER; break; } SPrint (Buffer, EFI_MAX_PRINT_BUFFER, L"%s -- %s\n", Description, AssertionType); Status = StslWriteLogFile (Private, Buffer); if (EFI_ERROR (Status)) { return Status; } SPrint (Buffer, EFI_MAX_PRINT_BUFFER, L"%g\n", &EventId); Status = StslWriteLogFile (Private, Buffer); if (EFI_ERROR (Status)) { return Status; } VA_START(Marker, Detail); VSPrint (Buffer, EFI_MAX_PRINT_BUFFER, Detail, Marker); VA_END (Marker); if ( EfiStrLen (Buffer) + 5 < EFI_MAX_PRINT_BUFFER ) { EfiStrCat (Buffer, L"\r\n\r\n"); } Status = StslWriteLogFile (Private, Buffer); if (EFI_ERROR (Status)) { return Status; } // // write key file detail line // SPrint (Buffer, EFI_MAX_PRINT_BUFFER, L"%g:%s|%s:", &EventId, AssertionType, Description); Status = StslWriteKeyFile (Private, Buffer); if (EFI_ERROR (Status)) { return Status; } VA_START(Marker, Detail); VSPrint (Buffer, EFI_MAX_PRINT_BUFFER, Detail, Marker); VA_END (Marker); if ( EfiStrLen (Buffer) + 3 < EFI_MAX_PRINT_BUFFER ) { EfiStrCat (Buffer, L"\r\n"); } Status = StslWriteKeyFile (Private, Buffer); if (EFI_ERROR (Status)) { return Status; } return Status; }
EFI_STATUS EFIAPI PlatOverMngrCallback ( IN EFI_FORM_CALLBACK_PROTOCOL *This, IN UINT16 KeyValue, IN EFI_IFR_DATA_ARRAY *Data, OUT EFI_HII_CALLBACK_PACKET **Packet ) /*++ Routine Description: This is the function that is called to provide results data to the driver. This data consists of a unique key which is used to identify what data is either being passed back or being asked for. Arguments: KeyValue - A unique Goto OpCode callback value which record user's selection 0x100 <= KeyValue <0x500 : user select a controller item in the first page; KeyValue == 0x1234 : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page KeyValue == 0x1235 : user select 'Pci device filter' in first page KeyValue == 0x1500 : user select 'order ... priority' item in second page KeyValue == 0x1800 : user select 'commint changes' in third page KeyValue == 0x2000 : user select 'Go to Previous Menu' in third page Data - EFI_IFR_DATA_ARRAY data Packet- No use here. Returns - Always successful --*/ { EFI_CALLBACK_INFO *Private; EFI_STATUS Status; STRING_REF NewStringToken; Private = EFI_CALLBACK_INFO_FROM_THIS (This); if (KeyValue == 0x1234 || KeyValue == 0x1235) { UpdateDeviceSelectPage (Private, KeyValue, Data); // // Update page title string // NewStringToken = (STRING_REF) STR_TITLE; Status = Private->Hii->NewString (Private->Hii, mLang, Private->RegisteredHandle, &NewStringToken, L"First, Select the controller by device path"); ASSERT_EFI_ERROR (Status); } if ((0x100 <= KeyValue) && (KeyValue < 0x500) || (KeyValue == 0x2000)) { if (KeyValue == 0x2000) { KeyValue = (UINT16)mSelectedCtrIndex + 0x100; } UpdateBindingDriverSelectPage (Private, KeyValue, Data); // // Update page title string // NewStringToken = (STRING_REF) STR_TITLE; Status = Private->Hii->NewString (Private->Hii, mLang, Private->RegisteredHandle, &NewStringToken, L"Second, Select drivers for the previous selected controller"); ASSERT_EFI_ERROR (Status); } if (KeyValue == 0x1500) { UpdatePrioritySelectPage (Private, KeyValue, Data); // // Update page title string // NewStringToken = (STRING_REF) STR_TITLE; Status = Private->Hii->NewString (Private->Hii, mLang, Private->RegisteredHandle, &NewStringToken, L"Finally, Set the priority order for the drivers and save them"); ASSERT_EFI_ERROR (Status); } if (KeyValue == 0x1800) { Status = CommintChanges (Private, KeyValue, Data); if (EFI_ERROR (Status)) { *Packet = EfiLibAllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + sizeof ( L"Single Override Info too large, Saving Error!") + 2); EfiStrCpy ((*Packet)->String, L"Single Override Info too large, Saving Error!"); return EFI_DEVICE_ERROR; } } if (KeyValue == 0x1236) { // // Deletes all environment variable(s) that contain the override mappings info // LibFreeMappingDatabase (&mMappingDataBase); Status = LibSaveOverridesMapping (&mMappingDataBase); UpdateDeviceSelectPage (Private, KeyValue, Data); } return EFI_SUCCESS; }
EFI_STATUS IfrCatenate ( IN FORM_BROWSER_FORMSET *FormSet, OUT EFI_HII_VALUE *Result ) /*++ Routine Description: Evaluate opcode EFI_IFR_CATENATE. Arguments: FormSet - Formset which contains this opcode. Result - Evaluation result for this opcode. Returns: EFI_SUCCESS - Opcode evaluation success. Other - Opcode evaluation failed. --*/ { EFI_STATUS Status; EFI_HII_VALUE Value; CHAR16 *String[2]; UINTN Index; CHAR16 *StringPtr; // // String[0] - The second string // String[1] - The first string // String[0] = NULL; String[1] = NULL; StringPtr = NULL; Status = EFI_SUCCESS; for (Index = 0; Index < 2; Index++) { Status = PopExpression (&Value); if (EFI_ERROR (Status)) { goto Done; } if (Value.Type != EFI_IFR_TYPE_STRING) { Status = EFI_UNSUPPORTED; goto Done; } String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle); if (String== NULL) { Status = EFI_NOT_FOUND; goto Done; } } StringPtr= EfiLibAllocatePool (EfiStrSize (String[1]) + EfiStrSize (String[0])); ASSERT (StringPtr != NULL); EfiStrCpy (StringPtr, String[1]); EfiStrCat (StringPtr, String[0]); Result->Type = EFI_IFR_TYPE_STRING; Result->Value.string = NewString (StringPtr, FormSet->HiiHandle); Done: EfiLibSafeFreePool (String[0]); EfiLibSafeFreePool (String[1]); EfiLibSafeFreePool (StringPtr); return Status; }
VOID AlignmentItem ( IN CHAR16 *ControllerHandleName, IN CHAR16 *PrefixString, IN OUT CHAR16 **NewString ) /*++ Routine Description: Do controller item string swap and alignment if needed. The alignment is the length of PrefixString. Because controller device path is too long sometime and cannot be presented in one line, and the browser automatic swap will break the necessary alignment, so do some additional process for the problem. Arguments: ControllerHandleName - a pointer to the controller real device path string PrefixString- a pointer to the prefix string NewString - a pointer to the string which will be presented by the browser Returns: None --*/ { CHAR16 *PadString; UINTN PtrIndex; UINTN IndexOffset; UINTN Width; CHAR16 *NewStringSwapped; UINTN SwapLineNum; UINTN SwapLine; // // Register the device name string and create item in set options page // *NewString = EfiLibAllocateZeroPool (EfiStrSize (ControllerHandleName) + EfiStrSize (PrefixString)); EfiStrCat (*NewString, PrefixString); EfiStrCat (*NewString, ControllerHandleName); // // Add pad chars into the string for string swap in set options page to solve following two issue: // Issue1: Our form browser will do the string swap according to the spaces in the string, so // if a string is too long and without space in it, the string position will be ugly. // The driver need add some spaces to control the swap in the long and no space string. // Issue2: If browser find a space to do swap, it will not show any other space directly followed it in swap position. // So if you want to use the space to do the alignment in swapped new line, you need add another char(e.g '.') in it. // e.g. if the item max lenth is 5, then the following string need add some space and '.' to get right presentation // '12345678901234567890' --------> ' 12345 . 67890 . 12345 . 67890' , and presentation is below // | 12345 // |. 67890 // |. 12345 // |. 67890 // if ((EfiStrLen (*NewString)/SWAP_LENGTH > 0) && (EfiStrLen (PrefixString) > 0)) { // // Prepare the pad string according to the PrefixString length // the pad string is string of ' ', except of the NO2 charater which is '.' // PadString = EfiLibAllocateZeroPool (EfiStrSize (PrefixString) + 2); for (PtrIndex = 0; PtrIndex < (EfiStrLen (PrefixString) + 1); PtrIndex++) { PadString[PtrIndex] = ' '; } PadString[1] = '.'; Width = SWAP_LENGTH - EfiStrLen (PrefixString); SwapLineNum = EfiStrLen (ControllerHandleName)/Width; NewStringSwapped = EfiLibAllocateZeroPool (EfiStrSize (ControllerHandleName) + EfiStrSize (PrefixString) + SwapLineNum * EfiStrSize (PadString)); ASSERT (NewStringSwapped != NULL); IndexOffset = 0; EfiStrCpy (NewStringSwapped, PrefixString); IndexOffset += EfiStrLen (PrefixString); for (SwapLine = 0; SwapLine < SwapLineNum; SwapLine++) { EfiStrnCpy (&NewStringSwapped[IndexOffset], &ControllerHandleName[SwapLine * Width], Width ); IndexOffset += Width; EfiStrnCpy (&NewStringSwapped[IndexOffset], PadString, EfiStrLen (PadString) ); IndexOffset += EfiStrLen (PadString); } EfiStrCat (NewStringSwapped, &ControllerHandleName[SwapLine * Width]); gBS->FreePool (PadString); gBS->FreePool (*NewString); *NewString = NewStringSwapped; } return; }