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