]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / DxeExtractGuidedSectionLib / DxeExtractGuidedSectionLib.c
1 /** @file
2 Provide generic extract guided section functions for Dxe phase.
3
4 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <PiDxe.h>
10
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>
16
17 #define EXTRACT_HANDLER_TABLE_SIZE 0x10
18
19 UINT32 mNumberOfExtractHandler = 0;
20 UINT32 mMaxNumberOfExtractHandler = 0;
21
22 GUID *mExtractHandlerGuidTable = NULL;
23 EXTRACT_GUIDED_SECTION_DECODE_HANDLER *mExtractDecodeHandlerTable = NULL;
24 EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *mExtractGetInfoHandlerTable = NULL;
25
26 /**
27 Reallocates more global memory to store the registered guid and Handler list.
28
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.
31 **/
32 RETURN_STATUS
33 EFIAPI
34 ReallocateExtractHandlerTable (
35 VOID
36 )
37 {
38 //
39 // Reallocate memory for GuidTable
40 //
41 mExtractHandlerGuidTable = ReallocatePool (
42 mMaxNumberOfExtractHandler * sizeof (GUID),
43 (mMaxNumberOfExtractHandler + EXTRACT_HANDLER_TABLE_SIZE) * sizeof (GUID),
44 mExtractHandlerGuidTable
45 );
46
47 if (mExtractHandlerGuidTable == NULL) {
48 goto Done;
49 }
50
51 //
52 // Reallocate memory for Decode handler Table
53 //
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
58 );
59
60 if (mExtractDecodeHandlerTable == NULL) {
61 goto Done;
62 }
63
64 //
65 // Reallocate memory for GetInfo handler Table
66 //
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
71 );
72
73 if (mExtractGetInfoHandlerTable == NULL) {
74 goto Done;
75 }
76
77 //
78 // Increase max handler number
79 //
80 mMaxNumberOfExtractHandler = mMaxNumberOfExtractHandler + EXTRACT_HANDLER_TABLE_SIZE;
81 return RETURN_SUCCESS;
82
83 Done:
84 if (mExtractHandlerGuidTable != NULL) {
85 FreePool (mExtractHandlerGuidTable);
86 }
87
88 if (mExtractDecodeHandlerTable != NULL) {
89 FreePool (mExtractDecodeHandlerTable);
90 }
91
92 if (mExtractGetInfoHandlerTable != NULL) {
93 FreePool (mExtractGetInfoHandlerTable);
94 }
95
96 return RETURN_OUT_OF_RESOURCES;
97 }
98
99 /**
100 Constructor allocates the global memory to store the registered guid and Handler list.
101
102 @param ImageHandle The firmware allocated handle for the EFI image.
103 @param SystemTable A pointer to the EFI System Table.
104
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.
107 **/
108 RETURN_STATUS
109 EFIAPI
110 DxeExtractGuidedSectionLibConstructor (
111 IN EFI_HANDLE ImageHandle,
112 IN EFI_SYSTEM_TABLE *SystemTable
113 )
114 {
115 return ReallocateExtractHandlerTable ();
116 }
117
118 /**
119 Retrieve the list GUIDs that have been registered through ExtractGuidedSectionRegisterHandlers().
120
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().
125
126 @param[out] ExtractHandlerGuidTable A pointer to the array of GUIDs that have been registered through
127 ExtractGuidedSectionRegisterHandlers().
128
129 @return The number of the supported extract guided Handler.
130
131 **/
132 UINTN
133 EFIAPI
134 ExtractGuidedSectionGetGuidList (
135 OUT GUID **ExtractHandlerGuidTable
136 )
137 {
138 ASSERT (ExtractHandlerGuidTable != NULL);
139
140 *ExtractHandlerGuidTable = mExtractHandlerGuidTable;
141 return mNumberOfExtractHandler;
142 }
143
144 /**
145 Registers handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and EXTRACT_GUIDED_SECTION_DECODE_HANDLER
146 for a specific GUID section type.
147
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.
151
152 If SectionGuid is NULL, then ASSERT().
153 If GetInfoHandler is NULL, then ASSERT().
154 If DecodeHandler is NULL, then ASSERT().
155
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.
163
164 @retval RETURN_SUCCESS The handlers were registered.
165 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to register the handlers.
166
167 **/
168 RETURN_STATUS
169 EFIAPI
170 ExtractGuidedSectionRegisterHandlers (
171 IN CONST GUID *SectionGuid,
172 IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER GetInfoHandler,
173 IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER DecodeHandler
174 )
175 {
176 UINT32 Index;
177 VOID *GuidData;
178
179 //
180 // Check input parameter.
181 //
182 ASSERT (SectionGuid != NULL);
183 ASSERT (GetInfoHandler != NULL);
184 ASSERT (DecodeHandler != NULL);
185
186 //
187 // Search the match registered GetInfo handler for the input guided section.
188 //
189 for (Index = 0; Index < mNumberOfExtractHandler; Index++) {
190 if (CompareGuid (&mExtractHandlerGuidTable[Index], SectionGuid)) {
191 //
192 // If the guided handler has been registered before, only update its handler.
193 //
194 mExtractDecodeHandlerTable[Index] = DecodeHandler;
195 mExtractGetInfoHandlerTable[Index] = GetInfoHandler;
196 return RETURN_SUCCESS;
197 }
198 }
199
200 //
201 // Check the global table is enough to contain new Handler.
202 //
203 if (mNumberOfExtractHandler >= mMaxNumberOfExtractHandler) {
204 if (ReallocateExtractHandlerTable () != RETURN_SUCCESS) {
205 return RETURN_OUT_OF_RESOURCES;
206 }
207 }
208
209 //
210 // Register new Handler and guid value.
211 //
212 CopyGuid (&mExtractHandlerGuidTable[mNumberOfExtractHandler], SectionGuid);
213 mExtractDecodeHandlerTable[mNumberOfExtractHandler] = DecodeHandler;
214 mExtractGetInfoHandlerTable[mNumberOfExtractHandler++] = GetInfoHandler;
215
216 //
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.
219 //
220 GuidData = AllocateCopyPool (sizeof (GUID), (VOID *)SectionGuid);
221 if (GuidData != NULL) {
222 gBS->InstallConfigurationTable ((EFI_GUID *)SectionGuid, GuidData);
223 }
224
225 return RETURN_SUCCESS;
226 }
227
228 /**
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.
233
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.
241
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().
246
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.
254
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.
260
261 **/
262 RETURN_STATUS
263 EFIAPI
264 ExtractGuidedSectionGetInfo (
265 IN CONST VOID *InputSection,
266 OUT UINT32 *OutputBufferSize,
267 OUT UINT32 *ScratchBufferSize,
268 OUT UINT16 *SectionAttribute
269 )
270 {
271 UINT32 Index;
272 EFI_GUID *SectionDefinitionGuid;
273
274 ASSERT (InputSection != NULL);
275 ASSERT (OutputBufferSize != NULL);
276 ASSERT (ScratchBufferSize != NULL);
277 ASSERT (SectionAttribute != NULL);
278
279 if (IS_SECTION2 (InputSection)) {
280 SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid);
281 } else {
282 SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid);
283 }
284
285 //
286 // Search the match registered GetInfo handler for the input guided section.
287 //
288 for (Index = 0; Index < mNumberOfExtractHandler; Index++) {
289 if (CompareGuid (&mExtractHandlerGuidTable[Index], SectionDefinitionGuid)) {
290 //
291 // Call the match handler to getinfo for the input section data.
292 //
293 return mExtractGetInfoHandlerTable[Index](
294 InputSection,
295 OutputBufferSize,
296 ScratchBufferSize,
297 SectionAttribute
298 );
299 }
300 }
301
302 //
303 // Not found, the input guided section is not supported.
304 //
305 return RETURN_UNSUPPORTED;
306 }
307
308 /**
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.
313
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.
324
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().
329
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
336 Specification.
337
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.
341
342 **/
343 RETURN_STATUS
344 EFIAPI
345 ExtractGuidedSectionDecode (
346 IN CONST VOID *InputSection,
347 OUT VOID **OutputBuffer,
348 IN VOID *ScratchBuffer OPTIONAL,
349 OUT UINT32 *AuthenticationStatus
350 )
351 {
352 UINT32 Index;
353 EFI_GUID *SectionDefinitionGuid;
354
355 //
356 // Check the input parameters
357 //
358 ASSERT (InputSection != NULL);
359 ASSERT (OutputBuffer != NULL);
360 ASSERT (AuthenticationStatus != NULL);
361
362 if (IS_SECTION2 (InputSection)) {
363 SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid);
364 } else {
365 SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid);
366 }
367
368 //
369 // Search the match registered extract handler for the input guided section.
370 //
371 for (Index = 0; Index < mNumberOfExtractHandler; Index++) {
372 if (CompareGuid (&mExtractHandlerGuidTable[Index], SectionDefinitionGuid)) {
373 //
374 // Call the match handler to extract raw data for the input section data.
375 //
376 return mExtractDecodeHandlerTable[Index](
377 InputSection,
378 OutputBuffer,
379 ScratchBuffer,
380 AuthenticationStatus
381 );
382 }
383 }
384
385 //
386 // Not found, the input guided section is not supported.
387 //
388 return RETURN_UNSUPPORTED;
389 }
390
391 /**
392 Retrieves handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and
393 EXTRACT_GUIDED_SECTION_DECODE_HANDLER for a specific GUID section type.
394
395 Retrieves the handlers associated with SectionGuid and returns them in
396 GetInfoHandler and DecodeHandler.
397
398 If the GUID value specified by SectionGuid has not been registered, then
399 return RETURN_NOT_FOUND.
400
401 If SectionGuid is NULL, then ASSERT().
402
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.
413
414 @retval RETURN_SUCCESS The handlers were retrieved.
415 @retval RETURN_NOT_FOUND No handlers have been registered with the specified GUID.
416
417 **/
418 RETURN_STATUS
419 EFIAPI
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
424 )
425 {
426 UINT32 Index;
427
428 //
429 // Check input parameter.
430 //
431 ASSERT (SectionGuid != NULL);
432
433 //
434 // Search the match registered GetInfo handler for the input guided section.
435 //
436 for (Index = 0; Index < mNumberOfExtractHandler; Index++) {
437 if (CompareGuid (&mExtractHandlerGuidTable[Index], SectionGuid)) {
438 //
439 // If the guided handler has been registered before, then return the registered handlers.
440 //
441 if (GetInfoHandler != NULL) {
442 *GetInfoHandler = mExtractGetInfoHandlerTable[Index];
443 }
444
445 if (DecodeHandler != NULL) {
446 *DecodeHandler = mExtractDecodeHandlerTable[Index];
447 }
448
449 return RETURN_SUCCESS;
450 }
451 }
452
453 return RETURN_NOT_FOUND;
454 }