/** @file
EnglishDxe -- UEFI Unicode Collation English DXE Driver
This DXE driver produces the EFI_UNICODE_COLLATION_PROTOCOL (and optionally
EFI_UNICODE_COLLATION2_PROTOCOL) on a new handle. It provides English-language
string comparison (case-insensitive with wildcard pattern matching), case
conversion (upper/lower via lookup tables), and FAT file name legal character
filtering.
Initialization flow:
1. ModuleEntryPoint() sets up global UEFI library state (ImageHandle,
SystemTable, BootServices, RuntimeServices).
2. ModuleEntryPoint() calls GetHobList() to locate the HOB list, then
calls UnicodeCollationEngEntryPoint().
3. UnicodeCollationEngEntryPoint() initializes three 256-byte lookup tables:
- byte_10A0[0..255] -- upper-case translation
- byte_10A0[256..511] -- character classification flags (bit 0 = legal FAT char)
- byte_1398[0..255] -- sort priority / FAT directory ordering value
- byte_12A0[0..255] -- lower-case translation
It then installs EFI_UNICODE_COLLATION_PROTOCOL via gBS->InstallMultipleProtocolInterfaces().
Protocol functions:
- EngStriUpper -- Convert string to upper case via byte_10A0
- EngStriLower -- Convert string to lower case via byte_12A0
- EngStriColl -- Case-insensitive pattern matching with *, ?, [...]
- EngStrToFat -- Convert ASCII char* to FAT Unicode CHAR16*
- EngMetaiMatch -- Convert Unicode string to FAT 8.3 name (illegal chars -> '_')
Source: MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/UnicodeCollationEng.c
Build environment: VS2015, DEBUG, X64
PDB: EnglishDxe.pdb
Image size: 0x14c0 bytes
Copyright (c) HR650X BIOS Decompilation Project
**/
#include "EnglishDxe.h"
//
// ---------------------------------------------------------------------------
// Global Data
// ---------------------------------------------------------------------------
///
/// Upper-case translation table (0x10A0, 512 bytes).
/// byte_10A0[0..255] = upper-case mapping for each byte value.
/// byte_10A0[256..511] = flags: bit 0 set = legal FAT file name character.
///
UINT8 byte_10A0[512] = {0};
///
/// Lower-case translation table (0x12A0, 256 bytes).
/// byte_12A0[c] = lower-case of character c (for c < 0x100).
///
UINT8 byte_12A0[256] = {0};
///
/// FAT directory ordering priority table (0x1398, 256 bytes).
/// Stores sort priorities for ASCII characters.
///
UINT8 byte_1398[256] = {0};
///
/// Cached debug output device protocol pointer (0x1088).
///
UINT64 qword_1088 = 0;
///
/// Cached HOB list pointer (0x1090).
///
UINT64 qword_1090 = 0;
///
/// UEFI ImageHandle stored by the EDK2 UefiBootServicesTableLib constructor.
///
EFI_HANDLE gImageHandle = NULL;
///
/// UEFI SystemTable stored by the EDK2 UefiBootServicesTableLib constructor.
///
EFI_SYSTEM_TABLE *gST = NULL;
///
/// UEFI BootServices pointer, extracted from SystemTable.
///
EFI_BOOT_SERVICES *gBS = NULL;
///
/// UEFI RuntimeServices pointer, extracted from SystemTable.
///
EFI_RUNTIME_SERVICES *gRT = NULL;
//
// ---------------------------------------------------------------------------
// Function Implementations
// ---------------------------------------------------------------------------
///
/// UEFI driver entry point. Called by firmware after image loading.
///
/// Saves the ImageHandle and SystemTable in global variables, extracts
/// BootServices and RuntimeServices pointers, validates them, then
/// initializes the HOB library and calls the Unicode Collation driver
/// entry point.
///
/// @param ImageHandle Handle for this driver image.
/// @param SystemTable Pointer to the UEFI System Table.
///
/// @return EFI_STATUS code from UnicodeCollationEngEntryPoint().
///
EFI_STATUS
EFIAPI
ModuleEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
gImageHandle = ImageHandle;
if (!ImageHandle) {
DebugPrint((UINTN)"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
(UINTN)51,
"gImageHandle != ((void *) 0)");
}
gST = SystemTable;
if (!SystemTable) {
DebugPrint((UINTN)"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
(UINTN)57,
"gST != ((void *) 0)");
}
gBS = SystemTable->BootServices;
if (!gBS) {
DebugPrint((UINTN)"e:\\hs\\MdePkg\\Library\\UefiBootServicesTableLib\\UefiBootServicesTableLib.c",
(UINTN)63,
"gBS != ((void *) 0)");
}
gRT = SystemTable->RuntimeServices;
if (!gRT) {
DebugPrint((UINTN)"e:\\hs\\MdePkg\\Library\\UefiRuntimeServicesTableLib\\UefiRuntimeServicesTableLib.c",
(UINTN)47,
"gRT != ((void *) 0)");
}
GetHobList();
return UnicodeCollationEngEntryPoint(ImageHandle, SystemTable);
}
///
/// Unicode Collation driver entry point.
///
/// Initializes the three case-conversion and classification tables
/// (byte_10A0, byte_12A0, byte_1398) for all 256 byte values, then
/// installs EFI_UNICODE_COLLATION_PROTOCOL on a new handle.
///
/// Table initialization:
/// - For each c in [0, 256):
/// - byte_10A0[c] = upper-case of c (identity for non-alpha)
/// - byte_1398[c] = FAT sort priority (distance from 'A')
/// - byte_10A0[c + 256] = flags
/// - lowercase letters (c in [97..122]) get special handling:
/// byte_10A0[c] = c - 32 (upper-case equivalent)
/// byte_1398[c] = distance from 'A' + 1, etc.
/// - Characters in "0123456789\\._^$~!#%&-{}()@`'" get their FAT-legal
/// flag bit (bit 0 of byte_10A0[c + 256]) set.
///
/// @param ImageHandle Handle for this driver image (unused).
/// @param SystemTable Pointer to the UEFI System Table (unused).
///
/// @return EFI_SUCCESS on success, error code otherwise.
///
EFI_STATUS
EFIAPI
UnicodeCollationEngEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINTN Index;
UINTN MapIndex;
CHAR8 Char;
CONST CHAR8 *LegalChars = "0123456789\\._^$~!#%&-{}()@`'";
EFI_STATUS Status;
//
// Initialize the case conversion and classification tables
//
for (Index = 0; Index < 256; Index++) {
//
// Upper-case table: initialize to identity
//
byte_10A0[Index] = (UINT8)Index;
//
// Lower-case table: identity (will be filled later for alpha chars)
//
//
// Sort priority: default to distance from 'A' + 1
//
byte_1398[Index] = (UINT8)(Index - 8);
//
// Upper-case mapping for 256..511 (flags): default to identity
//
byte_10A0[Index + 248] = (UINT8)(Index - 8);
//
// Set upper-case mapping for lowercase letters (a-z -> A-Z)
// and set FAT-legal flags
//
if ((Index + 151 <= 0x19) || // Index in [97, 122] (0x61-0x7a)
(Index + 24 <= 0x16) || // Index in [?, ?]
(Index <= 6)) // Index in [0, 6]
{
MapIndex = Index + 216; // = Index + 216 = c - 40 for the range
byte_10A0[Index] = (UINT8)(Index - 32); // upper-case: 'a'->'A'
byte_10A0[MapIndex + 256] |= 1; // Set legal FAT char flag
byte_1398[Index] = (UINT8)(Index - 40); // Sort priority
byte_10A0[MapIndex] = (UINT8)(Index - 8); // Alternate mapping
}
}
//
// Mark the legal FAT file name characters
//
Char = '0';
while (*LegalChars) {
byte_10A0[(UINTN)Char + 256] |= 1;
Char = *LegalChars++;
}
//
// Install the Unicode Collation protocol
// gBS->InstallMultipleProtocolInterfaces(
// &Handle,
// &gEfiUnicodeCollationProtocolGuid, &mUnicodeCollationInterface,
// &gEfiUnicodeCollation2ProtocolGuid, &mUnicodeCollation2Interface,
// NULL
// );
//
Status = gBS->InstallMultipleProtocolInterfaces(
&gImageHandle, // Handle
&gEfiUnicodeCollationProtocolGuid, // GUID
&mUnicodeCollationInterface, // Interface
&gEfiUnicodeCollation2ProtocolGuid, // GUID2
&mUnicodeCollation2Interface, // Interface2
NULL
);
if (EFI_ERROR(Status)) {
DebugAssert((CONST CHAR8 *)EFI_ERROR_MASK,
(UINTN)"\nASSERT_EFI_ERROR (Status = %r)\n",
Status);
DebugPrint((UINTN)"e:\\hs\\MdeModulePkg\\Universal\\Disk\\UnicodeCollation\\EnglishDxe\\UnicodeCollationEng.c",
(UINTN)140,
"!EFI_ERROR (Status)");
}
return Status;
}
///
/// Convert a string to upper case using the byte_10A0[] translation table.
///
/// For each character in the string, if the character is < 0x100, its
/// upper-case equivalent from byte_10A0[] is written back. Characters
/// >= 0x100 are left unchanged.
///
/// @param This Pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
/// @param String Null-terminated Unicode string to convert in place.
///
/// @return The value 255 (0xFF) if the string contained only characters > 0xFF,
/// otherwise the last non-zero character processed.
///
UINTN
EFIAPI
EngStriUpper(
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN OUT CHAR16 *String
)
{
UINTN MapValue = 255;
CHAR16 Char;
while (*String) {
MapValue = 255;
if (*String > 0xFF) {
Char = *String;
} else {
MapValue = *String;
Char = (CHAR16)byte_10A0[MapValue];
}
*String++ = Char;
}
return MapValue;
}
///
/// Convert a string to lower case using the byte_12A0[] translation table.
///
/// For each character in the string, if the character is < 0x100, its
/// lower-case equivalent from byte_12A0[] is written back. Characters
/// >= 0x100 are left unchanged.
///
/// @param This Pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
/// @param String Null-terminated Unicode string to convert in place.
///
/// @return The value 255 (0xFF) if the string contained only characters > 0xFF,
/// otherwise the last non-zero character processed.
///
UINTN
EFIAPI
EngStriLower(
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN OUT CHAR16 *String
)
{
UINTN MapValue = 255;
CHAR16 Char;
while (*String) {
MapValue = 255;
if (*String > 0xFF) {
Char = *String;
} else {
MapValue = *String;
Char = byte_12A0[MapValue];
}
*String++ = Char;
}
return MapValue;
}
///
/// Case-insensitive string comparison with wildcard support.
///
/// Pattern syntax:
/// * Matches zero or more characters
/// ? Matches any single character
/// [abc] Matches any character in the set
/// [a-z] Matches any character in the range (inclusive)
/// [a-z0-9] Matches any character in multiple ranges
/// [!...] (Not implemented in this driver -- '!' as first char is literal)
///
/// All character comparisons are case-insensitive, using the lower-case
/// byte_12A0[] table.
///
/// @param This Pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
/// @param S1 String to compare (expected to not contain wildcards).
/// @param S2 Pattern string (may contain wildcards *, ?, [...]).
///
/// @return TRUE if the string matches the pattern, FALSE otherwise.
///
BOOLEAN
EFIAPI
EngStriColl(
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *S1,
IN CHAR16 *S2
)
{
CHAR16 PatternChar;
CHAR16 CurrentPatternChar;
CHAR16 *PatternPtr;
CHAR16 SavedChar;
CHAR16 RangeStart = 0;
UINTN StringChar;
UINTN i;
PatternChar = *S2;
PatternPtr = S2 + 1;
if (PatternChar == 0) {
return (*S1 == 0);
}
for (;;) {
//
// Handle '*' -- match zero or more characters
//
if (PatternChar == L'*') {
if (*S1 == 0) {
goto NextPatternChar;
}
while (!EngStriColl(This, S1, PatternPtr)) {
S1++;
if (*S1 == 0) {
goto NextPatternChar;
}
}
return TRUE;
}
//
// Handle '?' -- match any single character
//
if (PatternChar == L'?') {
if (*S1 == 0) {
return FALSE;
}
goto AdvanceBoth;
}
//
// Handle '[' -- character range
//
if (PatternChar == L'[') {
if (*S1 == 0) {
return FALSE;
}
RangeStart = 0;
CurrentPatternChar = *PatternPtr;
PatternPtr++;
if (CurrentPatternChar == 0) {
return FALSE;
}
i = *S1; // StringChar as integer
while (CurrentPatternChar != L']') {
//
// Handle range '-'
//
if (CurrentPatternChar == L'-') {
CurrentPatternChar = *PatternPtr;
if (CurrentPatternChar == 0 || CurrentPatternChar == L']') {
return FALSE;
}
StringChar = (*S1 > 0xFF) ? *S1 : byte_12A0[i];
if (StringChar < byte_12A0[RangeStart] ||
StringChar > byte_12A0[CurrentPatternChar]) {
goto CheckChar;
}
goto SkipToCloseBracket;
}
CheckChar:
RangeStart = CurrentPatternChar;
StringChar = (*S1 > 0xFF) ? *S1 : byte_12A0[i];
if (StringChar != byte_12A0[CurrentPatternChar]) {
CurrentPatternChar = *PatternPtr++;
if (CurrentPatternChar) {
continue;
}
}
SkipToCloseBracket:
while (CurrentPatternChar && CurrentPatternChar != L']') {
CurrentPatternChar = *PatternPtr++;
}
goto AdvanceBoth;
}
//
// Empty bracket -- no match
//
return FALSE;
}
//
// Literal character comparison (case-insensitive)
//
StringChar = (*S1 > 0xFF) ? *S1 : byte_12A0[*S1];
if (PatternChar <= 0xFF) {
PatternChar = byte_12A0[PatternChar];
}
if (StringChar != PatternChar) {
return FALSE;
}
AdvanceBoth:
S1++;
NextPatternChar:
PatternChar = *PatternPtr++;
if (PatternChar == 0) {
return (*S1 == 0);
}
}
}
///
/// Converts an ASCII string to a FAT-format Unicode string.
///
/// This simply copies bytes from the 8-bit ASCII input and zero-extends
/// each to a 16-bit CHAR16 output value.
///
/// @param This Pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
/// @param FatSize Size in bytes of the FatOutput buffer.
/// @param String 8-bit ASCII input string.
/// @param FatOutput Output buffer for the FAT Unicode string.
///
/// @return The last character copied, or 0 if the input string was empty.
///
CHAR8
EFIAPI
EngStrToFat(
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN UINTN FatSize,
IN CHAR8 *String,
OUT CHAR16 *FatOutput
)
{
CHAR8 Char;
while (*String && FatSize) {
Char = *String++;
*FatOutput++ = (CHAR16)(UINT8)Char;
FatSize--;
}
*FatOutput = 0;
return Char;
}
///
/// Converts a Unicode string to a FAT file name (8.3 format).
///
/// Processing:
/// - Dots ('.') and spaces (' ') are skipped.
/// - Characters < 0x100 that have bit 0 set in byte_10A0[char + 256]
/// (i.e., legal FAT characters) are lower-cased via byte_12A0[].
/// - All other characters are replaced with '_' (0x5F).
///
/// @param This Pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance.
/// @param String Unicode input string.
/// @param FatSize Size of the FatOutput buffer.
/// @param FatOutput Output buffer for the FAT file name (8-bit chars).
///
/// @return 0 if all characters were valid FAT characters,
/// 1 if any replacement with '_' was necessary.
///
CHAR8
EFIAPI
EngMetaiMatch(
IN EFI_UNICODE_COLLATION_PROTOCOL *This,
IN CHAR16 *String,
IN UINTN FatSize,
OUT CHAR8 *FatOutput
)
{
CHAR16 Char;
CHAR8 IllegalChar = 0;
Char = *String;
for ( ; *String; Char = *String) {
if (FatSize == 0) {
break;
}
//
// Skip dots and spaces
//
if (Char != L'.' && Char != L' ') {
//
// If it's a legal FAT character (bit 0 set in classification table)
//
if (Char < 0x100 && (byte_10A0[Char + 256] & 1) != 0) {
*FatOutput = byte_12A0[Char];
} else {
*FatOutput = '_';
IllegalChar = 1;
}
FatOutput++;
FatSize--;
}
String++;
}
return IllegalChar;
}
///
/// Retrieves the debug output device protocol.
///
/// Allocates an event and then uses gBS->LocateProtocol() to find the
/// debug output device via the HOB list GUID. If the allocation succeeds
/// but the protocol is not found, the cached pointer is set to NULL.
///
/// Results are cached in qword_1088 after the first successful lookup.
///
/// @return Pointer to the debug output device interface, or NULL.
///
VOID *
GetDebugOutputDevice(
VOID
)
{
EFI_STATUS Status;
UINTN PoolSize;
VOID *Interface;
if (qword_1088 != 0) {
return (VOID *)qword_1088;
}
//
// Allocate pool (BootServices + 24 = AllocatePool with type=31=EfiBootServicesData)
//
PoolSize = (UINTN)gBS->AllocatePool(31, 0, &Interface);
gBS->FreePool((VOID *)PoolSize);
if (PoolSize <= 0x10) {
//
// Locate protocol via HOB list GUID
// BootServices[40] = LocateProtocol (offset 320 = 40*8)
//
Status = gBS->LocateProtocol(
&gEfiHobListGuid, // Protocol GUID
NULL, // Registration
&qword_1088 // Interface
);
if (EFI_ERROR(Status)) {
qword_1088 = 0;
}
return (VOID *)qword_1088;
}
return NULL;
}
///
/// Debug assertion handler.
///
/// Reads the CMOS diagnostic output device configuration (CMOS index 0x4B)
/// to determine where to send assertion output. If the device supports
/// the error level indicated by FileName (upper bits), calls the assertion
/// handler on the debug output device.
///
/// The CMOS byte at 0x4B encodes the platform type:
/// 1 = platform with serial debug output
/// 2 = platform with video/console debug output
/// 3+ = other (also checks physical address 0xFDAF0490 as fallback)
///
/// @param FileName Source file name (also encodes error level in high bits).
/// @param LineNumber Line number of the assertion.
/// @param Description Assertion description string.
///
VOID
EFIAPI
DebugAssert(
IN CONST CHAR8 *FileName,
IN UINTN LineNumber,
IN CONST CHAR8 *Description
)
{
VOID *DebugDevice;
UINTN ErrorMask;
UINT8 PlatformType;
CONST CHAR8 *DescriptionPtr = Description;
DebugDevice = GetDebugOutputDevice();
ErrorMask = 0;
if (DebugDevice != NULL) {
//
// Read CMOS diagnostic port to determine platform type
//
__outbyte(0x70, (__inbyte(0x70) & 0x80) | 0x4B);
PlatformType = __inbyte(0x71);
if (PlatformType > 3) {
if (PlatformType == 0) {
//
// Fallback: read physical address 0xFDAF0490
//
PlatformType = (*(volatile UINT8 *)0xFDAF0490 & 2) | 1;
}
}
if ((PlatformType - 1) <= 0xFD) {
ErrorMask = 0x80000006LL; // EFI_ERROR_MASK | bit 1 (platform type >=2)
if (PlatformType == 1) {
ErrorMask = 0x80000004LL; // EFI_ERROR_MASK only (platform type 1)
}
}
//
// Check if the error level matches what this device handles
//
if ((ErrorMask & (UINTN)FileName) != 0) {
//
// Call the debug device's assertion handler (offset +0 = ASSERT)
//
((void (*)(CONST CHAR8 *, UINTN, CONST CHAR8 **))DebugDevice)(
FileName,
LineNumber,
&DescriptionPtr
);
}
}
}
///
/// Debug print function.
///
/// Formats and sends a debug message through the debug output device.
/// The first argument encodes the error level; the second is the format
/// string; subsequent arguments are variadic parameters.
///
/// @param ErrorLevel Debug error level mask.
/// @param Format Format string.
/// @param ... Variable arguments.
///
VOID
EFIAPI
DebugPrint(
IN UINTN ErrorLevel,
IN CONST CHAR8 *Format,
...
)
{
VOID *DebugDevice;
UINTN ArgValue;
va_list Args;
va_start(Args, Format);
ArgValue = va_arg(Args, UINTN);
DebugDevice = GetDebugOutputDevice();
if (DebugDevice != NULL) {
//
// Call debug device's print handler (offset +8 = PRINT)
//
((void (*)(UINTN, CONST CHAR8 *, UINTN))DebugDevice)(
ErrorLevel,
Format,
ArgValue
);
}
va_end(Args);
}
//
// ========== Support Library Functions ==========
//
///
/// Locates the HOB (Hand-Off Block) list from the UEFI System Table
/// configuration table.
///
/// Scans SystemTable->ConfigurationTable[] entries looking for the GUID
/// {0x7739F24C, 0x93D7, 0x11D4, 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}
/// which is EFI_HOB_LIST_GUID.
///
/// Results are cached in qword_1090 after the first successful lookup.
///
/// @return Pointer to the start of the HOB list, or NULL if not found.
///
VOID *
GetHobList(
VOID
)
{
UINTN Index;
EFI_CONFIGURATION_TABLE *ConfigTable;
if (qword_1090 != 0) {
return (VOID *)qword_1090;
}
qword_1090 = 0;
if (gST->NumberOfTableEntries > 0) {
ConfigTable = gST->ConfigurationTable;
for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
if (IsProtocolInstalled(0, &ConfigTable[Index])) {
qword_1090 = (UINTN)ConfigTable[Index].Table;
return (VOID *)qword_1090;
}
}
//
// Not found in configuration table
//
DebugAssert((CONST CHAR8 *)0x80000000LL,
(UINTN)"\nASSERT_EFI_ERROR (Status = %r)\n",
(CONST CHAR8 *)0x800000000000000ELL);
DebugPrint((UINTN)"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
(UINTN)54,
"!EFI_ERROR (Status)");
}
if (qword_1090 == 0) {
DebugPrint((UINTN)"e:\\hs\\MdePkg\\Library\\DxeHobLib\\HobLib.c",
(UINTN)55,
"mHobList != ((void *) 0)");
}
return (VOID *)qword_1090;
}
///
/// Reads an unaligned 64-bit value from memory.
///
/// Implements the EDK2 BaseLib ReadUnaligned64() function. If the Buffer
/// pointer is NULL, issues a debug assertion via DebugPrint().
///
/// @param Buffer Pointer to the (potentially unaligned) 64-bit value.
///
/// @return The 64-bit value read from memory.
///
UINT64
EFIAPI
ReadUnaligned64(
IN CONST UINT64 *Buffer
)
{
if (Buffer == NULL) {
DebugPrint((UINTN)"e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
(UINTN)192,
"Buffer != ((void *) 0)");
}
return *Buffer;
}
///
/// Checks whether a configuration table entry matches a reference GUID.
///
/// Compares the VendorGuid field of an EFI_CONFIGURATION_TABLE entry
/// against the EFI_HOB_LIST_GUID by reading both as unaligned 64-bit
/// values.
///
/// @param a1 Unused context parameter.
/// @param Buffer Pointer to an EFI_CONFIGURATION_TABLE entry to check.
///
/// @retval TRUE The GUID in the entry matches the HOB list GUID.
/// @retval FALSE The GUID does not match.
///
BOOLEAN
EFIAPI
IsProtocolInstalled(
IN UINTN a1,
IN EFI_CONFIGURATION_TABLE *Buffer
)
{
EFI_GUID ReferenceGuid = EFI_HOB_LIST_GUID;
//
// Compare first 8 bytes and second 8 bytes as 64-bit values
//
return (ReadUnaligned64((CONST UINT64 *)&ReferenceGuid) ==
ReadUnaligned64((CONST UINT64 *)Buffer)) &&
(ReadUnaligned64((CONST UINT64 *)&ReferenceGuid.Data4[0]) ==
ReadUnaligned64((CONST UINT64 *)&Buffer->VendorGuid.Data4[0]));
}