2 Utility routines used by boot maintenance modules.
4 Copyright (c) 2004 - 2008, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BootMaint.h"
18 Wrap original AllocatePool gBS call
19 and ZeroMem gBS call into a single
20 function in order to decrease code length
23 @param Size The size to allocate
25 @return Valid pointer to the allocated buffer
26 @retval Null for failure
36 Status
= gBS
->AllocatePool (EfiBootServicesData
, Size
, &Ptr
);
37 if (EFI_ERROR (Status
)) {
48 Find the first instance of this Protocol
49 in the system and return it's interface
52 @param ProtocolGuid - Provides the protocol to search for
53 @param Interface - On return, a pointer to the first interface
54 that matches ProtocolGuid
56 @retval EFI_SUCCESS A protocol instance matching ProtocolGuid was found
57 @retval EFI_NOT_FOUND No protocol instances were found that match ProtocolGuid
61 EfiLibLocateProtocol (
62 IN EFI_GUID
*ProtocolGuid
,
68 Status
= gBS
->LocateProtocol (
78 Function opens and returns a file handle to the root directory of a volume.
81 @param DeviceHandle - A handle for a device
83 @return A valid file handle or NULL is returned
88 IN EFI_HANDLE DeviceHandle
92 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
98 // File the file system interface to the device
100 Status
= gBS
->HandleProtocol (
102 &gEfiSimpleFileSystemProtocolGuid
,
107 // Open the root directory of the volume
109 if (!EFI_ERROR (Status
)) {
110 Status
= Volume
->OpenVolume (
118 return EFI_ERROR (Status
) ? NULL
: File
;
123 Helper function called as part of the code needed
124 to allocate the proper sized buffer for various
128 @param Status - Current status
129 @param Buffer - Current allocated buffer, or NULL
130 @param BufferSize - Current buffer size needed
132 @retval TRUE if the buffer was reallocated and the caller
133 should try the API again.
138 IN OUT EFI_STATUS
*Status
,
139 IN OUT VOID
**Buffer
,
146 // If this is an initial request, buffer will be null with a new buffer size
148 if ((*Buffer
== NULL
) && (BufferSize
!= 0)) {
149 *Status
= EFI_BUFFER_TOO_SMALL
;
152 // If the status code is "buffer too small", resize the buffer
155 if (*Status
== EFI_BUFFER_TOO_SMALL
) {
157 SafeFreePool (*Buffer
);
159 *Buffer
= EfiAllocateZeroPool (BufferSize
);
161 if (*Buffer
!= NULL
) {
164 *Status
= EFI_OUT_OF_RESOURCES
;
168 // If there's an error, free the buffer
170 if (!TryAgain
&& EFI_ERROR (*Status
) && (*Buffer
!= NULL
)) {
171 SafeFreePool (*Buffer
);
179 Function returns the value of the specified variable.
182 @param Name - A Null-terminated Unicode string that is
183 the name of the vendor's variable.
184 @param VendorGuid - A unique identifier for the vendor.
186 @return The payload of the variable.
192 IN EFI_GUID
*VendorGuid
197 return BdsLibGetVariableAndSize (Name
, VendorGuid
, &VarSize
);
201 Function deletes the variable specified by VarName and VarGuid.
204 @param VarName - A Null-terminated Unicode string that is
205 the name of the vendor's variable.
207 @param VendorGuid - A unique identifier for the vendor.
209 @retval EFI_SUCCESS The variable was found and removed
210 @retval EFI_UNSUPPORTED The variable store was inaccessible
211 @retval EFI_OUT_OF_RESOURCES The temporary buffer was not available
212 @retval EFI_NOT_FOUND The variable was not found
216 EfiLibDeleteVariable (
224 VarBuf
= EfiLibGetVariable (VarName
, VarGuid
);
225 Status
= EFI_NOT_FOUND
;
227 if (VarBuf
!= NULL
) {
229 // Delete variable from Storage
231 Status
= gRT
->SetVariable (VarName
, VarGuid
, VAR_FLAG
, 0, NULL
);
232 ASSERT (!EFI_ERROR (Status
));
233 SafeFreePool (VarBuf
);
241 Function gets the file system information from an open file descriptor,
242 and stores it in a buffer allocated from pool.
245 @param FHand The file handle.
247 @return A pointer to a buffer with file information or NULL is returned
250 EFI_FILE_SYSTEM_VOLUME_LABEL_INFO
*
251 EfiLibFileSystemVolumeLabelInfo (
252 IN EFI_FILE_HANDLE FHand
256 EFI_FILE_SYSTEM_VOLUME_LABEL_INFO
*Buffer
;
259 // Initialize for GrowBuffer loop
262 BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO
+ 200;
265 // Call the real function
267 while (EfiGrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
268 Status
= FHand
->GetInfo (
270 &gEfiFileSystemVolumeLabelInfoIdGuid
,
282 @param Src The source.
284 @return A new string which is duplicated copy of the source.
285 @retval NULL If there is not enought memory.
296 Size
= StrSize (Src
);
297 Dest
= EfiAllocateZeroPool (Size
);
298 ASSERT (Dest
!= NULL
);
300 CopyMem (Dest
, Src
, Size
);
308 Function gets the file information from an open file descriptor, and stores it
309 in a buffer allocated from pool.
311 @param FHand File Handle.
313 @return A pointer to a buffer with file information or NULL is returned
318 IN EFI_FILE_HANDLE FHand
322 EFI_FILE_INFO
*Buffer
;
326 // Initialize for GrowBuffer loop
329 BufferSize
= SIZE_OF_EFI_FILE_INFO
+ 200;
332 // Call the real function
334 while (EfiGrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
335 Status
= FHand
->GetInfo (
347 Function is used to determine the number of device path instances
348 that exist in a device path.
351 @param DevicePath - A pointer to a device path data structure.
353 @return This function counts and returns the number of device path instances
358 EfiDevicePathInstanceCount (
359 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
366 while (GetNextDevicePathInstance (&DevicePath
, &Size
)) {
374 Adjusts the size of a previously allocated buffer.
377 @param OldPool - A pointer to the buffer whose size is being adjusted.
378 @param OldSize - The size of the current buffer.
379 @param NewSize - The size of the new buffer.
381 @retval EFI_SUCEESS The requested number of bytes were allocated.
382 @retval EFI_OUT_OF_RESOURCES The pool requested could not be allocated.
383 @retval EFI_INVALID_PARAMETER The buffer was invalid.
397 NewPool
= EfiAllocateZeroPool (NewSize
);
400 if (OldPool
!= NULL
) {
401 if (NewPool
!= NULL
) {
402 CopyMem (NewPool
, OldPool
, OldSize
< NewSize
? OldSize
: NewSize
);
405 SafeFreePool (OldPool
);
412 Compare two EFI_TIME data.
415 @param FirstTime - A pointer to the first EFI_TIME data.
416 @param SecondTime - A pointer to the second EFI_TIME data.
418 @retval TRUE The FirstTime is not later than the SecondTime.
419 @retval FALSE The FirstTime is later than the SecondTime.
424 IN EFI_TIME
*FirstTime
,
425 IN EFI_TIME
*SecondTime
428 if (FirstTime
->Year
!= SecondTime
->Year
) {
429 return (BOOLEAN
) (FirstTime
->Year
< SecondTime
->Year
);
430 } else if (FirstTime
->Month
!= SecondTime
->Month
) {
431 return (BOOLEAN
) (FirstTime
->Month
< SecondTime
->Month
);
432 } else if (FirstTime
->Day
!= SecondTime
->Day
) {
433 return (BOOLEAN
) (FirstTime
->Day
< SecondTime
->Day
);
434 } else if (FirstTime
->Hour
!= SecondTime
->Hour
) {
435 return (BOOLEAN
) (FirstTime
->Hour
< SecondTime
->Hour
);
436 } else if (FirstTime
->Minute
!= SecondTime
->Minute
) {
437 return (BOOLEAN
) (FirstTime
->Minute
< FirstTime
->Minute
);
438 } else if (FirstTime
->Second
!= SecondTime
->Second
) {
439 return (BOOLEAN
) (FirstTime
->Second
< SecondTime
->Second
);
442 return (BOOLEAN
) (FirstTime
->Nanosecond
<= SecondTime
->Nanosecond
);
446 Get a string from the Data Hub record based on
449 @param DevPath The device Path.
451 @return A string located from the Data Hub records based on
456 EfiLibStrFromDatahub (
457 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
462 EFI_DATA_HUB_PROTOCOL
*Datahub
;
464 EFI_DATA_RECORD_HEADER
*Record
;
465 EFI_SUBCLASS_TYPE1_HEADER
*DataHdr
;
466 EFI_GUID MiscGuid
= EFI_MISC_SUBCLASS_GUID
;
467 EFI_MISC_ONBOARD_DEVICE_DATA
*ob
;
468 EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA
*Port
;
471 Status
= gBS
->LocateProtocol (
472 &gEfiDataHubProtocolGuid
,
476 if (EFI_ERROR (Status
)) {
480 Status
= gRT
->GetTime (&CurTime
, NULL
);
481 if (EFI_ERROR (Status
)) {
487 Status
= Datahub
->GetNextRecord (Datahub
, &Count
, NULL
, &Record
);
489 if (EFI_ERROR (Status
)) {
493 if (Record
->DataRecordClass
== EFI_DATA_RECORD_CLASS_DATA
&& CompareGuid (&Record
->DataRecordGuid
, &MiscGuid
)) {
495 // This record is what we need
497 DataHdr
= (EFI_SUBCLASS_TYPE1_HEADER
*) (Record
+ 1);
498 if (EFI_MISC_ONBOARD_DEVICE_RECORD_NUMBER
== DataHdr
->RecordType
) {
499 ob
= (EFI_MISC_ONBOARD_DEVICE_DATA
*) (DataHdr
+ 1);
500 if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL
*) &ob
->OnBoardDevicePath
, DevPath
)) {
501 GetProducerString (&Record
->ProducerName
, ob
->OnBoardDeviceDescription
, &Desc
);
506 if (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_RECORD_NUMBER
== DataHdr
->RecordType
) {
507 Port
= (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA
*) (DataHdr
+ 1);
508 if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL
*) &Port
->PortPath
, DevPath
)) {
509 GetProducerString (&Record
->ProducerName
, Port
->PortExternalConnectorDesignator
, &Desc
);
515 } while (TimeCompare (&Record
->LogTime
, &CurTime
) && Count
!= 0);