From 4220e9754e288a5aedee79dc8440dc20afab2eea Mon Sep 17 00:00:00 2001 From: srs5694 Date: Sun, 29 Nov 2015 13:27:00 -0500 Subject: [PATCH] Added forgotten new or split files to git repo. --- docs/refind/about.svg | 972 ++++++++++++++++++++++++++++++++++++++++++ refind/mystrings.c | 458 ++++++++++++++++++++ refind/mystrings.h | 56 +++ 3 files changed, 1486 insertions(+) create mode 100644 docs/refind/about.svg create mode 100644 refind/mystrings.c create mode 100644 refind/mystrings.h diff --git a/docs/refind/about.svg b/docs/refind/about.svg new file mode 100644 index 0000000..47b2b8b --- /dev/null +++ b/docs/refind/about.svg @@ -0,0 +1,972 @@ + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/refind/mystrings.c b/refind/mystrings.c new file mode 100644 index 0000000..a5c5823 --- /dev/null +++ b/refind/mystrings.c @@ -0,0 +1,458 @@ +/* + * refind/mystrings.c + * String-manipulation functions + * + * Copyright (c) 2012-2015 Roderick W. Smith + * + * Distributed under the terms of the GNU General Public License (GPL) + * version 3 (GPLv3), or (at your option) any later version. + * + */ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "mystrings.h" +#include "lib.h" + +BOOLEAN StriSubCmp(IN CHAR16 *SmallStr, IN CHAR16 *BigStr) { + BOOLEAN Found = 0, Terminate = 0; + UINTN BigIndex = 0, SmallIndex = 0, BigStart = 0; + + if (SmallStr && BigStr) { + while (!Terminate) { + if (BigStr[BigIndex] == '\0') { + Terminate = 1; + } + if (SmallStr[SmallIndex] == '\0') { + Found = 1; + Terminate = 1; + } + if ((SmallStr[SmallIndex] & ~0x20) == (BigStr[BigIndex] & ~0x20)) { + SmallIndex++; + BigIndex++; + } else { + SmallIndex = 0; + BigStart++; + BigIndex = BigStart; + } + } // while + } // if + return Found; +} // BOOLEAN StriSubCmp() + +// Performs a case-insensitive string comparison. This function is necesary +// because some EFIs have buggy StriCmp() functions that actually perform +// case-sensitive comparisons. +// Returns TRUE if strings are identical, FALSE otherwise. +BOOLEAN MyStriCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString) { + if (FirstString && SecondString) { + while ((*FirstString != L'\0') && ((*FirstString & ~0x20) == (*SecondString & ~0x20))) { + FirstString++; + SecondString++; + } + return (*FirstString == *SecondString); + } else { + return FALSE; + } +} // BOOLEAN MyStriCmp() + +/*++ + * + * Routine Description: + * + * Find a substring. + * + * Arguments: + * + * String - Null-terminated string to search. + * StrCharSet - Null-terminated string to search for. + * + * Returns: + * The address of the first occurrence of the matching substring if successful, or NULL otherwise. + * --*/ +CHAR16* MyStrStr (IN CHAR16 *String, IN CHAR16 *StrCharSet) +{ + CHAR16 *Src; + CHAR16 *Sub; + + if ((String == NULL) || (StrCharSet == NULL)) + return NULL; + + Src = String; + Sub = StrCharSet; + + while ((*String != L'\0') && (*StrCharSet != L'\0')) { + if (*String++ != *StrCharSet) { + String = ++Src; + StrCharSet = Sub; + } else { + StrCharSet++; + } + } + if (*StrCharSet == L'\0') { + return Src; + } else { + return NULL; + } +} // CHAR16 *MyStrStr() + +// Convert input string to all-lowercase. +// DO NOT USE the standard StrLwr() function, since it's broken on some EFIs! +VOID ToLower(CHAR16 * MyString) { + UINTN i = 0; + + if (MyString) { + while (MyString[i] != L'\0') { + if ((MyString[i] >= L'A') && (MyString[i] <= L'Z')) + MyString[i] = MyString[i] - L'A' + L'a'; + i++; + } // while + } // if +} // VOID ToLower() + +// Merges two strings, creating a new one and returning a pointer to it. +// If AddChar != 0, the specified character is placed between the two original +// strings (unless the first string is NULL or empty). The original input +// string *First is de-allocated and replaced by the new merged string. +// This is similar to StrCat, but safer and more flexible because +// MergeStrings allocates memory that's the correct size for the +// new merged string, so it can take a NULL *First and it cleans +// up the old memory. It should *NOT* be used with a constant +// *First, though.... +VOID MergeStrings(IN OUT CHAR16 **First, IN CHAR16 *Second, CHAR16 AddChar) { + UINTN Length1 = 0, Length2 = 0; + CHAR16* NewString; + + if (*First != NULL) + Length1 = StrLen(*First); + if (Second != NULL) + Length2 = StrLen(Second); + NewString = AllocatePool(sizeof(CHAR16) * (Length1 + Length2 + 2)); + if (NewString != NULL) { + if ((*First != NULL) && (Length1 == 0)) { + MyFreePool(*First); + *First = NULL; + } + NewString[0] = L'\0'; + if (*First != NULL) { + StrCat(NewString, *First); + if (AddChar) { + NewString[Length1] = AddChar; + NewString[Length1 + 1] = '\0'; + } // if (AddChar) + } // if (*First != NULL) + if (Second != NULL) + StrCat(NewString, Second); + MyFreePool(*First); + *First = NewString; + } else { + Print(L"Error! Unable to allocate memory in MergeStrings()!\n"); + } // if/else +} // VOID MergeStrings() + +// Similar to MergeStrings, but breaks the input string into word chunks and +// merges each word separately. Words are defined as string fragments separated +// by ' ', '_', or '-'. +VOID MergeWords(CHAR16 **MergeTo, CHAR16 *SourceString, CHAR16 AddChar) { + CHAR16 *Temp, *Word, *p; + BOOLEAN LineFinished = FALSE; + + if (SourceString) { + Temp = Word = p = StrDuplicate(SourceString); + if (Temp) { + while (!LineFinished) { + if ((*p == L' ') || (*p == L'_') || (*p == L'-') || (*p == L'\0')) { + if (*p == L'\0') + LineFinished = TRUE; + *p = L'\0'; + if (*Word != L'\0') + MergeStrings(MergeTo, Word, AddChar); + Word = p + 1; + } // if + p++; + } // while + MyFreePool(Temp); + } else { + Print(L"Error! Unable to allocate memory in MergeWords()!\n"); + } // if/else + } // if +} // VOID MergeWords() + +// Restrict TheString to at most Limit characters. +// Does this in two ways: +// - Locates stretches of two or more spaces and compresses +// them down to one space. +// - Truncates TheString +// Returns TRUE if changes were made, FALSE otherwise +BOOLEAN LimitStringLength(CHAR16 *TheString, UINTN Limit) { + CHAR16 *SubString, *TempString; + UINTN i; + BOOLEAN HasChanged = FALSE; + + // SubString will be NULL or point WITHIN TheString + SubString = MyStrStr(TheString, L" "); + while (SubString != NULL) { + i = 0; + while (SubString[i] == L' ') + i++; + if (i >= StrLen(SubString)) { + SubString[0] = '\0'; + HasChanged = TRUE; + } else { + TempString = StrDuplicate(&SubString[i]); + if (TempString != NULL) { + StrCpy(&SubString[1], TempString); + MyFreePool(TempString); + HasChanged = TRUE; + } else { + // memory allocation problem; abort to avoid potentially infinite loop! + break; + } // if/else + } // if/else + SubString = MyStrStr(TheString, L" "); + } // while + + // If the string is still too long, truncate it.... + if (StrLen(TheString) > Limit) { + TheString[Limit] = '\0'; + HasChanged = TRUE; + } // if + + return HasChanged; +} // BOOLEAN LimitStringLength() + +// Returns all the digits in the input string, including intervening +// non-digit characters. For instance, if InString is "foo-3.3.4-7.img", +// this function returns "3.3.4-7". If InString contains no digits, +// the return value is NULL. +CHAR16 *FindNumbers(IN CHAR16 *InString) { + UINTN i, StartOfElement, EndOfElement = 0, CopyLength; + CHAR16 *Found = NULL; + + if (InString == NULL) + return NULL; + + StartOfElement = StrLen(InString); + // Find start & end of target element + for (i = 0; InString[i] != L'\0'; i++) { + if ((InString[i] >= L'0') && (InString[i] <= L'9')) { + if (StartOfElement > i) + StartOfElement = i; + if (EndOfElement < i) + EndOfElement = i; + } // if + } // for + // Extract the target element + if (EndOfElement > 0) { + if (EndOfElement >= StartOfElement) { + CopyLength = EndOfElement - StartOfElement + 1; + Found = StrDuplicate(&InString[StartOfElement]); + if (Found != NULL) + Found[CopyLength] = 0; + } // if (EndOfElement >= StartOfElement) + } // if (EndOfElement > 0) + return (Found); +} // CHAR16 *FindNumbers() + +// Find the #Index element (numbered from 0) in a comma-delimited string +// of elements. +// Returns the found element, or NULL if Index is out of range or InString +// is NULL. Note that the calling function is responsible for freeing the +// memory associated with the returned string pointer. +CHAR16 *FindCommaDelimited(IN CHAR16 *InString, IN UINTN Index) { + UINTN StartPos = 0, CurPos = 0, InLength; + BOOLEAN Found = FALSE; + CHAR16 *FoundString = NULL; + + if (InString != NULL) { + InLength = StrLen(InString); + // After while() loop, StartPos marks start of item #Index + while ((Index > 0) && (CurPos < InLength)) { + if (InString[CurPos] == L',') { + Index--; + StartPos = CurPos + 1; + } // if + CurPos++; + } // while + // After while() loop, CurPos is one past the end of the element + while ((CurPos < InLength) && (!Found)) { + if (InString[CurPos] == L',') + Found = TRUE; + else + CurPos++; + } // while + if (Index == 0) + FoundString = StrDuplicate(&InString[StartPos]); + if (FoundString != NULL) + FoundString[CurPos - StartPos] = 0; + } // if + return (FoundString); +} // CHAR16 *FindCommaDelimited() + +// Returns TRUE if SmallString is an element in the comma-delimited List, +// FALSE otherwise. Performs comparison case-insensitively. +BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List) { + UINTN i = 0; + BOOLEAN Found = FALSE; + CHAR16 *OneElement; + + if (SmallString && List) { + while (!Found && (OneElement = FindCommaDelimited(List, i++))) { + if (MyStriCmp(OneElement, SmallString)) + Found = TRUE; + } // while + } // if + return Found; +} // BOOLEAN IsIn() + +// Returns TRUE if any element of List can be found as a substring of +// BigString, FALSE otherwise. Performs comparisons case-insensitively. +BOOLEAN IsInSubstring(IN CHAR16 *BigString, IN CHAR16 *List) { + UINTN i = 0, ElementLength; + BOOLEAN Found = FALSE; + CHAR16 *OneElement; + + if (BigString && List) { + while (!Found && (OneElement = FindCommaDelimited(List, i++))) { + ElementLength = StrLen(OneElement); + if ((ElementLength <= StrLen(BigString)) && (StriSubCmp(OneElement, BigString))) + Found = TRUE; + } // while + } // if + return Found; +} // BOOLEAN IsSubstringIn() + +// Returns TRUE if *Input contains nothing but valid hexadecimal characters, +// FALSE otherwise. Note that a leading "0x" is NOT acceptable in the input! +BOOLEAN IsValidHex(CHAR16 *Input) { + BOOLEAN IsHex = TRUE; + UINTN i = 0; + + while ((Input[i] != L'\0') && IsHex) { + if (!(((Input[i] >= L'0') && (Input[i] <= L'9')) || + ((Input[i] >= L'A') && (Input[i] <= L'F')) || + ((Input[i] >= L'a') && (Input[i] <= L'f')))) { + IsHex = FALSE; + } + i++; + } // while + return IsHex; +} // BOOLEAN IsValidHex() + +// Converts consecutive characters in the input string into a +// number, interpreting the string as a hexadecimal number, starting +// at the specified position and continuing for the specified number +// of characters or until the end of the string, whichever is first. +// NumChars must be between 1 and 16. Ignores invalid characters. +UINT64 StrToHex(CHAR16 *Input, UINTN Pos, UINTN NumChars) { + UINT64 retval = 0x00; + UINTN NumDone = 0, InputLength; + CHAR16 a; + + if ((Input == NULL) || (NumChars == 0) || (NumChars > 16)) { + return 0; + } + + InputLength = StrLen(Input); + while ((Pos <= InputLength) && (NumDone < NumChars)) { + a = Input[Pos]; + if ((a >= '0') && (a <= '9')) { + retval *= 0x10; + retval += (a - '0'); + NumDone++; + } + if ((a >= 'a') && (a <= 'f')) { + retval *= 0x10; + retval += (a - 'a' + 0x0a); + NumDone++; + } + if ((a >= 'A') && (a <= 'F')) { + retval *= 0x10; + retval += (a - 'A' + 0x0a); + NumDone++; + } + Pos++; + } // while() + return retval; +} // StrToHex() + +// Returns TRUE if UnknownString can be interpreted as a GUID, FALSE otherwise. +// Note that the input string must have no extraneous spaces and must be +// conventionally formatted as a 36-character GUID, complete with dashes in +// appropriate places. +BOOLEAN IsGuid(CHAR16 *UnknownString) { + UINTN Length, i; + BOOLEAN retval = TRUE; + CHAR16 a; + + if (UnknownString == NULL) + return FALSE; + + Length = StrLen(UnknownString); + if (Length != 36) + return FALSE; + + for (i = 0; i < Length; i++) { + a = UnknownString[i]; + if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { + if (a != L'-') + retval = FALSE; + } else if (((a < L'a') || (a > L'f')) && + ((a < L'A') || (a > L'F')) && + ((a < L'0') && (a > L'9'))) { + retval = FALSE; + } // if/else if + } // for + return retval; +} // BOOLEAN IsGuid() + +// Return the GUID as a string, suitable for display to the user. Note that the calling +// function is responsible for freeing the allocated memory. +CHAR16 * GuidAsString(EFI_GUID *GuidData) { + CHAR16 *TheString; + + TheString = AllocateZeroPool(42 * sizeof(CHAR16)); + if (TheString != 0) { + SPrint (TheString, 82, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + (UINTN)GuidData->Data1, (UINTN)GuidData->Data2, (UINTN)GuidData->Data3, + (UINTN)GuidData->Data4[0], (UINTN)GuidData->Data4[1], (UINTN)GuidData->Data4[2], + (UINTN)GuidData->Data4[3], (UINTN)GuidData->Data4[4], (UINTN)GuidData->Data4[5], + (UINTN)GuidData->Data4[6], (UINTN)GuidData->Data4[7]); + } + return TheString; +} // GuidAsString(EFI_GUID *GuidData) + +EFI_GUID StringAsGuid(CHAR16 * InString) { + EFI_GUID Guid = NULL_GUID_VALUE; + + if (!IsGuid(InString)) { + return Guid; + } + + Guid.Data1 = (UINT32) StrToHex(InString, 0, 8); + Guid.Data2 = (UINT16) StrToHex(InString, 9, 4); + Guid.Data3 = (UINT16) StrToHex(InString, 14, 4); + Guid.Data4[0] = (UINT8) StrToHex(InString, 19, 2); + Guid.Data4[1] = (UINT8) StrToHex(InString, 21, 2); + Guid.Data4[2] = (UINT8) StrToHex(InString, 23, 2); + Guid.Data4[3] = (UINT8) StrToHex(InString, 26, 2); + Guid.Data4[4] = (UINT8) StrToHex(InString, 28, 2); + Guid.Data4[5] = (UINT8) StrToHex(InString, 30, 2); + Guid.Data4[6] = (UINT8) StrToHex(InString, 32, 2); + Guid.Data4[7] = (UINT8) StrToHex(InString, 34, 2); + + return Guid; +} // EFI_GUID StringAsGuid() diff --git a/refind/mystrings.h b/refind/mystrings.h new file mode 100644 index 0000000..9b4faec --- /dev/null +++ b/refind/mystrings.h @@ -0,0 +1,56 @@ +/* + * refit/mystrings.h + * String functions header file + * + * Copyright (c) 2012-2015 Roderick W. Smith + * + * Distributed under the terms of the GNU General Public License (GPL) + * version 3 (GPLv3), or (at your option) any later version. + * + */ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __MYSTRINGS_H_ +#define __MYSTRINGS_H_ + +#ifdef __MAKEWITH_GNUEFI +#include +#include +#else +#include "../include/tiano_includes.h" +#endif +#include "../EfiLib/GenericBdsLib.h" + +BOOLEAN StriSubCmp(IN CHAR16 *TargetStr, IN CHAR16 *BigStr); +BOOLEAN MyStriCmp(IN CONST CHAR16 *String1, IN CONST CHAR16 *String2); +CHAR16* MyStrStr (IN CHAR16 *String, IN CHAR16 *StrCharSet); +VOID ToLower(CHAR16 * MyString); +VOID MergeStrings(IN OUT CHAR16 **First, IN CHAR16 *Second, CHAR16 AddChar); +VOID MergeWords(CHAR16 **MergeTo, CHAR16 *InString, CHAR16 AddChar); +BOOLEAN LimitStringLength(CHAR16 *TheString, UINTN Limit); +CHAR16 *FindNumbers(IN CHAR16 *InString); +CHAR16 *FindCommaDelimited(IN CHAR16 *InString, IN UINTN Index); +BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List); +BOOLEAN IsInSubstring(IN CHAR16 *BigString, IN CHAR16 *List); + +BOOLEAN IsValidHex(CHAR16 *Input); +UINT64 StrToHex(CHAR16 *Input, UINTN Position, UINTN NumChars); +BOOLEAN IsGuid(CHAR16 *UnknownString); +CHAR16 * GuidAsString(EFI_GUID *GuidData); +EFI_GUID StringAsGuid(CHAR16 * InString); + + +#endif \ No newline at end of file -- 2.39.2