/** The function is called by PerformQuickSort to sort file name in alphabet. @param[in] Left The pointer to first buffer. @param[in] Right The pointer to second buffer. @retval 0 Buffer1 equal to Buffer2. @return <0 Buffer1 is less than Buffer2. @return >0 Buffer1 is greater than Buffer2. **/ INTN EFIAPI CompareFileNameInAlphabet ( IN VOID *Left, IN VOID *Right ) { EFI_FILE_INFO *FileInfo1; EFI_FILE_INFO *FileInfo2; CHAR16 FileName1[MAX_FILE_NAME_SIZE]; CHAR16 FileExtension1[MAX_FILE_NAME_SIZE]; CHAR16 FileName2[MAX_FILE_NAME_SIZE]; CHAR16 FileExtension2[MAX_FILE_NAME_SIZE]; CHAR16 TempSubStr1[MAX_FILE_NAME_SIZE]; CHAR16 TempSubStr2[MAX_FILE_NAME_SIZE]; UINTN SubStrLen1; UINTN SubStrLen2; INTN SubStrCmpResult; FileInfo1 = (EFI_FILE_INFO *) (*(UINTN *)Left); FileInfo2 = (EFI_FILE_INFO *) (*(UINTN *)Right); SplitFileNameExtension (FileInfo1->FileName, FileName1, FileExtension1); SplitFileNameExtension (FileInfo2->FileName, FileName2, FileExtension2); UpperCaseString (FileName1); UpperCaseString (FileName2); GetSubStringBeforePeriod (FileName1, TempSubStr1, &SubStrLen1); GetSubStringBeforePeriod (FileName2, TempSubStr2, &SubStrLen2); if (SubStrLen1 > SubStrLen2) { // // Substr in NewFileName is longer. Pad tail with SPACE // PadStrInTail (TempSubStr2, SubStrLen1 - SubStrLen2, L' '); } else if (SubStrLen1 < SubStrLen2){ // // Substr in ListedFileName is longer. Pad tail with SPACE // PadStrInTail (TempSubStr1, SubStrLen2 - SubStrLen1, L' '); } SubStrCmpResult = StrnCmp (TempSubStr1, TempSubStr2, MAX_FILE_NAME_LEN); if (SubStrCmpResult != 0) { return SubStrCmpResult; } UpperCaseString (FileExtension1); UpperCaseString (FileExtension2); return StrnCmp (FileExtension1, FileExtension2, MAX_FILE_NAME_LEN); }
/** Check whether the input variable is an key option variable. @param Name Input variable name. @param Guid Input variable guid. @param OptionNumber The option number of this key option variable. @retval TRUE Input variable is a key option variable. @retval FALSE Input variable is not a key option variable. **/ BOOLEAN BmIsKeyOptionVariable ( CHAR16 *Name, EFI_GUID *Guid, UINT16 *OptionNumber ) { UINTN Index; UINTN Uint; if (!CompareGuid (Guid, &gEfiGlobalVariableGuid) || (StrSize (Name) != sizeof (L"Key####")) || (StrnCmp (Name, L"Key", 3) != 0) ) { return FALSE; } *OptionNumber = 0; for (Index = 3; Index < 7; Index++) { Uint = BmCharToUint (Name[Index]); if (Uint == -1) { return FALSE; } else { *OptionNumber = (UINT16) Uint + *OptionNumber * 0x10; } } return TRUE; }
/** Function to check the TYPE of Data. @param[in] Data The Data to be check. @retval DATA_TYPE The TYPE of Data. **/ DATA_TYPE TestDataType ( IN CONST CHAR16 *Data ) { if (Data[0] == L'0' && (Data[1] == L'x' || Data[1] == L'X')) { if (IsStringOfHexNibbles (Data+2) && StrLen (Data + 2) <= 16) { return DataTypeHexNumber; } else { return DataTypeUnKnow; } } else if (Data[0] == L'H') { if (IsStringOfHexNibbles (Data + 1) && StrLen (Data + 1) % 2 == 0) { return DataTypeHexArray; } else { return DataTypeUnKnow; } } else if (Data[0] == L'S') { return DataTypeAscii; } else if (Data[0] == L'L') { return DataTypeUnicode; } else if (Data[0] == L'P' || StrnCmp (Data, L"--", 2) == 0) { return DataTypeDevicePath; } if (IsStringOfHexNibbles (Data) && StrLen (Data) % 2 == 0) { return DataTypeHexArray; } return DataTypeAscii; }
EFIAPI GetManFileName( IN CONST CHAR16 *ManFileName ) { CHAR16 *Buffer; if (ManFileName == NULL) { return (NULL); } // // Fix the file name // if (StrnCmp(ManFileName+StrLen(ManFileName)-4, L".man", 4)==0) { Buffer = AllocateCopyPool(StrSize(ManFileName), ManFileName); } else { Buffer = AllocateZeroPool(StrSize(ManFileName) + 4*sizeof(CHAR16)); if (Buffer != NULL) { StrnCpyS( Buffer, (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16), ManFileName, StrLen(ManFileName) ); StrnCatS( Buffer, (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16), L".man", 4 ); } } return (Buffer); }
/** Variable property get with wildcard name. @param[in] VariableName Pointer to variable name. @param[in] VendorGuid Pointer to variable vendor GUID. @param[in] WildcardMatch Try wildcard match or not. @return Pointer to variable property. **/ VAR_CHECK_VARIABLE_PROPERTY * VariablePropertyGetWithWildcardName ( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN BOOLEAN WildcardMatch ) { UINTN Index; UINTN NameLength; NameLength = StrLen (VariableName) - 4; for (Index = 0; Index < sizeof (mVarCheckVariableWithWildcardName)/sizeof (mVarCheckVariableWithWildcardName[0]); Index++) { if (CompareGuid (mVarCheckVariableWithWildcardName[Index].Guid, VendorGuid)){ if (WildcardMatch) { if ((StrLen (VariableName) == StrLen (mVarCheckVariableWithWildcardName[Index].Name)) && (StrnCmp (VariableName, mVarCheckVariableWithWildcardName[Index].Name, NameLength) == 0) && VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength]) && VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) && VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) && VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) { return &mVarCheckVariableWithWildcardName[Index].VariableProperty; } } if (StrCmp (mVarCheckVariableWithWildcardName[Index].Name, VariableName) == 0) { return &mVarCheckVariableWithWildcardName[Index].VariableProperty; } } } return NULL; }
BOOLEAN IsKeyOptionVariable ( CHAR16 *Name, EFI_GUID *Guid, UINT16 *OptionNumber ) { UINTN Index; if (!CompareGuid (Guid, &gEfiGlobalVariableGuid) || (StrSize (Name) != sizeof (L"Key####")) || (StrnCmp (Name, L"Key", 3) != 0) ) { return FALSE; } *OptionNumber = 0; for (Index = 3; Index < 7; Index++) { if ((Name[Index] >= L'0') && (Name[Index] <= L'9')) { *OptionNumber = *OptionNumber * 10 + Name[Index] - L'0'; } else if ((Name[Index] >= L'A') && (Name[Index] <= L'F')) { *OptionNumber = *OptionNumber * 10 + Name[Index] - L'A'; } else { return FALSE; } } return TRUE; }
const CHAR16* StrStr(const CHAR16* haystack, const CHAR16* needle) { int len = StrLen(needle); while (haystack && haystack[0]) { if (StrnCmp(haystack, needle, len) == 0) { return haystack; } ++haystack; } return 0; }
EFIAPI GetExecuatableFileName ( IN CONST CHAR16 *NameString ) { CHAR16 *Buffer; CHAR16 *SuffixStr; if (NameString == NULL) { return (NULL); } // // Fix the file name // if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".efi"), L".efi", StrLen(L".efi"))==0) { Buffer = AllocateCopyPool(StrSize(NameString), NameString); } else if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".man"), L".man", StrLen(L".man"))==0) { Buffer = AllocateCopyPool(StrSize(NameString), NameString); if (Buffer != NULL) { SuffixStr = Buffer+StrLen(Buffer)-StrLen(L".man"); StrnCpyS (SuffixStr, StrSize(L".man")/sizeof(CHAR16), L".efi", StrLen(L".efi")); } } else { Buffer = AllocateZeroPool(StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16)); if (Buffer != NULL) { StrnCpyS( Buffer, (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16), NameString, StrLen(NameString) ); StrnCatS( Buffer, (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16), L".efi", StrLen(L".efi") ); } } return (Buffer); }
EFI_STATUS flash(VOID *data, UINTN size, CHAR16 *label) { UINTN i; #ifndef USER /* special case for writing inside esp partition */ CHAR16 esp[] = L"/ESP/"; if (!StrnCmp(esp, label, StrLen(esp))) return flash_into_esp(data, size, &label[ARRAY_SIZE(esp) - 1]); #endif /* special cases */ for (i = 0; i < ARRAY_SIZE(LABEL_EXCEPTIONS); i++) if (!StrCmp(LABEL_EXCEPTIONS[i].name, label)) return LABEL_EXCEPTIONS[i].flash_func(data, size); return flash_partition(data, size, label); }
/** This code checks if variable is hardware error record variable or not. According to UEFI spec, hardware error record variable should use the EFI_HARDWARE_ERROR_VARIABLE VendorGuid and have the L"HwErrRec####" name convention, #### is a printed hex value and no 0x or h is included in the hex value. @param[in] VariableName Pointer to variable name. @param[in] VendorGuid Variable Vendor Guid. @retval TRUE Variable is hardware error record variable. @retval FALSE Variable is not hardware error record variable. **/ BOOLEAN EFIAPI IsHwErrRecVariable ( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid ) { if (!CompareGuid (VendorGuid, &gEfiHardwareErrorVariableGuid) || (StrLen (VariableName) != StrLen (L"HwErrRec####")) || (StrnCmp(VariableName, L"HwErrRec", StrLen (L"HwErrRec")) != 0) || !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x8]) || !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x9]) || !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xA]) || !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xB])) { return FALSE; } return TRUE; }
/** Check whether the VariableName is a valid load option variable name and return the load option type and option number. @param VariableName The name of the load option variable. @param OptionType Return the load option type. @param OptionNumber Return the load option number. @retval TRUE The variable name is valid; The load option type and load option number is returned. @retval FALSE The variable name is NOT valid. **/ BOOLEAN BmIsValidLoadOptionVariableName ( IN CHAR16 *VariableName, OUT EFI_BOOT_MANAGER_LOAD_OPTION_TYPE *OptionType, OUT UINT16 *OptionNumber ) { UINTN VariableNameLen; UINTN Index; UINTN Uint; VariableNameLen = StrLen (VariableName); if (VariableNameLen <= 4) { return FALSE; } for (Index = 0; Index < sizeof (mBmLoadOptionName) / sizeof (mBmLoadOptionName[0]); Index++) { if ((VariableNameLen - 4 == StrLen (mBmLoadOptionName[Index])) && (StrnCmp (VariableName, mBmLoadOptionName[Index], VariableNameLen - 4) == 0) ) { break; } } if (Index == sizeof (mBmLoadOptionName) / sizeof (mBmLoadOptionName[0])) { return FALSE; } *OptionType = (EFI_BOOT_MANAGER_LOAD_OPTION_TYPE) Index; *OptionNumber = 0; for (Index = VariableNameLen - 4; Index < VariableNameLen; Index++) { Uint = BmCharToUint (VariableName[Index]); if (Uint == -1) { break; } else { *OptionNumber = (UINT16) Uint + *OptionNumber * 0x10; } } return (BOOLEAN) (Index == VariableNameLen); }
/** Get UEFI defined var check function. @param[in] VariableName Pointer to variable name. @param[in] VendorGuid Pointer to variable vendor GUID. @param[out] VariableProperty Pointer to variable property. @return Internal var check function, NULL if no specific check function. **/ INTERNAL_VAR_CHECK_FUNCTION GetUefiDefinedVarCheckFunction ( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, OUT VAR_CHECK_VARIABLE_PROPERTY **VariableProperty ) { UINTN Index; UINTN NameLength; if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) { // // Try list 1, exactly match. // for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) { if (StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) { *VariableProperty = &(mGlobalVariableList[Index].VariableProperty); return mGlobalVariableList[Index].CheckFunction; } } // // Try list 2. // NameLength = StrLen (VariableName) - 4; for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) { if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) && (StrnCmp (VariableName, mGlobalVariableList2[Index].Name, NameLength) == 0) && VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength]) && VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) && VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) && VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) { *VariableProperty = &(mGlobalVariableList2[Index].VariableProperty); return mGlobalVariableList2[Index].CheckFunction; } } } return NULL; }
/** Extract the decimal index from the network interface name. @param[in] Name Name of the network interface. @retval INVALID_NIC_INDEX Failed to extract the network interface index. @return others The network interface index. **/ UINTN NicNameToIndex ( IN CHAR16 *Name ) { CHAR16 *Str; Str = Name + 3; if ((StrnCmp (Name, L"eth", 3) != 0) || (*Str == 0)) { return INVALID_NIC_INDEX; } while (*Str != 0) { if ((*Str < L'0') || (*Str > L'9')) { return INVALID_NIC_INDEX; } Str++; } return (UINT16) StrDecimalToUintn (Name + 3); }
/** Set information about a file. @param[in] Instance A pointer to the description of the volume the file belongs to. @param[in] File A pointer to the description of the file. @param[in] Info A pointer to the file information to write. @retval EFI_SUCCESS The information was set. @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY Attribute. @retval EFI_ACCESS_DENIED The file was opened in read-only mode and an attempt is being made to modify a field other than Attribute. @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a file that is already present. @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only attribute. @retval EFI_OUT_OF_RESOURCES An allocation needed to process the request failed. **/ STATIC EFI_STATUS SetFileInfo ( IN BOOTMON_FS_INSTANCE *Instance, IN BOOTMON_FS_FILE *File, IN EFI_FILE_INFO *Info ) { EFI_STATUS Status; BOOLEAN FileSizeIsDifferent; BOOLEAN FileNameIsDifferent; BOOLEAN TimeIsDifferent; // // A directory can not be changed to a file and a file can // not be changed to a directory. // if ((Info->Attribute & EFI_FILE_DIRECTORY) != (File->Info->Attribute & EFI_FILE_DIRECTORY) ) { return EFI_ACCESS_DENIED; } FileSizeIsDifferent = (Info->FileSize != File->Info->FileSize); FileNameIsDifferent = (StrnCmp ( Info->FileName, File->Info->FileName, MAX_NAME_LENGTH - 1 ) != 0); // // Check if the CreateTime, LastAccess or ModificationTime // have been changed. The file system does not support file // timestamps thus the three times in "File->Info" are // always equal to zero. The following comparison actually // checks if all three times are still equal to 0 or not. // TimeIsDifferent = CompareMem ( &Info->CreateTime, &File->Info->CreateTime, 3 * sizeof (EFI_TIME) ) != 0; // // For a file opened in read-only mode, only the Attribute field can be // modified. The root directory open mode is forced to read-only at opening // thus the following test protects the root directory to be somehow modified. // if (File->OpenMode == EFI_FILE_MODE_READ) { if (FileSizeIsDifferent || FileNameIsDifferent || TimeIsDifferent) { return EFI_ACCESS_DENIED; } } if (TimeIsDifferent) { return EFI_WRITE_PROTECTED; } if (FileSizeIsDifferent) { Status = SetFileSize (Instance, File, Info->FileSize); if (EFI_ERROR (Status)) { return Status; } } // // Note down in RAM the Attribute field but we can not // ask to store it in flash for the time being. // File->Info->Attribute = Info->Attribute; if (FileNameIsDifferent) { Status = SetFileName (Instance, File, Info->FileName); if (EFI_ERROR (Status)) { return Status; } } return EFI_SUCCESS; }
/** parses through the MAN file specified by SHELL_FILE_HANDLE and returns the detailed help for any sub section specified in the comma seperated list of sections provided. If the end of the file or a .TH section is found then return. Upon a sucessful return the caller is responsible to free the memory in *HelpText @param[in] Handle FileHandle to read from @param[in] Sections name of command's sub sections to find @param[out] HelpText pointer to pointer to string where text goes. @param[out] HelpSize pointer to size of allocated HelpText (may be updated) @param[in] Ascii TRUE if the file is ASCII, FALSE otherwise. @retval EFI_OUT_OF_RESOURCES a memory allocation failed. @retval EFI_SUCCESS the section was found and its description sotred in an alloceted buffer. **/ EFI_STATUS EFIAPI ManFileFindSections( IN SHELL_FILE_HANDLE Handle, IN CONST CHAR16 *Sections, OUT CHAR16 **HelpText, OUT UINTN *HelpSize, IN BOOLEAN Ascii ) { EFI_STATUS Status; CHAR16 *ReadLine; UINTN Size; BOOLEAN CurrentlyReading; CHAR16 *SectionName; UINTN SectionLen; BOOLEAN Found; if ( Handle == NULL || HelpText == NULL || HelpSize == NULL ){ return (EFI_INVALID_PARAMETER); } Status = EFI_SUCCESS; CurrentlyReading = FALSE; Size = 1024; Found = FALSE; ReadLine = AllocateZeroPool(Size); if (ReadLine == NULL) { return (EFI_OUT_OF_RESOURCES); } for (;!ShellFileHandleEof(Handle);Size = 1024) { Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, &Ascii); if (ReadLine[0] == L'#') { // // Skip comment lines // continue; } // // ignore too small of buffer... // if (Status == EFI_BUFFER_TOO_SMALL) { Status = EFI_SUCCESS; } if (EFI_ERROR(Status)) { break; } else if (StrnCmp(ReadLine, L".TH", 3) == 0) { // // we hit the end of this commands section so stop. // break; } else if (StrnCmp(ReadLine, L".SH", 3) == 0) { if (Sections == NULL) { CurrentlyReading = TRUE; continue; } // // we found a section // if (CurrentlyReading) { CurrentlyReading = FALSE; } // // is this a section we want to read in? // for ( SectionName = ReadLine + 3 ; *SectionName == L' ' ; SectionName++); SectionLen = StrLen(SectionName); SectionName = StrStr(Sections, SectionName); if (SectionName == NULL) { continue; } if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') { CurrentlyReading = TRUE; } } else if (CurrentlyReading) { Found = TRUE; // // copy and save the current line. // ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL)); StrnCatGrow (HelpText, HelpSize, ReadLine, 0); StrnCatGrow (HelpText, HelpSize, L"\r\n", 0); } } FreePool(ReadLine); if (!Found && !EFI_ERROR(Status)) { return (EFI_NOT_FOUND); } return (Status); }
/** parses through Buffer (which is MAN file formatted) and returns the detailed help for any sub section specified in the comma seperated list of sections provided. If the end of the file or a .TH section is found then return. Upon a sucessful return the caller is responsible to free the memory in *HelpText @param[in] Buffer Buffer to read from @param[in] Sections name of command's sub sections to find @param[in] HelpText pointer to pointer to string where text goes. @param[in] HelpSize pointer to size of allocated HelpText (may be updated) @retval EFI_OUT_OF_RESOURCES a memory allocation failed. @retval EFI_SUCCESS the section was found and its description sotred in an alloceted buffer. **/ EFI_STATUS EFIAPI ManBufferFindSections( IN CONST CHAR16 *Buffer, IN CONST CHAR16 *Sections, IN CHAR16 **HelpText, IN UINTN *HelpSize ) { EFI_STATUS Status; CONST CHAR16 *CurrentLocation; BOOLEAN CurrentlyReading; CHAR16 *SectionName; UINTN SectionLen; BOOLEAN Found; CHAR16 *TempString; CHAR16 *TempString2; if ( Buffer == NULL || HelpText == NULL || HelpSize == NULL ){ return (EFI_INVALID_PARAMETER); } Status = EFI_SUCCESS; CurrentlyReading = FALSE; Found = FALSE; for (CurrentLocation = Buffer,TempString = NULL ; CurrentLocation != NULL && *CurrentLocation != CHAR_NULL ; CurrentLocation=StrStr(CurrentLocation, L"\r\n"),TempString = NULL ){ while(CurrentLocation[0] == L'\r' || CurrentLocation[0] == L'\n') { CurrentLocation++; } if (CurrentLocation[0] == L'#') { // // Skip comment lines // continue; } if (StrnCmp(CurrentLocation, L".TH", 3) == 0) { // // we hit the end of this commands section so stop. // break; } if (StrnCmp(CurrentLocation, L".SH ", 4) == 0) { if (Sections == NULL) { CurrentlyReading = TRUE; continue; } else if (CurrentlyReading) { CurrentlyReading = FALSE; } CurrentLocation += 4; // // is this a section we want to read in? // if (StrLen(CurrentLocation)!=0) { TempString2 = StrStr(CurrentLocation, L" "); TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\r")); TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n")); ASSERT(TempString == NULL); TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation); if (TempString == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } SectionName = TempString; SectionLen = StrLen(SectionName); SectionName = StrStr(Sections, SectionName); if (SectionName == NULL) { continue; } if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') { CurrentlyReading = TRUE; } } } else if (CurrentlyReading) { Found = TRUE; if (StrLen(CurrentLocation)!=0) { TempString2 = StrStr(CurrentLocation, L"\r"); TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n")); ASSERT(TempString == NULL); TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation); if (TempString == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } // // copy and save the current line. // ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL)); StrnCatGrow (HelpText, HelpSize, TempString, 0); if (HelpText == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } StrnCatGrow (HelpText, HelpSize, L"\r\n", 0); if (HelpText == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } } } SHELL_FREE_NON_NULL(TempString); } if (!Found && !EFI_ERROR(Status)) { return (EFI_NOT_FOUND); } return (Status); }
/** Function for 'setvar' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunSetVar ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CONST CHAR16 *VariableName; CONST CHAR16 *Data; EFI_GUID Guid; CONST CHAR16 *StringGuid; UINT32 Attributes; UINT32 Attributes2; VOID *Buffer; UINTN Size; UINTN LoopVar; EFI_DEVICE_PATH_PROTOCOL *DevPath; ShellStatus = SHELL_SUCCESS; Status = EFI_SUCCESS; Buffer = NULL; Size = 0; Attributes = 0; DevPath = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { if (ShellCommandLineGetCount(Package) < 2) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetCount(Package) > 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle); ShellStatus = SHELL_INVALID_PARAMETER; } else { VariableName = ShellCommandLineGetRawValue(Package, 1); Data = ShellCommandLineGetRawValue(Package, 2); if (!ShellCommandLineGetFlag(Package, L"-guid")){ CopyGuid(&Guid, &gEfiGlobalVariableGuid); } else { StringGuid = ShellCommandLineGetValue(Package, L"-guid"); Status = ConvertStringToGuid(StringGuid, &Guid); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, StringGuid); ShellStatus = SHELL_INVALID_PARAMETER; } } if (Data == NULL) { // // Display what's there // Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer); if (Status == EFI_BUFFER_TOO_SMALL) { Buffer = AllocateZeroPool(Size); Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer); } if (!EFI_ERROR(Status)&& Buffer != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size); for (LoopVar = 0 ; LoopVar < Size ; LoopVar++) { ShellPrintEx(-1, -1, L"%02x ", ((UINT8*)Buffer)[LoopVar]); } ShellPrintEx(-1, -1, L"\r\n"); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, &Guid, VariableName, Status); ShellStatus = SHELL_ACCESS_DENIED; } } else if (StrCmp(Data, L"=") == 0) { // // Delete what's there! // Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, 0, NULL); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status); ShellStatus = SHELL_ACCESS_DENIED; } else { ASSERT(ShellStatus == SHELL_SUCCESS); } } else { if (Data[0] == L'=') { Data++; } // // Change what's there // if (ShellCommandLineGetFlag(Package, L"-bs")) { Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS; } if (ShellCommandLineGetFlag(Package, L"-rt")) { Attributes |= EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS; } if (ShellCommandLineGetFlag(Package, L"-nv")) { Attributes |= EFI_VARIABLE_NON_VOLATILE; } if (ShellIsHexOrDecimalNumber(Data, TRUE, FALSE)) { if (StrLen(Data) % 2 != 0) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, Data); ShellStatus = SHELL_INVALID_PARAMETER; } else { // // arbitrary buffer // Buffer = AllocateZeroPool((StrLen(Data) / 2)); if (Buffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { for (LoopVar = 0 ; LoopVar < (StrLen(Data) / 2) ; LoopVar++) { ((UINT8*)Buffer)[LoopVar] = (UINT8)(HexCharToUintn(Data[LoopVar*2]) * 16); ((UINT8*)Buffer)[LoopVar] = (UINT8)(((UINT8*)Buffer)[LoopVar] + HexCharToUintn(Data[LoopVar*2+1])); } Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrLen(Data) / 2, Buffer); } if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status); ShellStatus = SHELL_ACCESS_DENIED; } else { ASSERT(ShellStatus == SHELL_SUCCESS); } } } else if (StrnCmp(Data, L"\"", 1) == 0) { Size = 0; Attributes2 = 0; Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes2, &Size, Buffer); if (Status == EFI_BUFFER_TOO_SMALL) { Buffer = AllocateZeroPool(Size); Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes2, &Size, Buffer); if (Buffer != NULL) { FreePool(Buffer); } Attributes = Attributes2; } // // ascii text // Data++; Buffer = AllocateZeroPool(StrSize(Data) / 2); if (Buffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { AsciiSPrint(Buffer, StrSize(Data) / 2, "%s", Data); ((CHAR8*)Buffer)[AsciiStrLen(Buffer)-1] = CHAR_NULL; Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, AsciiStrSize(Buffer)-sizeof(CHAR8), Buffer); } if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status); ShellStatus = SHELL_ACCESS_DENIED; } else { ASSERT(ShellStatus == SHELL_SUCCESS); } } else if (StrnCmp(Data, L"L\"", 2) == 0) { // // ucs2 text // Data++; Data++; Buffer = AllocateZeroPool(StrSize(Data)); if (Buffer == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle); ShellStatus = SHELL_OUT_OF_RESOURCES; } else { UnicodeSPrint(Buffer, StrSize(Data), L"%s", Data); ((CHAR16*)Buffer)[StrLen(Buffer)-1] = CHAR_NULL; Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrSize(Buffer)-sizeof(CHAR16), Buffer); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status); ShellStatus = SHELL_ACCESS_DENIED; } else { ASSERT(ShellStatus == SHELL_SUCCESS); } } } else if (StrnCmp(Data, L"--", 2) == 0) { // // device path in text format // Data++; Data++; DevPath = ConvertTextToDevicePath(Data); if (DevPath == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, Status); ShellStatus = SHELL_INVALID_PARAMETER; } else { Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, GetDevicePathSize(DevPath), DevPath); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status); ShellStatus = SHELL_ACCESS_DENIED; } else { ASSERT(ShellStatus == SHELL_SUCCESS); } } } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Data); ShellStatus = SHELL_INVALID_PARAMETER; } } } ShellCommandLineFreeVarList (Package); } if (Buffer != NULL) { FreePool(Buffer); } if (DevPath != NULL) { FreePool(DevPath); } return (ShellStatus); }
/** Function to parse the Data by the type of Data, and save in the Buffer. @param[in] Data A pointer to a buffer to be parsed. @param[out] Buffer A pointer to a buffer to hold the return data. @param[in,out] BufferSize On input, indicates the size of Buffer in bytes. On output,indicates the size of data return in Buffer. Or the size in bytes of the buffer needed to obtain. @retval EFI_INVALID_PARAMETER The Buffer or BufferSize is NULL. @retval EFI_BUFFER_TOO_SMALL The Buffer is too small to hold the data. @retval EFI_OUT_OF_RESOURCES A memory allcation failed. @retval EFI_SUCCESS The Data parsed successful and save in the Buffer. **/ EFI_STATUS ParseParameterData ( IN CONST CHAR16 *Data, OUT VOID *Buffer, IN OUT UINTN *BufferSize ) { UINT64 HexNumber; UINTN HexNumberLen; UINTN Size; CHAR8 *AsciiBuffer; DATA_TYPE DataType; EFI_DEVICE_PATH_PROTOCOL *DevPath; EFI_STATUS Status; HexNumber = 0; HexNumberLen = 0; Size = 0; AsciiBuffer = NULL; DevPath = NULL; Status = EFI_SUCCESS; if (Data == NULL || BufferSize == NULL) { return EFI_INVALID_PARAMETER; } DataType = TestDataType (Data); if (DataType == DataTypeHexNumber) { // // hex number // StrHexToUint64S (Data + 2, NULL, &HexNumber); HexNumberLen = StrLen (Data + 2); if (HexNumberLen >= 1 && HexNumberLen <= 2) { Size = 1; } else if (HexNumberLen >= 3 && HexNumberLen <= 4) { Size = 2; } else if (HexNumberLen >= 5 && HexNumberLen <= 8) { Size = 4; } else if (HexNumberLen >= 9 && HexNumberLen <= 16) { Size = 8; } if (Buffer != NULL && *BufferSize >= Size) { CopyMem(Buffer, (VOID *)&HexNumber, Size); } else { Status = EFI_BUFFER_TOO_SMALL; } *BufferSize = Size; } else if (DataType == DataTypeHexArray) { // // hex array // if (*Data == L'H') { Data = Data + 1; } Size = StrLen (Data) / 2; if (Buffer != NULL && *BufferSize >= Size) { StrHexToBytes(Data, StrLen (Data), (UINT8 *)Buffer, Size); } else { Status = EFI_BUFFER_TOO_SMALL; } *BufferSize = Size; } else if (DataType == DataTypeAscii) { // // ascii text // if (*Data == L'S') { Data = Data + 1; } AsciiBuffer = AllocateZeroPool (StrSize (Data) / 2); if (AsciiBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { AsciiSPrint (AsciiBuffer, StrSize (Data) / 2, "%s", (CHAR8 *)Data); Size = StrSize (Data) / 2 - 1; if (Buffer != NULL && *BufferSize >= Size) { CopyMem (Buffer, AsciiBuffer, Size); } else { Status = EFI_BUFFER_TOO_SMALL; } *BufferSize = Size; } SHELL_FREE_NON_NULL (AsciiBuffer); } else if (DataType == DataTypeUnicode) { // // unicode text // if (*Data == L'L') { Data = Data + 1; } Size = StrSize (Data) - sizeof (CHAR16); if (Buffer != NULL && *BufferSize >= Size) { CopyMem (Buffer, Data, Size); } else { Status = EFI_BUFFER_TOO_SMALL; } *BufferSize = Size; } else if (DataType == DataTypeDevicePath) { if (*Data == L'P') { Data = Data + 1; } else if (StrnCmp (Data, L"--", 2) == 0) { Data = Data + 2; } DevPath = ConvertTextToDevicePath (Data); if (DevPath == NULL) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar"); Status = EFI_INVALID_PARAMETER; } else { Size = GetDevicePathSize (DevPath); if (Buffer != NULL && *BufferSize >= Size) { CopyMem (Buffer, DevPath, Size); } else { Status = EFI_BUFFER_TOO_SMALL; } *BufferSize = Size; } SHELL_FREE_NON_NULL (DevPath); } else { Status = EFI_INVALID_PARAMETER; } return Status; }
/** Add new boot option for HTTP boot. @param[in] Private Pointer to the driver private data. @param[in] UsingIpv6 Set to TRUE if creating boot option for IPv6. @param[in] Description The description text of the boot option. @param[in] Uri The URI string of the boot file. @retval EFI_SUCCESS The boot option is created successfully. @retval Others Failed to create new boot option. **/ EFI_STATUS HttpBootAddBootOption ( IN HTTP_BOOT_PRIVATE_DATA *Private, IN BOOLEAN UsingIpv6, IN CHAR16 *Description, IN CHAR16 *Uri ) { EFI_DEV_PATH *Node; EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; UINTN Length; CHAR8 AsciiUri[URI_STR_MAX_SIZE]; CHAR16 *CurrentOrder; EFI_STATUS Status; UINTN OrderCount; UINTN TargetLocation; BOOLEAN Found; UINT8 *TempByteBuffer; UINT8 *TempByteStart; UINTN DescSize; UINTN FilePathSize; CHAR16 OptionStr[10]; UINT16 *NewOrder; UINTN Index; NewOrder = NULL; TempByteStart = NULL; NewDevicePath = NULL; NewOrder = NULL; Node = NULL; TmpDevicePath = NULL; CurrentOrder = NULL; if (StrLen (Description) == 0) { return EFI_INVALID_PARAMETER; } // // Convert the scheme to all lower case. // for (Index = 0; Index < StrLen (Uri); Index++) { if (Uri[Index] == L':') { break; } if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') { Uri[Index] -= (CHAR16)(L'A' - L'a'); } } // // Only accept http and https URI. // if ((StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 7) != 0)) { return EFI_INVALID_PARAMETER; } // // Create a new device path by appending the IP node and URI node to // the driver's parent device path // if (!UsingIpv6) { Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH)); if (Node == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH; Node->Ipv4.Header.SubType = MSG_IPv4_DP; SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH)); } else { Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH)); if (Node == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH; Node->Ipv6.Header.SubType = MSG_IPv6_DP; SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH)); } TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node); FreePool (Node); if (TmpDevicePath == NULL) { return EFI_OUT_OF_RESOURCES; } // // Update the URI node with the input boot file URI. // UnicodeStrToAsciiStr (Uri, AsciiUri); Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri); Node = AllocatePool (Length); if (Node == NULL) { Status = EFI_OUT_OF_RESOURCES; FreePool (TmpDevicePath); goto ON_EXIT; } Node->DevPath.Type = MESSAGING_DEVICE_PATH; Node->DevPath.SubType = MSG_URI_DP; SetDevicePathNodeLength (Node, Length); CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, AsciiStrSize (AsciiUri)); NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node); FreePool (Node); FreePool (TmpDevicePath); if (NewDevicePath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } // // Get current "BootOrder" variable and find a free target. // Length = 0; Status = GetVariable2 ( L"BootOrder", &gEfiGlobalVariableGuid, (VOID **)&CurrentOrder, &Length ); if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) { goto ON_EXIT; } OrderCount = Length / sizeof (UINT16); Found = FALSE; for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) { Found = TRUE; for (Index = 0; Index < OrderCount; Index++) { if (CurrentOrder[Index] == TargetLocation) { Found = FALSE; break; } } if (Found) { break; } } if (TargetLocation == 0xFFFF) { DEBUG ((EFI_D_ERROR, "Could not find unused target index.\n")); Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } else { DEBUG ((EFI_D_INFO, "TargetIndex = %04x.\n", TargetLocation)); } // // Construct and set the "Boot####" variable // DescSize = StrSize(Description); FilePathSize = GetDevicePathSize (NewDevicePath); TempByteBuffer = AllocateZeroPool(sizeof(EFI_LOAD_OPTION) + DescSize + FilePathSize); if (TempByteBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } TempByteStart = TempByteBuffer; *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes TempByteBuffer += sizeof (UINT32); *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength TempByteBuffer += sizeof (UINT16); CopyMem (TempByteBuffer, Description, DescSize); TempByteBuffer += DescSize; CopyMem (TempByteBuffer, NewDevicePath, FilePathSize); UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", L"Boot", TargetLocation); Status = gRT->SetVariable ( OptionStr, &gEfiGlobalVariableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize, TempByteStart ); if (EFI_ERROR (Status)) { goto ON_EXIT; } // // Insert into the order list and set "BootOrder" variable // NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (UINT16)); if (NewOrder == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } CopyMem(NewOrder, CurrentOrder, OrderCount * sizeof(UINT16)); NewOrder[OrderCount] = (UINT16) TargetLocation; Status = gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, ((OrderCount + 1) * sizeof (UINT16)), NewOrder ); ON_EXIT: if (CurrentOrder != NULL) { FreePool (CurrentOrder); } if (NewOrder != NULL) { FreePool (NewOrder); } if (TempByteStart != NULL) { FreePool (TempByteStart); } if (NewDevicePath != NULL) { FreePool (NewDevicePath); } return Status; }
/** Convert the UEFI DevicePath to full text representation with DevPathToText, then match the UEFI device path fragment in Translated against it. @param[in] Translated UEFI device path fragment, translated from OpenFirmware format, to search for. @param[in] TranslatedLength The length of Translated in CHAR16's. @param[in] DevicePath Boot option device path whose textual rendering to search in. @param[in] DevPathToText Binary-to-text conversion protocol for DevicePath. @retval TRUE If Translated was found at the beginning of DevicePath after converting the latter to text. @retval FALSE If DevicePath was NULL, or it could not be converted, or there was no match. **/ STATIC BOOLEAN Match ( IN CONST CHAR16 *Translated, IN UINTN TranslatedLength, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { CHAR16 *Converted; BOOLEAN Result; Converted = ConvertDevicePathToText ( DevicePath, FALSE, // DisplayOnly FALSE // AllowShortcuts ); if (Converted == NULL) { return FALSE; } // // Attempt to expand any relative UEFI device path starting with HD() to an // absolute device path first. The logic imitates BdsLibBootViaBootOption(). // We don't have to free the absolute device path, // BdsExpandPartitionPartialDevicePathToFull() has internal caching. // Result = FALSE; if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH && DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP) { EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath; CHAR16 *AbsConverted; AbsDevicePath = BdsExpandPartitionPartialDevicePathToFull ( (HARDDRIVE_DEVICE_PATH *) DevicePath); if (AbsDevicePath == NULL) { goto Exit; } AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE); if (AbsConverted == NULL) { goto Exit; } DEBUG ((DEBUG_VERBOSE, "%a: expanded relative device path \"%s\" for prefix matching\n", __FUNCTION__, Converted)); FreePool (Converted); Converted = AbsConverted; } // // Is Translated a prefix of Converted? // Result = (BOOLEAN)(StrnCmp (Converted, Translated, TranslatedLength) == 0); DEBUG (( DEBUG_VERBOSE, "%a: against \"%s\": %a\n", __FUNCTION__, Converted, Result ? "match" : "no match" )); Exit: FreePool (Converted); return Result; }
int compare(struct sorted_data * sd1, struct sorted_data * sd2, ULONG col, BOOL case_on) { ULONG len = MIN(sd1->len, sd2->len); #warning It seems like StrnCmp of locale does not work. #if 1 LONG retval = 0; if (TRUE == case_on) { int i = col; while (i < len) { BOOL a,b; a = IsUpper(locale,(ULONG)*(sd1->data+col+i)); b = IsUpper(locale,(ULONG)*(sd2->data+col+i)); if (a == b) { if (0 != (retval = StrnCmp(locale, sd1->data+col, sd2->data+col, 1, SC_COLLATE2))); break; } else { retval = b - a; break; } i++; } } else { retval=StrnCmp(locale, sd1->data+col, sd2->data+col, len, SC_COLLATE2); if (0 == retval) { if (sd1->len < sd2->len) retval = -100; else retval = +100; } } return retval; #else int i = col; char * str1 = sd1->data; char * str2 = sd2->data; while (i < len) { if (str1[i] != str2[i]) return (int)(str1[i] - str2[i]); i++; } return (int)sd1->len - (int)sd2->len; #endif }
EFI_STATUS FindApplicationMatchingUiSection ( IN CHAR16 *UiString, OUT EFI_HANDLE *FvHandle, OUT EFI_GUID *NameGuid ) { EFI_STATUS Status; EFI_STATUS NextStatus; UINTN NoHandles; EFI_HANDLE *Buffer; UINTN Index; EFI_FV_FILETYPE FileType; EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; VOID *Key; EFI_FV_FILE_ATTRIBUTES Attributes; UINTN Size; UINTN UiStringLen; CHAR16 *UiSection; UINT32 Authentication; UiStringLen = 0; if (UiString != NULL) { DEBUG ((DEBUG_ERROR, "UiString %s\n", UiString)); UiStringLen = StrLen (UiString); } Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Buffer); if (!EFI_ERROR (Status)) { for (Index = 0; Index < NoHandles; Index++) { Status = gBS->HandleProtocol (Buffer[Index], &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv); if (!EFI_ERROR (Status)) { Key = AllocatePool (Fv->KeySize); ASSERT (Key != NULL); ZeroMem (Key, Fv->KeySize); FileType = EFI_FV_FILETYPE_APPLICATION; do { NextStatus = Fv->GetNextFile (Fv, Key, &FileType, NameGuid, &Attributes, &Size); if (!EFI_ERROR (NextStatus)) { if (UiString == NULL) { // // If UiString is NULL match first application we find. // *FvHandle = Buffer[Index]; FreePool (Key); return Status; } UiSection = NULL; Status = Fv->ReadSection ( Fv, NameGuid, EFI_SECTION_USER_INTERFACE, 0, (VOID **)&UiSection, &Size, &Authentication ); if (!EFI_ERROR (Status)) { if (StrnCmp (UiString, UiSection, UiStringLen) == 0) { // // We found a UiString match. // *FvHandle = Buffer[Index]; FreePool (Key); FreePool (UiSection); return Status; } FreePool (UiSection); } } } while (!EFI_ERROR (NextStatus)); FreePool (Key); } } FreePool (Buffer); } return EFI_NOT_FOUND; }
EFI_STATUS EFIAPI ShellAppMain ( IN UINTN Argc, IN CHAR16 **Argv ) { EFI_STATUS Status; UINT16 *BootVariable; UINTN BootVariableSize; UINT16 LDAttr; CHAR16 *Name; UINTN NewNameSize; UINTN NameSize; UINTN i; UINT32 Attr; EFI_GUID VarGuid; ParseOpt(Argc, Argv); //------------Usage----------------------- if (opts.usage){ Usage(); return EFI_SUCCESS; } //----------Set BootOrder----------------- if (opts.set_bootorder){ BootVariable = mGetVariable(L"BootOrder", &gEfiGlobalVariableGuid, &BootVariableSize, &Attr); BootVariable[0]=opts.bootnum; Status = gRT->SetVariable(L"BootOrder", &gEfiGlobalVariableGuid, Attr, BootVariableSize, BootVariable); if (!EFI_ERROR(Status)) Print(L"Set first boot to Boot%04x\n", opts.bootnum); return Status; } //----------Show Boot UEFI variables-------- //get BootCurrent BootVariable = mGetVariable(L"BootCurrent", &gEfiGlobalVariableGuid, &BootVariableSize, NULL); if (BootVariable != NULL) Print(L"BootCurrent: %04x\n", *BootVariable); //get BootOrder BootVariable = mGetVariable(L"BootOrder", &gEfiGlobalVariableGuid, &BootVariableSize, &Attr); if (BootVariable != NULL){ Print(L"BootOrder: "); for(i=0; i<(BootVariableSize/2); i++){ Print(L" %04x ",BootVariable[i]); } Print(L"\n"); } //Print all BOOT#### Load Options NameSize = sizeof(CHAR16); Name = AllocateZeroPool(NameSize); for (i=0; ;i++ ){ NewNameSize = NameSize; //search all EFI variables Status = gRT->GetNextVariableName (&NewNameSize, Name, &VarGuid); if (Status == EFI_BUFFER_TOO_SMALL) { Name = ReallocatePool (NameSize, NewNameSize, Name); Status = gRT->GetNextVariableName (&NewNameSize, Name, &VarGuid); NameSize = NewNameSize; } // if (Status == EFI_NOT_FOUND) { break; } //skip if not Global variable if (!CompareGuid(&VarGuid, &gEfiGlobalVariableGuid)) continue; //check BOOT#### variable if(!StrnCmp(Name, L"Boot", 4) && IsCharDigit(Name[4]) && IsCharDigit(Name[5]) && IsCharDigit(Name[6]) && IsCharDigit(Name[7])) { Print(L"%s:", Name); //get BOOT#### BootVariable = mGetVariable(Name, &gEfiGlobalVariableGuid, &BootVariableSize, NULL); //print attribute LDAttr = BootVariable[0]; if (opts.show_verbose){ i = 6; //for adjust display if (LDAttr == 0) Print(L"CB*", i--); //category boot if (LDAttr & 1) Print(L"A* ", i--); //active if (LDAttr & 2) Print(L"FR*", i--); //force reconnect if (LDAttr & 8) Print(L"H* ", i--); //hidden if (LDAttr & 0x100) Print(L"CA*", i--); //category app //Print(L"\n"); while (i--){ Print(L" "); } } //print EFI_LOAD_OPTION description Print(L" %s",(CHAR16 *)(BootVariable+3)); Print(L"\n"); } } return Status; }