]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BmLib.c
e5d96407f179eed956cc1326f7c45bead5687718
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BmLib.c
1 /** @file
2 Utility routines used by boot maintenance modules.
3
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "BootMaint.h"
10
11 /**
12
13 Function opens and returns a file handle to the root directory of a volume.
14
15 @param DeviceHandle A handle for a device
16
17 @return A valid file handle or NULL is returned
18
19 **/
20 EFI_FILE_HANDLE
21 EfiLibOpenRoot (
22 IN EFI_HANDLE DeviceHandle
23 )
24 {
25 EFI_STATUS Status;
26 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
27 EFI_FILE_HANDLE File;
28
29 File = NULL;
30
31 //
32 // File the file system interface to the device
33 //
34 Status = gBS->HandleProtocol (
35 DeviceHandle,
36 &gEfiSimpleFileSystemProtocolGuid,
37 (VOID *) &Volume
38 );
39
40 //
41 // Open the root directory of the volume
42 //
43 if (!EFI_ERROR (Status)) {
44 Status = Volume->OpenVolume (
45 Volume,
46 &File
47 );
48 }
49 //
50 // Done
51 //
52 return EFI_ERROR (Status) ? NULL : File;
53 }
54
55 /**
56
57 Helper function called as part of the code needed
58 to allocate the proper sized buffer for various
59 EFI interfaces.
60
61
62 @param Status Current status
63 @param Buffer Current allocated buffer, or NULL
64 @param BufferSize Current buffer size needed
65
66 @retval TRUE if the buffer was reallocated and the caller
67 should try the API again.
68 @retval FALSE The caller should not call this function again.
69
70 **/
71 BOOLEAN
72 EfiGrowBuffer (
73 IN OUT EFI_STATUS *Status,
74 IN OUT VOID **Buffer,
75 IN UINTN BufferSize
76 )
77 {
78 BOOLEAN TryAgain;
79
80 //
81 // If this is an initial request, buffer will be null with a new buffer size
82 //
83 if ((*Buffer == NULL) && (BufferSize != 0)) {
84 *Status = EFI_BUFFER_TOO_SMALL;
85 }
86 //
87 // If the status code is "buffer too small", resize the buffer
88 //
89 TryAgain = FALSE;
90 if (*Status == EFI_BUFFER_TOO_SMALL) {
91
92 if (*Buffer != NULL) {
93 FreePool (*Buffer);
94 }
95
96 *Buffer = AllocateZeroPool (BufferSize);
97
98 if (*Buffer != NULL) {
99 TryAgain = TRUE;
100 } else {
101 *Status = EFI_OUT_OF_RESOURCES;
102 }
103 }
104 //
105 // If there's an error, free the buffer
106 //
107 if (!TryAgain && EFI_ERROR (*Status) && (*Buffer != NULL)) {
108 FreePool (*Buffer);
109 *Buffer = NULL;
110 }
111
112 return TryAgain;
113 }
114
115 /**
116 Function returns the value of the specified variable.
117
118
119 @param Name A Null-terminated Unicode string that is
120 the name of the vendor's variable.
121 @param VendorGuid A unique identifier for the vendor.
122
123 @return The payload of the variable.
124 @retval NULL If the variable can't be read.
125
126 **/
127 VOID *
128 EfiLibGetVariable (
129 IN CHAR16 *Name,
130 IN EFI_GUID *VendorGuid
131 )
132 {
133 UINTN VarSize;
134
135 return BdsLibGetVariableAndSize (Name, VendorGuid, &VarSize);
136 }
137
138 /**
139 Function deletes the variable specified by VarName and VarGuid.
140
141 @param VarName A Null-terminated Unicode string that is
142 the name of the vendor's variable.
143
144 @param VarGuid A unique identifier for the vendor.
145
146 @retval EFI_SUCCESS The variable was found and removed
147 @retval EFI_UNSUPPORTED The variable store was inaccessible
148 @retval EFI_OUT_OF_RESOURCES The temporary buffer was not available
149 @retval EFI_NOT_FOUND The variable was not found
150
151 **/
152 EFI_STATUS
153 EfiLibDeleteVariable (
154 IN CHAR16 *VarName,
155 IN EFI_GUID *VarGuid
156 )
157 {
158 VOID *VarBuf;
159 EFI_STATUS Status;
160
161 VarBuf = EfiLibGetVariable (VarName, VarGuid);
162 Status = EFI_NOT_FOUND;
163
164 if (VarBuf != NULL) {
165 //
166 // Delete variable from Storage
167 //
168 Status = gRT->SetVariable (
169 VarName,
170 VarGuid,
171 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
172 0,
173 NULL
174 );
175 //
176 // Deleting variable with current variable implementation shouldn't fail.
177 //
178 ASSERT_EFI_ERROR (Status);
179 FreePool (VarBuf);
180 }
181
182 return Status;
183 }
184
185 /**
186
187 Function gets the file system information from an open file descriptor,
188 and stores it in a buffer allocated from pool.
189
190
191 @param FHand The file handle.
192
193 @return A pointer to a buffer with file information.
194 @retval NULL is returned if failed to get Vaolume Label Info.
195
196 **/
197 EFI_FILE_SYSTEM_VOLUME_LABEL *
198 EfiLibFileSystemVolumeLabelInfo (
199 IN EFI_FILE_HANDLE FHand
200 )
201 {
202 EFI_STATUS Status;
203 EFI_FILE_SYSTEM_VOLUME_LABEL *Buffer;
204 UINTN BufferSize;
205 //
206 // Initialize for GrowBuffer loop
207 //
208 Buffer = NULL;
209 BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL + 200;
210
211 //
212 // Call the real function
213 //
214 while (EfiGrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
215 Status = FHand->GetInfo (
216 FHand,
217 &gEfiFileSystemVolumeLabelInfoIdGuid,
218 &BufferSize,
219 Buffer
220 );
221 }
222
223 return Buffer;
224 }
225
226 /**
227 Duplicate a string.
228
229 @param Src The source.
230
231 @return A new string which is duplicated copy of the source.
232 @retval NULL If there is not enough memory.
233
234 **/
235 CHAR16 *
236 EfiStrDuplicate (
237 IN CHAR16 *Src
238 )
239 {
240 CHAR16 *Dest;
241 UINTN Size;
242
243 Size = StrSize (Src);
244 Dest = AllocateZeroPool (Size);
245 ASSERT (Dest != NULL);
246 if (Dest != NULL) {
247 CopyMem (Dest, Src, Size);
248 }
249
250 return Dest;
251 }
252
253 /**
254
255 Function gets the file information from an open file descriptor, and stores it
256 in a buffer allocated from pool.
257
258 @param FHand File Handle.
259
260 @return A pointer to a buffer with file information or NULL is returned
261
262 **/
263 EFI_FILE_INFO *
264 EfiLibFileInfo (
265 IN EFI_FILE_HANDLE FHand
266 )
267 {
268 EFI_STATUS Status;
269 EFI_FILE_INFO *Buffer;
270 UINTN BufferSize;
271
272 //
273 // Initialize for GrowBuffer loop
274 //
275 Buffer = NULL;
276 BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
277
278 //
279 // Call the real function
280 //
281 while (EfiGrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
282 Status = FHand->GetInfo (
283 FHand,
284 &gEfiFileInfoGuid,
285 &BufferSize,
286 Buffer
287 );
288 }
289
290 return Buffer;
291 }
292
293 /**
294 Function is used to determine the number of device path instances
295 that exist in a device path.
296
297
298 @param DevicePath A pointer to a device path data structure.
299
300 @return This function counts and returns the number of device path instances
301 in DevicePath.
302
303 **/
304 UINTN
305 EfiDevicePathInstanceCount (
306 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
307 )
308 {
309 UINTN Count;
310 UINTN Size;
311
312 Count = 0;
313 while (GetNextDevicePathInstance (&DevicePath, &Size) != NULL) {
314 Count += 1;
315 }
316
317 return Count;
318 }
319
320
321 /**
322 Get a string from the Data Hub record based on
323 a device path.
324
325 @param DevPath The device Path.
326
327 @return A string located from the Data Hub records based on
328 the device path.
329 @retval NULL If failed to get the String from Data Hub.
330
331 **/
332 UINT16 *
333 EfiLibStrFromDatahub (
334 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
335 )
336 {
337 return NULL;
338 }
339
340 /**
341
342 Find the first instance of this Protocol
343 in the system and return it's interface.
344
345
346 @param ProtocolGuid Provides the protocol to search for
347 @param Interface On return, a pointer to the first interface
348 that matches ProtocolGuid
349
350 @retval EFI_SUCCESS A protocol instance matching ProtocolGuid was found
351 @retval EFI_NOT_FOUND No protocol instances were found that match ProtocolGuid
352
353 **/
354 EFI_STATUS
355 EfiLibLocateProtocol (
356 IN EFI_GUID *ProtocolGuid,
357 OUT VOID **Interface
358 )
359 {
360 EFI_STATUS Status;
361
362 Status = gBS->LocateProtocol (
363 ProtocolGuid,
364 NULL,
365 (VOID **) Interface
366 );
367 return Status;
368 }
369