2 Provide generic extract guided section functions for Dxe phase.
4 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Library/DebugLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/MemoryAllocationLib.h>
14 #include <Library/ExtractGuidedSectionLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
17 #define EXTRACT_HANDLER_TABLE_SIZE 0x10
19 UINT32 mNumberOfExtractHandler
= 0;
20 UINT32 mMaxNumberOfExtractHandler
= 0;
22 GUID
*mExtractHandlerGuidTable
= NULL
;
23 EXTRACT_GUIDED_SECTION_DECODE_HANDLER
*mExtractDecodeHandlerTable
= NULL
;
24 EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER
*mExtractGetInfoHandlerTable
= NULL
;
27 Reallocates more global memory to store the registered guid and Handler list.
29 @retval RETURN_SUCCESS Reallocated more global memory space to store guid and function tables.
30 @retval RETURN_OUT_OF_RESOURCES Not enough memory to allocate.
34 ReallocateExtractHandlerTable (
39 // Reallocate memory for GuidTable
41 mExtractHandlerGuidTable
= ReallocatePool (
42 mMaxNumberOfExtractHandler
* sizeof (GUID
),
43 (mMaxNumberOfExtractHandler
+ EXTRACT_HANDLER_TABLE_SIZE
) * sizeof (GUID
),
44 mExtractHandlerGuidTable
47 if (mExtractHandlerGuidTable
== NULL
) {
52 // Reallocate memory for Decode handler Table
54 mExtractDecodeHandlerTable
= ReallocatePool (
55 mMaxNumberOfExtractHandler
* sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER
),
56 (mMaxNumberOfExtractHandler
+ EXTRACT_HANDLER_TABLE_SIZE
) * sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER
),
57 mExtractDecodeHandlerTable
60 if (mExtractDecodeHandlerTable
== NULL
) {
65 // Reallocate memory for GetInfo handler Table
67 mExtractGetInfoHandlerTable
= ReallocatePool (
68 mMaxNumberOfExtractHandler
* sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER
),
69 (mMaxNumberOfExtractHandler
+ EXTRACT_HANDLER_TABLE_SIZE
) * sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER
),
70 mExtractGetInfoHandlerTable
73 if (mExtractGetInfoHandlerTable
== NULL
) {
78 // Increase max handler number
80 mMaxNumberOfExtractHandler
= mMaxNumberOfExtractHandler
+ EXTRACT_HANDLER_TABLE_SIZE
;
81 return RETURN_SUCCESS
;
84 if (mExtractHandlerGuidTable
!= NULL
) {
85 FreePool (mExtractHandlerGuidTable
);
88 if (mExtractDecodeHandlerTable
!= NULL
) {
89 FreePool (mExtractDecodeHandlerTable
);
92 if (mExtractGetInfoHandlerTable
!= NULL
) {
93 FreePool (mExtractGetInfoHandlerTable
);
96 return RETURN_OUT_OF_RESOURCES
;
100 Constructor allocates the global memory to store the registered guid and Handler list.
102 @param ImageHandle The firmware allocated handle for the EFI image.
103 @param SystemTable A pointer to the EFI System Table.
105 @retval RETURN_SUCCESS Allocated the global memory space to store guid and function tables.
106 @retval RETURN_OUT_OF_RESOURCES Not enough memory to allocate.
110 DxeExtractGuidedSectionLibConstructor (
111 IN EFI_HANDLE ImageHandle
,
112 IN EFI_SYSTEM_TABLE
*SystemTable
115 return ReallocateExtractHandlerTable ();
119 Retrieve the list GUIDs that have been registered through ExtractGuidedSectionRegisterHandlers().
121 Sets ExtractHandlerGuidTable so it points at a callee allocated array of registered GUIDs.
122 The total number of GUIDs in the array are returned. Since the array of GUIDs is callee allocated
123 and caller must treat this array of GUIDs as read-only data.
124 If ExtractHandlerGuidTable is NULL, then ASSERT().
126 @param[out] ExtractHandlerGuidTable A pointer to the array of GUIDs that have been registered through
127 ExtractGuidedSectionRegisterHandlers().
129 @return The number of the supported extract guided Handler.
134 ExtractGuidedSectionGetGuidList (
135 OUT GUID
**ExtractHandlerGuidTable
138 ASSERT (ExtractHandlerGuidTable
!= NULL
);
140 *ExtractHandlerGuidTable
= mExtractHandlerGuidTable
;
141 return mNumberOfExtractHandler
;
145 Registers handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and EXTRACT_GUIDED_SECTION_DECODE_HANDLER
146 for a specific GUID section type.
148 Registers the handlers specified by GetInfoHandler and DecodeHandler with the GUID specified by SectionGuid.
149 If the GUID value specified by SectionGuid has already been registered, then return RETURN_ALREADY_STARTED.
150 If there are not enough resources available to register the handlers then RETURN_OUT_OF_RESOURCES is returned.
152 If SectionGuid is NULL, then ASSERT().
153 If GetInfoHandler is NULL, then ASSERT().
154 If DecodeHandler is NULL, then ASSERT().
156 @param[in] SectionGuid A pointer to the GUID associated with the handlers
157 of the GUIDed section type being registered.
158 @param[in] GetInfoHandler The pointer to a function that examines a GUIDed section and returns the
159 size of the decoded buffer and the size of an optional scratch buffer
160 required to actually decode the data in a GUIDed section.
161 @param[in] DecodeHandler The pointer to a function that decodes a GUIDed section into a caller
162 allocated output buffer.
164 @retval RETURN_SUCCESS The handlers were registered.
165 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to register the handlers.
170 ExtractGuidedSectionRegisterHandlers (
171 IN CONST GUID
*SectionGuid
,
172 IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER GetInfoHandler
,
173 IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER DecodeHandler
180 // Check input parameter.
182 ASSERT (SectionGuid
!= NULL
);
183 ASSERT (GetInfoHandler
!= NULL
);
184 ASSERT (DecodeHandler
!= NULL
);
187 // Search the match registered GetInfo handler for the input guided section.
189 for (Index
= 0; Index
< mNumberOfExtractHandler
; Index
++) {
190 if (CompareGuid (&mExtractHandlerGuidTable
[Index
], SectionGuid
)) {
192 // If the guided handler has been registered before, only update its handler.
194 mExtractDecodeHandlerTable
[Index
] = DecodeHandler
;
195 mExtractGetInfoHandlerTable
[Index
] = GetInfoHandler
;
196 return RETURN_SUCCESS
;
201 // Check the global table is enough to contain new Handler.
203 if (mNumberOfExtractHandler
>= mMaxNumberOfExtractHandler
) {
204 if (ReallocateExtractHandlerTable () != RETURN_SUCCESS
) {
205 return RETURN_OUT_OF_RESOURCES
;
210 // Register new Handler and guid value.
212 CopyGuid (&mExtractHandlerGuidTable
[mNumberOfExtractHandler
], SectionGuid
);
213 mExtractDecodeHandlerTable
[mNumberOfExtractHandler
] = DecodeHandler
;
214 mExtractGetInfoHandlerTable
[mNumberOfExtractHandler
++] = GetInfoHandler
;
217 // Install the Guided Section GUID configuration table to record the GUID itself.
218 // Then the content of the configuration table buffer will be the same as the GUID value itself.
220 GuidData
= AllocateCopyPool (sizeof (GUID
), (VOID
*)SectionGuid
);
221 if (GuidData
!= NULL
) {
222 gBS
->InstallConfigurationTable ((EFI_GUID
*)SectionGuid
, GuidData
);
225 return RETURN_SUCCESS
;
229 Retrieves a GUID from a GUIDed section and uses that GUID to select an associated handler of type
230 EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().
231 The selected handler is used to retrieve and return the size of the decoded buffer and the size of an
232 optional scratch buffer required to actually decode the data in a GUIDed section.
234 Examines a GUIDed section specified by InputSection.
235 If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),
236 then RETURN_UNSUPPORTED is returned.
237 If the GUID of InputSection does match the GUID that this handler supports, then the associated handler
238 of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()
239 is used to retrieve the OutputBufferSize, ScratchSize, and Attributes values. The return status from the handler of
240 type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER is returned.
242 If InputSection is NULL, then ASSERT().
243 If OutputBufferSize is NULL, then ASSERT().
244 If ScratchBufferSize is NULL, then ASSERT().
245 If SectionAttribute is NULL, then ASSERT().
247 @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.
248 @param[out] OutputBufferSize A pointer to the size, in bytes, of an output buffer required if the buffer
249 specified by InputSection were decoded.
250 @param[out] ScratchBufferSize A pointer to the size, in bytes, required as scratch space if the buffer specified by
251 InputSection were decoded.
252 @param[out] SectionAttribute A pointer to the attributes of the GUIDed section. See the Attributes field of
253 EFI_GUID_DEFINED_SECTION in the PI Specification.
255 @retval RETURN_SUCCESS Successfully obtained the required information.
256 @retval RETURN_UNSUPPORTED The GUID from the section specified by InputSection does not match any of
257 the GUIDs registered with ExtractGuidedSectionRegisterHandlers().
258 @retval Others The return status from the handler associated with the GUID retrieved from
259 the section specified by InputSection.
264 ExtractGuidedSectionGetInfo (
265 IN CONST VOID
*InputSection
,
266 OUT UINT32
*OutputBufferSize
,
267 OUT UINT32
*ScratchBufferSize
,
268 OUT UINT16
*SectionAttribute
272 EFI_GUID
*SectionDefinitionGuid
;
274 ASSERT (InputSection
!= NULL
);
275 ASSERT (OutputBufferSize
!= NULL
);
276 ASSERT (ScratchBufferSize
!= NULL
);
277 ASSERT (SectionAttribute
!= NULL
);
279 if (IS_SECTION2 (InputSection
)) {
280 SectionDefinitionGuid
= &(((EFI_GUID_DEFINED_SECTION2
*)InputSection
)->SectionDefinitionGuid
);
282 SectionDefinitionGuid
= &(((EFI_GUID_DEFINED_SECTION
*)InputSection
)->SectionDefinitionGuid
);
286 // Search the match registered GetInfo handler for the input guided section.
288 for (Index
= 0; Index
< mNumberOfExtractHandler
; Index
++) {
289 if (CompareGuid (&mExtractHandlerGuidTable
[Index
], SectionDefinitionGuid
)) {
291 // Call the match handler to getinfo for the input section data.
293 return mExtractGetInfoHandlerTable
[Index
](
303 // Not found, the input guided section is not supported.
305 return RETURN_UNSUPPORTED
;
309 Retrieves the GUID from a GUIDed section and uses that GUID to select an associated handler of type
310 EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().
311 The selected handler is used to decode the data in a GUIDed section and return the result in a caller
312 allocated output buffer.
314 Decodes the GUIDed section specified by InputSection.
315 If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),
316 then RETURN_UNSUPPORTED is returned.
317 If the GUID of InputSection does match the GUID that this handler supports, then the associated handler
318 of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()
319 is used to decode InputSection into the buffer specified by OutputBuffer and the authentication status of this
320 decode operation is returned in AuthenticationStatus. If the decoded buffer is identical to the data in InputSection,
321 then OutputBuffer is set to point at the data in InputSection. Otherwise, the decoded data will be placed in caller
322 allocated buffer specified by OutputBuffer. This function is responsible for computing the EFI_AUTH_STATUS_PLATFORM_OVERRIDE
323 bit of in AuthenticationStatus. The return status from the handler of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER is returned.
325 If InputSection is NULL, then ASSERT().
326 If OutputBuffer is NULL, then ASSERT().
327 If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().
328 If AuthenticationStatus is NULL, then ASSERT().
330 @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.
331 @param[out] OutputBuffer A pointer to a buffer that contains the result of a decode operation.
332 @param[in] ScratchBuffer A caller allocated buffer that may be required by this function as a scratch buffer to perform the decode operation.
333 @param[out] AuthenticationStatus
334 A pointer to the authentication status of the decoded output buffer. See the definition
335 of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI section of the PI
338 @retval RETURN_SUCCESS The buffer specified by InputSection was decoded.
339 @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports.
340 @retval RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded.
345 ExtractGuidedSectionDecode (
346 IN CONST VOID
*InputSection
,
347 OUT VOID
**OutputBuffer
,
348 IN VOID
*ScratchBuffer OPTIONAL
,
349 OUT UINT32
*AuthenticationStatus
353 EFI_GUID
*SectionDefinitionGuid
;
356 // Check the input parameters
358 ASSERT (InputSection
!= NULL
);
359 ASSERT (OutputBuffer
!= NULL
);
360 ASSERT (AuthenticationStatus
!= NULL
);
362 if (IS_SECTION2 (InputSection
)) {
363 SectionDefinitionGuid
= &(((EFI_GUID_DEFINED_SECTION2
*)InputSection
)->SectionDefinitionGuid
);
365 SectionDefinitionGuid
= &(((EFI_GUID_DEFINED_SECTION
*)InputSection
)->SectionDefinitionGuid
);
369 // Search the match registered extract handler for the input guided section.
371 for (Index
= 0; Index
< mNumberOfExtractHandler
; Index
++) {
372 if (CompareGuid (&mExtractHandlerGuidTable
[Index
], SectionDefinitionGuid
)) {
374 // Call the match handler to extract raw data for the input section data.
376 return mExtractDecodeHandlerTable
[Index
](
386 // Not found, the input guided section is not supported.
388 return RETURN_UNSUPPORTED
;
392 Retrieves handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and
393 EXTRACT_GUIDED_SECTION_DECODE_HANDLER for a specific GUID section type.
395 Retrieves the handlers associated with SectionGuid and returns them in
396 GetInfoHandler and DecodeHandler.
398 If the GUID value specified by SectionGuid has not been registered, then
399 return RETURN_NOT_FOUND.
401 If SectionGuid is NULL, then ASSERT().
403 @param[in] SectionGuid A pointer to the GUID associated with the handlers of the GUIDed
404 section type being retrieved.
405 @param[out] GetInfoHandler Pointer to a function that examines a GUIDed section and returns
406 the size of the decoded buffer and the size of an optional scratch
407 buffer required to actually decode the data in a GUIDed section.
408 This is an optional parameter that may be NULL. If it is NULL, then
409 the previously registered handler is not returned.
410 @param[out] DecodeHandler Pointer to a function that decodes a GUIDed section into a caller
411 allocated output buffer. This is an optional parameter that may be NULL.
412 If it is NULL, then the previously registered handler is not returned.
414 @retval RETURN_SUCCESS The handlers were retrieved.
415 @retval RETURN_NOT_FOUND No handlers have been registered with the specified GUID.
420 ExtractGuidedSectionGetHandlers (
421 IN CONST GUID
*SectionGuid
,
422 OUT EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER
*GetInfoHandler OPTIONAL
,
423 OUT EXTRACT_GUIDED_SECTION_DECODE_HANDLER
*DecodeHandler OPTIONAL
429 // Check input parameter.
431 ASSERT (SectionGuid
!= NULL
);
434 // Search the match registered GetInfo handler for the input guided section.
436 for (Index
= 0; Index
< mNumberOfExtractHandler
; Index
++) {
437 if (CompareGuid (&mExtractHandlerGuidTable
[Index
], SectionGuid
)) {
439 // If the guided handler has been registered before, then return the registered handlers.
441 if (GetInfoHandler
!= NULL
) {
442 *GetInfoHandler
= mExtractGetInfoHandlerTable
[Index
];
445 if (DecodeHandler
!= NULL
) {
446 *DecodeHandler
= mExtractDecodeHandlerTable
[Index
];
449 return RETURN_SUCCESS
;
453 return RETURN_NOT_FOUND
;