]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/DxeServicesLib/DxeServicesLib.c
Fix unicode issue.
[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
b75a165d
LG
94 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.\r
95 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.\r
96 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.\r
97 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.\r
166152e8 98 \r
f80b0830 99**/\r
1c280088 100EFI_STATUS\r
eb9dd4d0 101InternalGetSectionFromFv (\r
166152e8 102 IN EFI_HANDLE FvHandle,\r
103 IN CONST EFI_GUID *NameGuid,\r
104 IN EFI_SECTION_TYPE SectionType,\r
ff197efb 105 IN UINTN SectionInstance,\r
166152e8 106 OUT VOID **Buffer,\r
107 OUT UINTN *Size\r
1c280088 108 )\r
109{\r
166152e8 110 EFI_STATUS Status;\r
111 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
112 UINT32 AuthenticationStatus;\r
113\r
8cf43dd7 114 ASSERT (NameGuid != NULL);\r
115 ASSERT (Buffer != NULL);\r
116 ASSERT (Size != NULL);\r
117 \r
166152e8 118 ASSERT (FvHandle != NULL);\r
119\r
120 Status = gBS->HandleProtocol (\r
121 FvHandle,\r
122 &gEfiFirmwareVolume2ProtocolGuid,\r
123 (VOID **) &Fv\r
124 );\r
125 if (EFI_ERROR (Status)) {\r
7ca066f9 126 return EFI_NOT_FOUND;\r
166152e8 127 }\r
1c280088 128\r
129 //\r
130 // Read desired section content in NameGuid file\r
131 //\r
132 *Buffer = NULL;\r
133 *Size = 0;\r
134 Status = Fv->ReadSection (\r
135 Fv,\r
136 NameGuid,\r
137 SectionType,\r
ff197efb 138 SectionInstance,\r
1c280088 139 Buffer,\r
140 Size,\r
141 &AuthenticationStatus\r
142 );\r
143\r
144 if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {\r
145 //\r
166152e8 146 // Try reading PE32 section, if the required section is TE type \r
1c280088 147 //\r
148 *Buffer = NULL;\r
149 *Size = 0;\r
150 Status = Fv->ReadSection (\r
151 Fv,\r
152 NameGuid,\r
153 EFI_SECTION_PE32,\r
ff197efb 154 SectionInstance,\r
1c280088 155 Buffer,\r
156 Size,\r
157 &AuthenticationStatus\r
158 );\r
159 }\r
160\r
1c280088 161 return Status;\r
162}\r
163\r
b0d803fe 164\r
b0d803fe 165\r
f80b0830 166/**\r
b75a165d
LG
167 Searches all the availables firmware volumes and returns the first matching FFS section. \r
168\r
169 This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid. \r
170 The order that the firmware volumes is searched is not deterministic. For each FFS file found a search \r
171 is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances \r
172 of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer. \r
173 Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size. \r
174 It is the caller's responsibility to use FreePool() to free the allocated buffer. \r
175 See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections \r
176 are retrieved from an FFS file based on SectionType and SectionInstance.\r
177\r
178 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, \r
179 the search will be retried with a section type of EFI_SECTION_PE32.\r
180 This function must be called with a TPL <= TPL_NOTIFY.\r
181\r
182 If NameGuid is NULL, then ASSERT().\r
183 If Buffer is NULL, then ASSERT().\r
ff197efb 184 If Size is NULL, then ASSERT().\r
185\r
f80b0830 186\r
b75a165d
LG
187 @param NameGuid A pointer to to the FFS filename GUID to search for within \r
188 any of the firmware volumes in the platform. \r
189 @param SectionType Indicates the FFS section type to search for within the FFS file specified by NameGuid.\r
190 @param SectionInstance Indicates which section instance within the FFS file specified by NameGuid to retrieve.\r
191 @param Buffer On output, a pointer to a callee allocated buffer containing the FFS file section that was found. \r
3e5c3238 192 Is it the caller's responsibility to free this buffer using FreePool().\r
b75a165d
LG
193 @param Size On output, a pointer to the size, in bytes, of Buffer.\r
194\r
195 @retval EFI_SUCCESS The specified FFS section was returned.\r
196 @retval EFI_NOT_FOUND The specified FFS section could not be found.\r
3e5c3238 197 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve the matching FFS section.\r
b75a165d
LG
198 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a device error.\r
199 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the firmware volume that \r
200 contains the matching FFS section does not allow reads.\r
f80b0830 201**/\r
b0d803fe 202EFI_STATUS\r
203EFIAPI\r
eb9dd4d0 204GetSectionFromAnyFv (\r
b0d803fe 205 IN CONST EFI_GUID *NameGuid,\r
206 IN EFI_SECTION_TYPE SectionType,\r
ff197efb 207 IN UINTN SectionInstance,\r
b0d803fe 208 OUT VOID **Buffer,\r
209 OUT UINTN *Size\r
210 )\r
211{\r
212 EFI_STATUS Status;\r
213 EFI_HANDLE *HandleBuffer;\r
214 UINTN HandleCount;\r
215 UINTN Index;\r
216 EFI_HANDLE FvHandle;\r
b0d803fe 217\r
218 //\r
219 // Search the FV that contain the caller's FFS first.\r
220 // FV builder can choose to build FFS into the this FV\r
221 // so that this implementation of GetSectionFromAnyFv\r
222 // will locate the FFS faster.\r
223 //\r
166152e8 224 FvHandle = InternalImageHandleToFvHandle (gImageHandle);\r
eb9dd4d0 225 Status = InternalGetSectionFromFv (\r
b0d803fe 226 FvHandle,\r
227 NameGuid,\r
228 SectionType,\r
ff197efb 229 SectionInstance,\r
b0d803fe 230 Buffer,\r
231 Size\r
232 );\r
233 if (!EFI_ERROR (Status)) {\r
234 return EFI_SUCCESS;\r
235 }\r
236\r
b0d803fe 237 HandleBuffer = NULL;\r
238 Status = gBS->LocateHandleBuffer (\r
239 ByProtocol,\r
240 &gEfiFirmwareVolume2ProtocolGuid,\r
241 NULL,\r
242 &HandleCount,\r
243 &HandleBuffer\r
244 );\r
245 if (EFI_ERROR (Status)) {\r
246 goto Done;\r
247 }\r
248\r
ff197efb 249 for (Index = 0; Index < HandleCount; Index++) {\r
b0d803fe 250 //\r
251 // Skip the FV that contain the caller's FFS\r
252 //\r
ff197efb 253 if (HandleBuffer[Index] != FvHandle) {\r
eb9dd4d0 254 Status = InternalGetSectionFromFv (\r
ff197efb 255 HandleBuffer[Index], \r
256 NameGuid, \r
257 SectionType, \r
258 SectionInstance,\r
259 Buffer, \r
260 Size\r
261 );\r
262\r
263 if (!EFI_ERROR (Status)) {\r
264 goto Done;\r
265 }\r
b0d803fe 266 }\r
267\r
b0d803fe 268 }\r
269\r
270 if (Index == HandleCount) {\r
271 Status = EFI_NOT_FOUND;\r
272 }\r
273\r
274Done:\r
275 \r
b0d803fe 276 if (HandleBuffer != NULL) { \r
277 FreePool(HandleBuffer);\r
278 }\r
279 return Status;\r
280 \r
281}\r
282\r
f80b0830 283/**\r
b75a165d
LG
284 Searches the firmware volume that the currently executing module was loaded from and returns the first matching FFS section. \r
285\r
286 This function searches the firmware volume that the currently executing module was loaded \r
287 from for an FFS file with an FFS filename specified by NameGuid. If the FFS file is found a search \r
288 is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance \r
289 instances of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.\r
290 Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size. \r
291 It is the caller's responsibility to use FreePool() to free the allocated buffer. \r
292 See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from \r
293 an FFS file based on SectionType and SectionInstance.\r
294\r
295 If the currently executing module was not loaded from a firmware volume, then EFI_NOT_FOUND is returned.\r
296 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, \r
297 the search will be retried with a section type of EFI_SECTION_PE32.\r
298 \r
299 This function must be called with a TPL <= TPL_NOTIFY.\r
300 If NameGuid is NULL, then ASSERT().\r
301 If Buffer is NULL, then ASSERT().\r
ff197efb 302 If Size is NULL, then ASSERT().\r
303\r
b75a165d
LG
304 @param NameGuid A pointer to to the FFS filename GUID to search for within \r
305 the firmware volumes that the currently executing module was loaded from.\r
306 @param SectionType Indicates the FFS section type to search for within the FFS file specified by NameGuid.\r
307 @param SectionInstance Indicates which section instance within the FFS file specified by NameGuid to retrieve.\r
308 @param Buffer On output, a pointer to a callee allocated buffer containing the FFS file section that was found. \r
3e5c3238 309 Is it the caller's responsibility to free this buffer using FreePool().\r
b75a165d
LG
310 @param Size On output, a pointer to the size, in bytes, of Buffer.\r
311\r
312\r
313 @retval EFI_SUCCESS The specified FFS section was returned.\r
314 @retval EFI_NOT_FOUND The specified FFS section could not be found.\r
3e5c3238 315 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve the matching FFS section.\r
b75a165d
LG
316 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a device error.\r
317 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the firmware volume that \r
318 contains the matching FFS section does not allow reads. \r
f80b0830 319**/\r
b0d803fe 320EFI_STATUS\r
321EFIAPI\r
eb9dd4d0 322GetSectionFromFv (\r
b0d803fe 323 IN CONST EFI_GUID *NameGuid,\r
324 IN EFI_SECTION_TYPE SectionType,\r
ff197efb 325 IN UINTN SectionInstance,\r
b0d803fe 326 OUT VOID **Buffer,\r
327 OUT UINTN *Size\r
328 )\r
329{\r
eb9dd4d0 330 return InternalGetSectionFromFv (\r
331 InternalImageHandleToFvHandle(gImageHandle),\r
332 NameGuid,\r
333 SectionType,\r
334 SectionInstance,\r
335 Buffer,\r
336 Size\r
337 );\r
b0d803fe 338}\r
339\r
340\r
f80b0830 341/**\r
b75a165d
LG
342 Searches the FFS file the the currently executing module was loaded from and returns the first matching FFS section.\r
343\r
344 This function searches the FFS file that the currently executing module was loaded from for a FFS sections of type SectionType.\r
345 If the FFS file contains at least SectionInstance instances of the FFS section specified by SectionType, \r
346 then the SectionInstance instance is returned in Buffer. Buffer is allocated using AllocatePool(), \r
347 and the size of the allocated buffer is returned in Size. It is the caller's responsibility \r
348 to use FreePool() to free the allocated buffer. See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for \r
349 details on how sections are retrieved from an FFS file based on SectionType and SectionInstance.\r
350\r
351 If the currently executing module was not loaded from an FFS file, then EFI_NOT_FOUND is returned.\r
352 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, \r
353 the search will be retried with a section type of EFI_SECTION_PE32.\r
354 This function must be called with a TPL <= TPL_NOTIFY.\r
355 \r
356 If Buffer is NULL, then ASSERT().\r
ff197efb 357 If Size is NULL, then ASSERT().\r
358\r
b75a165d
LG
359\r
360 @param SectionType Indicates the FFS section type to search for within the FFS file \r
361 that the currently executing module was loaded from.\r
362 @param SectionInstance Indicates which section instance to retrieve within the FFS file \r
363 that the currently executing module was loaded from.\r
364 @param Buffer On output, a pointer to a callee allocated buffer containing the FFS file section that was found. \r
3e5c3238 365 Is it the caller's responsibility to free this buffer using FreePool().\r
b75a165d
LG
366 @param Size On output, a pointer to the size, in bytes, of Buffer.\r
367\r
368 @retval EFI_SUCCESS The specified FFS section was returned.\r
369 @retval EFI_NOT_FOUND The specified FFS section could not be found.\r
3e5c3238 370 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve the matching FFS section.\r
b75a165d
LG
371 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a device error.\r
372 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the firmware volume that \r
373 contains the matching FFS section does not allow reads. \r
f80b0830 374 \r
375**/\r
b0d803fe 376EFI_STATUS\r
377EFIAPI\r
eb9dd4d0 378GetSectionFromFfs (\r
b0d803fe 379 IN EFI_SECTION_TYPE SectionType,\r
ff197efb 380 IN UINTN SectionInstance,\r
b0d803fe 381 OUT VOID **Buffer,\r
382 OUT UINTN *Size\r
383 )\r
384{\r
eb9dd4d0 385 return InternalGetSectionFromFv(\r
386 InternalImageHandleToFvHandle(gImageHandle),\r
387 &gEfiCallerIdGuid,\r
388 SectionType,\r
389 SectionInstance,\r
390 Buffer,\r
391 Size\r
392 );\r
b0d803fe 393}\r
394\r