]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/DxeServicesLib/DxeServicesLib.c
Remove checking for overflow in several Multiple functions in BaseLib, for it is...
[mirror_edk2.git] / MdePkg / Library / DxeServicesLib / DxeServicesLib.c
CommitLineData
1c280088 1/** @file\r
b75a165d
LG
2 MDE DXE Services Library provides functions that simplify the development of DXE Drivers. \r
3 These functions help access data from sections of FFS files.\r
1c280088 4\r
8cf43dd7 5 Copyright (c) 2007 - 2008, Intel Corporation<BR>\r
1c280088 6 All rights reserved. This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <PiDxe.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
19#include <Library/UefiBootServicesTableLib.h>\r
eb9dd4d0 20#include <Library/DxeServicesLib.h>\r
1c280088 21#include <Protocol/FirmwareVolume2.h>\r
22#include <Protocol/LoadedImage.h>\r
23\r
24\r
25/**\r
166152e8 26 Identify the device handle from which the Image is loaded from. As this device handle is passed to\r
27 GetSectionFromFv as the identifier for a Firmware Volume, an EFI_FIRMWARE_VOLUME2_PROTOCOL \r
28 protocol instance should be located succesfully by calling gBS->HandleProtocol ().\r
1c280088 29\r
166152e8 30 This function locates the EFI_LOADED_IMAGE_PROTOCOL instance installed\r
31 on ImageHandle. It then returns EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle.\r
32 \r
33 If ImageHandle is NULL, then ASSERT ();\r
34 If failed to locate a EFI_LOADED_IMAGE_PROTOCOL on ImageHandle, then ASSERT ();\r
35 \r
36 @param ImageHandle The firmware allocated handle for UEFI image.\r
1c280088 37\r
b75a165d 38 @retval EFI_HANDLE The device handle from which the Image is loaded from.\r
1c280088 39\r
40**/\r
166152e8 41EFI_HANDLE\r
42InternalImageHandleToFvHandle (\r
43 EFI_HANDLE ImageHandle\r
44 )\r
45{\r
46 EFI_STATUS Status;\r
47 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
48 \r
49 ASSERT (ImageHandle != NULL);\r
50\r
51 Status = gBS->HandleProtocol (\r
52 (EFI_HANDLE *) ImageHandle,\r
53 &gEfiLoadedImageProtocolGuid,\r
54 (VOID **) &LoadedImage\r
55 );\r
56\r
57 ASSERT_EFI_ERROR (Status);\r
58\r
59 return LoadedImage->DeviceHandle;\r
60\r
61}\r
62\r
63/**\r
b75a165d
LG
64 Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware \r
65 Section type and instance number from the specified Firmware Volume.\r
66\r
67 This functions first locate the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance on FvHandle in order to \r
68 carry out the Firmware Volume read operation. The function then reads the Firmware Section found sepcifed \r
69 by NameGuid, SectionType and SectionInstance. \r
70 \r
71 The details of this search order is defined in description of EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection () \r
72 found in PI Specification.\r
73 \r
74 If SectionType is EFI_SECTION_TE, EFI_SECTION_TE is used as section type to start the search. If EFI_SECTION_TE section \r
75 is not found, EFI_SECTION_PE32 will be used to try the search again. If no EFI_SECTION_PE32 section is found, EFI_NOT_FOUND \r
76 is returned.\r
166152e8 77 \r
b75a165d
LG
78 The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated \r
79 by this function. This function can be only called at TPL_NOTIFY and below.\r
166152e8 80 \r
b75a165d
LG
81 If FvHandle is NULL, then ASSERT ();\r
82 If NameGuid is NULL, then ASSERT();\r
83 If Buffer is NULL, then ASSERT();\r
84 If Size is NULL, then ASSERT().\r
85\r
86 @param FvHandle The device handle that contains a instance of EFI_FIRMWARE_VOLUME2_PROTOCOL instance.\r
87 @param NameGuid The GUID name of a Firmware File.\r
88 @param SectionType The Firmware Section type.\r
89 @param SectionInstance The instance number of Firmware Section to read from starting from 0.\r
90 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.\r
91 @param Size On output, the size of Buffer.\r
92\r
93 @retval EFI_SUCCESS The image is found and data and size is returned.\r
94 @retval EFI_UNSUPPORTED FvHandle does not support EFI_FIRMWARE_VOLUME2_PROTOCOL.\r
95 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.\r
96 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
97 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
98 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.\r
166152e8 99 \r
f80b0830 100**/\r
1c280088 101EFI_STATUS\r
eb9dd4d0 102InternalGetSectionFromFv (\r
166152e8 103 IN EFI_HANDLE FvHandle,\r
104 IN CONST EFI_GUID *NameGuid,\r
105 IN EFI_SECTION_TYPE SectionType,\r
ff197efb 106 IN UINTN SectionInstance,\r
166152e8 107 OUT VOID **Buffer,\r
108 OUT UINTN *Size\r
1c280088 109 )\r
110{\r
166152e8 111 EFI_STATUS Status;\r
112 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
113 UINT32 AuthenticationStatus;\r
114\r
8cf43dd7 115 ASSERT (NameGuid != NULL);\r
116 ASSERT (Buffer != NULL);\r
117 ASSERT (Size != NULL);\r
118 \r
166152e8 119 ASSERT (FvHandle != NULL);\r
120\r
121 Status = gBS->HandleProtocol (\r
122 FvHandle,\r
123 &gEfiFirmwareVolume2ProtocolGuid,\r
124 (VOID **) &Fv\r
125 );\r
126 if (EFI_ERROR (Status)) {\r
127 return Status;\r
128 }\r
1c280088 129\r
130 //\r
131 // Read desired section content in NameGuid file\r
132 //\r
133 *Buffer = NULL;\r
134 *Size = 0;\r
135 Status = Fv->ReadSection (\r
136 Fv,\r
137 NameGuid,\r
138 SectionType,\r
ff197efb 139 SectionInstance,\r
1c280088 140 Buffer,\r
141 Size,\r
142 &AuthenticationStatus\r
143 );\r
144\r
145 if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {\r
146 //\r
166152e8 147 // Try reading PE32 section, if the required section is TE type \r
1c280088 148 //\r
149 *Buffer = NULL;\r
150 *Size = 0;\r
151 Status = Fv->ReadSection (\r
152 Fv,\r
153 NameGuid,\r
154 EFI_SECTION_PE32,\r
ff197efb 155 SectionInstance,\r
1c280088 156 Buffer,\r
157 Size,\r
158 &AuthenticationStatus\r
159 );\r
160 }\r
161\r
1c280088 162 return Status;\r
163}\r
164\r
b0d803fe 165\r
b0d803fe 166\r
f80b0830 167/**\r
b75a165d
LG
168 Searches all the availables firmware volumes and returns the first matching FFS section. \r
169\r
170 This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid. \r
171 The order that the firmware volumes is searched is not deterministic. For each FFS file found a search \r
172 is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances \r
173 of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer. \r
174 Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size. \r
175 It is the caller's responsibility to use FreePool() to free the allocated buffer. \r
176 See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections \r
177 are retrieved from an FFS file based on SectionType and SectionInstance.\r
178\r
179 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, \r
180 the search will be retried with a section type of EFI_SECTION_PE32.\r
181 This function must be called with a TPL <= TPL_NOTIFY.\r
182\r
183 If NameGuid is NULL, then ASSERT().\r
184 If Buffer is NULL, then ASSERT().\r
ff197efb 185 If Size is NULL, then ASSERT().\r
186\r
f80b0830 187\r
b75a165d
LG
188 @param NameGuid A pointer to to the FFS filename GUID to search for within \r
189 any of the firmware volumes in the platform. \r
190 @param SectionType Indicates the FFS section type to search for within the FFS file specified by NameGuid.\r
191 @param SectionInstance Indicates which section instance within the FFS file specified by NameGuid to retrieve.\r
192 @param Buffer On output, a pointer to a callee allocated buffer containing the FFS file section that was found. \r
193 Is it the caller's respobsibility to free this buffer using FreePool().\r
194 @param Size On output, a pointer to the size, in bytes, of Buffer.\r
195\r
196 @retval EFI_SUCCESS The specified FFS section was returned.\r
197 @retval EFI_NOT_FOUND The specified FFS section could not be found.\r
198 @retval EFI_OUT_OF_RESOURCES There are not enough rsources available to retrieve the matching FFS section.\r
199 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a device error.\r
200 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the firmware volume that \r
201 contains the matching FFS section does not allow reads.\r
f80b0830 202**/\r
b0d803fe 203EFI_STATUS\r
204EFIAPI\r
eb9dd4d0 205GetSectionFromAnyFv (\r
b0d803fe 206 IN CONST EFI_GUID *NameGuid,\r
207 IN EFI_SECTION_TYPE SectionType,\r
ff197efb 208 IN UINTN SectionInstance,\r
b0d803fe 209 OUT VOID **Buffer,\r
210 OUT UINTN *Size\r
211 )\r
212{\r
213 EFI_STATUS Status;\r
214 EFI_HANDLE *HandleBuffer;\r
215 UINTN HandleCount;\r
216 UINTN Index;\r
217 EFI_HANDLE FvHandle;\r
b0d803fe 218\r
219 //\r
220 // Search the FV that contain the caller's FFS first.\r
221 // FV builder can choose to build FFS into the this FV\r
222 // so that this implementation of GetSectionFromAnyFv\r
223 // will locate the FFS faster.\r
224 //\r
166152e8 225 FvHandle = InternalImageHandleToFvHandle (gImageHandle);\r
eb9dd4d0 226 Status = InternalGetSectionFromFv (\r
b0d803fe 227 FvHandle,\r
228 NameGuid,\r
229 SectionType,\r
ff197efb 230 SectionInstance,\r
b0d803fe 231 Buffer,\r
232 Size\r
233 );\r
234 if (!EFI_ERROR (Status)) {\r
235 return EFI_SUCCESS;\r
236 }\r
237\r
b0d803fe 238 HandleBuffer = NULL;\r
239 Status = gBS->LocateHandleBuffer (\r
240 ByProtocol,\r
241 &gEfiFirmwareVolume2ProtocolGuid,\r
242 NULL,\r
243 &HandleCount,\r
244 &HandleBuffer\r
245 );\r
246 if (EFI_ERROR (Status)) {\r
247 goto Done;\r
248 }\r
249\r
ff197efb 250 for (Index = 0; Index < HandleCount; Index++) {\r
b0d803fe 251 //\r
252 // Skip the FV that contain the caller's FFS\r
253 //\r
ff197efb 254 if (HandleBuffer[Index] != FvHandle) {\r
eb9dd4d0 255 Status = InternalGetSectionFromFv (\r
ff197efb 256 HandleBuffer[Index], \r
257 NameGuid, \r
258 SectionType, \r
259 SectionInstance,\r
260 Buffer, \r
261 Size\r
262 );\r
263\r
264 if (!EFI_ERROR (Status)) {\r
265 goto Done;\r
266 }\r
b0d803fe 267 }\r
268\r
b0d803fe 269 }\r
270\r
271 if (Index == HandleCount) {\r
272 Status = EFI_NOT_FOUND;\r
273 }\r
274\r
275Done:\r
276 \r
b0d803fe 277 if (HandleBuffer != NULL) { \r
278 FreePool(HandleBuffer);\r
279 }\r
280 return Status;\r
281 \r
282}\r
283\r
f80b0830 284/**\r
b75a165d
LG
285 Searches the firmware volume that the currently executing module was loaded from and returns the first matching FFS section. \r
286\r
287 This function searches the firmware volume that the currently executing module was loaded \r
288 from for an FFS file with an FFS filename specified by NameGuid. If the FFS file is found a search \r
289 is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance \r
290 instances of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.\r
291 Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size. \r
292 It is the caller's responsibility to use FreePool() to free the allocated buffer. \r
293 See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from \r
294 an FFS file based on SectionType and SectionInstance.\r
295\r
296 If the currently executing module was not loaded from a firmware volume, then EFI_NOT_FOUND is returned.\r
297 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, \r
298 the search will be retried with a section type of EFI_SECTION_PE32.\r
299 \r
300 This function must be called with a TPL <= TPL_NOTIFY.\r
301 If NameGuid is NULL, then ASSERT().\r
302 If Buffer is NULL, then ASSERT().\r
ff197efb 303 If Size is NULL, then ASSERT().\r
304\r
b75a165d
LG
305 @param NameGuid A pointer to to the FFS filename GUID to search for within \r
306 the firmware volumes that the currently executing module was loaded from.\r
307 @param SectionType Indicates the FFS section type to search for within the FFS file specified by NameGuid.\r
308 @param SectionInstance Indicates which section instance within the FFS file specified by NameGuid to retrieve.\r
309 @param Buffer On output, a pointer to a callee allocated buffer containing the FFS file section that was found. \r
310 Is it the caller's respobsibility to free this buffer using FreePool().\r
311 @param Size On output, a pointer to the size, in bytes, of Buffer.\r
312\r
313\r
314 @retval EFI_SUCCESS The specified FFS section was returned.\r
315 @retval EFI_NOT_FOUND The specified FFS section could not be found.\r
316 @retval EFI_OUT_OF_RESOURCES There are not enough rsources available to retrieve the matching FFS section.\r
317 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a device error.\r
318 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the firmware volume that \r
319 contains the matching FFS section does not allow reads. \r
f80b0830 320**/\r
b0d803fe 321EFI_STATUS\r
322EFIAPI\r
eb9dd4d0 323GetSectionFromFv (\r
b0d803fe 324 IN CONST EFI_GUID *NameGuid,\r
325 IN EFI_SECTION_TYPE SectionType,\r
ff197efb 326 IN UINTN SectionInstance,\r
b0d803fe 327 OUT VOID **Buffer,\r
328 OUT UINTN *Size\r
329 )\r
330{\r
eb9dd4d0 331 return InternalGetSectionFromFv (\r
332 InternalImageHandleToFvHandle(gImageHandle),\r
333 NameGuid,\r
334 SectionType,\r
335 SectionInstance,\r
336 Buffer,\r
337 Size\r
338 );\r
b0d803fe 339}\r
340\r
341\r
f80b0830 342/**\r
b75a165d
LG
343 Searches the FFS file the the currently executing module was loaded from and returns the first matching FFS section.\r
344\r
345 This function searches the FFS file that the currently executing module was loaded from for a FFS sections of type SectionType.\r
346 If the FFS file contains at least SectionInstance instances of the FFS section specified by SectionType, \r
347 then the SectionInstance instance is returned in Buffer. Buffer is allocated using AllocatePool(), \r
348 and the size of the allocated buffer is returned in Size. It is the caller's responsibility \r
349 to use FreePool() to free the allocated buffer. See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for \r
350 details on how sections are retrieved from an FFS file based on SectionType and SectionInstance.\r
351\r
352 If the currently executing module was not loaded from an FFS file, then EFI_NOT_FOUND is returned.\r
353 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, \r
354 the search will be retried with a section type of EFI_SECTION_PE32.\r
355 This function must be called with a TPL <= TPL_NOTIFY.\r
356 \r
357 If Buffer is NULL, then ASSERT().\r
ff197efb 358 If Size is NULL, then ASSERT().\r
359\r
b75a165d
LG
360\r
361 @param SectionType Indicates the FFS section type to search for within the FFS file \r
362 that the currently executing module was loaded from.\r
363 @param SectionInstance Indicates which section instance to retrieve within the FFS file \r
364 that the currently executing module was loaded from.\r
365 @param Buffer On output, a pointer to a callee allocated buffer containing the FFS file section that was found. \r
366 Is it the caller's respobsibility to free this buffer using FreePool().\r
367 @param Size On output, a pointer to the size, in bytes, of Buffer.\r
368\r
369 @retval EFI_SUCCESS The specified FFS section was returned.\r
370 @retval EFI_NOT_FOUND The specified FFS section could not be found.\r
371 @retval EFI_OUT_OF_RESOURCES There are not enough rsources available to retrieve the matching FFS section.\r
372 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a device error.\r
373 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the firmware volume that \r
374 contains the matching FFS section does not allow reads. \r
f80b0830 375 \r
376**/\r
b0d803fe 377EFI_STATUS\r
378EFIAPI\r
eb9dd4d0 379GetSectionFromFfs (\r
b0d803fe 380 IN EFI_SECTION_TYPE SectionType,\r
ff197efb 381 IN UINTN SectionInstance,\r
b0d803fe 382 OUT VOID **Buffer,\r
383 OUT UINTN *Size\r
384 )\r
385{\r
eb9dd4d0 386 return InternalGetSectionFromFv(\r
387 InternalImageHandleToFvHandle(gImageHandle),\r
388 &gEfiCallerIdGuid,\r
389 SectionType,\r
390 SectionInstance,\r
391 Buffer,\r
392 Size\r
393 );\r
b0d803fe 394}\r
395\r