Newer
Older
AMI-Aptio-BIOS-Reversed / MdeModulePkg / Universal / Console / GraphicsConsoleDxe / EnglishDxe / EnglishDxe.c
@Ajax Dong Ajax Dong 2 days ago 22 KB Restructure the repo
/** @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]));
}