해당 구조에는 기본 HII 프로토콜에 대한 포인터가 포함되어 있다. 이러한 각 프로토콜은 HII의 다른 부분과의 상호작용을 담당한다. 예를 들어 하나는 HII 데이터베이스(EFI_HII_FONT_PROTOCOL)의 글꼴과의 상호 작용을 담당하고, 다른 하나는 이미지와의 상호 작용(EFI_HII_IMAGE_PROTOCOL/EFI_HII_IMAGE_EX_PROTOCOL)과 문자열(EFI_HII_STRING_PROTOCOL)과의 상호작용을 담당한다.
앞서 데이터베이스에서 HII 패키지를 추가/제거하는 EFI_HII_DATABASE_PROTOCOL 를 살펴보았기 때문에 다른 HII 요소들을 통해 이 프로토콜의 가능성을 더 살펴보자.
LIST_ENTRY DatabaseList 는 첫번째 HII_DATABASE_RECORD 의 DatabaseEntry 필드를 가르킨다. 이 구조에서 DatabaseEntry 는 차례로 다음 HII_DATABASE_RECORD 의 DatabaseEntry 필드를 가르킨다.
각 이중 연결 리스트에는 이 패키지 목록에 있는 해당 유형의 패키지에 대한 포인터가 포함되어 있다. 이전 학습에서는 모든 패키지 목록과 해당 패키지를 연속 데이터 배열로 받았지만 이는 EFI_HII_DATABASE_PROTOCOL 의 ExportPackageLists 함수 기능일 뿐, HII 데이터는 플랫폼 메모리 전체에 분산 될 수 있는 이중 연결 리스트로 표현되어 있다.
@param Record The pointer to the field specified by Field within a data
structure of type TYPE.
@param TYPE The name of the data structure type to return This
data structure must contain the field specified by Field.
@param Field The name of the field in the data structure specified
by TYPE to which Record points.
@param TestSignature The 32-bit signature value to match.
**/
#if !defined(MDEPKG_NDEBUG)
#define CR(Record, TYPE, Field, TestSignature) \
(DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ? \
(TYPE *) (_ASSERT (CR has Bad Signature), Record) : \
BASE_CR (Record, TYPE, Field)
#else
#define CR(Record, TYPE, Field, TestSignature) \
BASE_CR (Record, TYPE, Field)
#endif
/**
Macro that returns a pointer to the data structure that contains a specified field of
that data structure. This is a lightweight method to hide information by placing a
public data structure inside a larger private data structure and using a pointer to
the public data structure to retrieve a pointer to the private data structure.
This function computes the offset, in bytes, of field specified by Field from the beginning
of the data structure specified by TYPE. This offset is subtracted from Record, and is
used to return a pointer to a data structure of the type specified by TYPE. If the data type
specified by TYPE does not contain the field specified by Field, then the module will not compile.
@param Record Pointer to the field specified by Field within a data structure of type TYPE.
@param TYPE The name of the data structure type to return. This data structure must
contain the field specified by Field.
@param Field The name of the field in the data structure specified by TYPE to which Record points.
@return A pointer to the structure from one of it's elements.
**/
#define BASE_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - OFFSET_OF (TYPE, Field)))
마지막으로로OFFSET_OF 에 대한 정의이다.
/**
The macro that returns the byte offset of a field in a data structure.
This function returns the offset, in bytes, of field specified by Field from the
beginning of the data structure specified by TYPE. If TYPE does not contain Field,
the module will not compile.
@param TYPE The name of the data structure that contains the field specified by Field.
@param Field The name of the field in the data structure.
@return Offset, in bytes, of field.
**/
#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)
#define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field))
#endif
#ifndef OFFSET_OF
#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
#endif