#include "../include/RemovableMedia.h"
#include "gpt.h"
#include "config.h"
+#include "mystrings.h"
#ifdef __MAKEWITH_GNUEFI
#define EfiReallocatePool ReallocatePool
return -1;
}
-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()
-
-// 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()
-
// Takes an input pathname (*Path) and returns the part of the filename from
// the final dot onwards, converted to lowercase. If the filename includes
// no dots, or if the input is NULL, returns an empty (but allocated) string.
return (PathOnly);
}
-/*++
- *
- * 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()
-
-// 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()
-
// Takes an input loadpath, splits it into disk and filename components, finds a matching
// DeviceVolume, and returns that and the filename (*loader).
VOID FindVolumeAndFilename(IN EFI_DEVICE_PATH *loadpath, OUT REFIT_VOLUME **DeviceVolume, OUT CHAR16 **loader) {
}
} // BOOLEAN SplitVolumeAndFilename()
-// 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()
-
// Take an input path name, which may include a volume specification and/or
// a path, and return separate volume, path, and file names. For instance,
// "BIGVOL:\EFI\ubuntu\grubx64.efi" will return a VolName of "BIGVOL", a Path
*Filename = NULL;
}
MyFreePool(Temp);
-} // VOID SplitPathName
-
-// 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()
+} // VOID SplitPathName()
// Returns TRUE if specified Volume, Directory, and Filename correspond to an
// element in the comma-delimited List, FALSE otherwise. Note that Directory and
return (Ejected > 0);
} // VOID EjectMedia()
-// 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()
-
// Returns TRUE if the two GUIDs are equal, FALSE otherwise
BOOLEAN GuidsAreEqual(EFI_GUID *Guid1, EFI_GUID *Guid2) {
return (CompareMem(Guid1, Guid2, 16) == 0);
} // BOOLEAN GuidsAreEqual()
+
+// Erase linked-list of UINT32 values....
+VOID EraseUint32List(UINT32_LIST **TheList) {
+ UINT32_LIST *NextItem;
+
+ while (*TheList) {
+ NextItem = (*TheList)->Next;
+ FreePool(*TheList);
+ *TheList = NextItem;
+ } // while
+} // EraseUin32List()