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"
19 Find the first instance of this Protocol
20 in the system and return it's interface.
23 @param ProtocolGuid Provides the protocol to search for
24 @param Interface On return, a pointer to the first interface
25 that matches ProtocolGuid
27 @retval EFI_SUCCESS A protocol instance matching ProtocolGuid was found
28 @retval EFI_NOT_FOUND No protocol instances were found that match ProtocolGuid
32 EfiLibLocateProtocol (
33 IN EFI_GUID
*ProtocolGuid
,
39 Status
= gBS
->LocateProtocol (
49 Function opens and returns a file handle to the root directory of a volume.
51 @param DeviceHandle A handle for a device
53 @return A valid file handle or NULL is returned
58 IN EFI_HANDLE DeviceHandle
62 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
68 // File the file system interface to the device
70 Status
= gBS
->HandleProtocol (
72 &gEfiSimpleFileSystemProtocolGuid
,
77 // Open the root directory of the volume
79 if (!EFI_ERROR (Status
)) {
80 Status
= Volume
->OpenVolume (
88 return EFI_ERROR (Status
) ? NULL
: File
;
93 Helper function called as part of the code needed
94 to allocate the proper sized buffer for various
98 @param Status Current status
99 @param Buffer Current allocated buffer, or NULL
100 @param BufferSize Current buffer size needed
102 @retval TRUE if the buffer was reallocated and the caller
103 should try the API again.
104 @retval FALSE The caller should not call this function again.
109 IN OUT EFI_STATUS
*Status
,
110 IN OUT VOID
**Buffer
,
117 // If this is an initial request, buffer will be null with a new buffer size
119 if ((*Buffer
== NULL
) && (BufferSize
!= 0)) {
120 *Status
= EFI_BUFFER_TOO_SMALL
;
123 // If the status code is "buffer too small", resize the buffer
126 if (*Status
== EFI_BUFFER_TOO_SMALL
) {
128 SafeFreePool (*Buffer
);
130 *Buffer
= AllocateZeroPool (BufferSize
);
132 if (*Buffer
!= NULL
) {
135 *Status
= EFI_OUT_OF_RESOURCES
;
139 // If there's an error, free the buffer
141 if (!TryAgain
&& EFI_ERROR (*Status
) && (*Buffer
!= NULL
)) {
142 SafeFreePool (*Buffer
);
150 Function returns the value of the specified variable.
153 @param Name A Null-terminated Unicode string that is
154 the name of the vendor's variable.
155 @param VendorGuid A unique identifier for the vendor.
157 @return The payload of the variable.
158 @retval NULL If the variable can't be read.
164 IN EFI_GUID
*VendorGuid
169 return BdsLibGetVariableAndSize (Name
, VendorGuid
, &VarSize
);
173 Function deletes the variable specified by VarName and VarGuid.
175 @param VarName A Null-terminated Unicode string that is
176 the name of the vendor's variable.
178 @param VarGuid A unique identifier for the vendor.
180 @retval EFI_SUCCESS The variable was found and removed
181 @retval EFI_UNSUPPORTED The variable store was inaccessible
182 @retval EFI_OUT_OF_RESOURCES The temporary buffer was not available
183 @retval EFI_NOT_FOUND The variable was not found
187 EfiLibDeleteVariable (
195 VarBuf
= EfiLibGetVariable (VarName
, VarGuid
);
196 Status
= EFI_NOT_FOUND
;
198 if (VarBuf
!= NULL
) {
200 // Delete variable from Storage
202 Status
= gRT
->SetVariable (VarName
, VarGuid
, VAR_FLAG
, 0, NULL
);
203 ASSERT (!EFI_ERROR (Status
));
204 SafeFreePool (VarBuf
);
212 Function gets the file system information from an open file descriptor,
213 and stores it in a buffer allocated from pool.
216 @param FHand The file handle.
218 @return A pointer to a buffer with file information.
219 @retval NULL is returned if failed to get Vaolume Label Info.
222 EFI_FILE_SYSTEM_VOLUME_LABEL_INFO
*
223 EfiLibFileSystemVolumeLabelInfo (
224 IN EFI_FILE_HANDLE FHand
228 EFI_FILE_SYSTEM_VOLUME_LABEL_INFO
*Buffer
;
231 // Initialize for GrowBuffer loop
234 BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO
+ 200;
237 // Call the real function
239 while (EfiGrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
240 Status
= FHand
->GetInfo (
242 &gEfiFileSystemVolumeLabelInfoIdGuid
,
254 @param Src The source.
256 @return A new string which is duplicated copy of the source.
257 @retval NULL If there is not enough memory.
268 Size
= StrSize (Src
);
269 Dest
= AllocateZeroPool (Size
);
270 ASSERT (Dest
!= NULL
);
272 CopyMem (Dest
, Src
, Size
);
280 Function gets the file information from an open file descriptor, and stores it
281 in a buffer allocated from pool.
283 @param FHand File Handle.
285 @return A pointer to a buffer with file information or NULL is returned
290 IN EFI_FILE_HANDLE FHand
294 EFI_FILE_INFO
*Buffer
;
298 // Initialize for GrowBuffer loop
301 BufferSize
= SIZE_OF_EFI_FILE_INFO
+ 200;
304 // Call the real function
306 while (EfiGrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
307 Status
= FHand
->GetInfo (
319 Function is used to determine the number of device path instances
320 that exist in a device path.
323 @param DevicePath A pointer to a device path data structure.
325 @return This function counts and returns the number of device path instances
330 EfiDevicePathInstanceCount (
331 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
338 while (GetNextDevicePathInstance (&DevicePath
, &Size
)) {
346 Adjusts the size of a previously allocated buffer.
349 @param OldPool - A pointer to the buffer whose size is being adjusted.
350 @param OldSize - The size of the current buffer.
351 @param NewSize - The size of the new buffer.
353 @return The newly allocated buffer.
354 @retval NULL Allocation failed.
368 NewPool
= AllocateZeroPool (NewSize
);
371 if (OldPool
!= NULL
) {
372 if (NewPool
!= NULL
) {
373 CopyMem (NewPool
, OldPool
, OldSize
< NewSize
? OldSize
: NewSize
);
376 SafeFreePool (OldPool
);
383 Compare two EFI_TIME data.
386 @param FirstTime - A pointer to the first EFI_TIME data.
387 @param SecondTime - A pointer to the second EFI_TIME data.
389 @retval TRUE The FirstTime is not later than the SecondTime.
390 @retval FALSE The FirstTime is later than the SecondTime.
395 IN EFI_TIME
*FirstTime
,
396 IN EFI_TIME
*SecondTime
399 if (FirstTime
->Year
!= SecondTime
->Year
) {
400 return (BOOLEAN
) (FirstTime
->Year
< SecondTime
->Year
);
401 } else if (FirstTime
->Month
!= SecondTime
->Month
) {
402 return (BOOLEAN
) (FirstTime
->Month
< SecondTime
->Month
);
403 } else if (FirstTime
->Day
!= SecondTime
->Day
) {
404 return (BOOLEAN
) (FirstTime
->Day
< SecondTime
->Day
);
405 } else if (FirstTime
->Hour
!= SecondTime
->Hour
) {
406 return (BOOLEAN
) (FirstTime
->Hour
< SecondTime
->Hour
);
407 } else if (FirstTime
->Minute
!= SecondTime
->Minute
) {
408 return (BOOLEAN
) (FirstTime
->Minute
< FirstTime
->Minute
);
409 } else if (FirstTime
->Second
!= SecondTime
->Second
) {
410 return (BOOLEAN
) (FirstTime
->Second
< SecondTime
->Second
);
413 return (BOOLEAN
) (FirstTime
->Nanosecond
<= SecondTime
->Nanosecond
);
417 Get a string from the Data Hub record based on
420 @param DevPath The device Path.
422 @return A string located from the Data Hub records based on
424 @retval NULL If failed to get the String from Data Hub.
428 EfiLibStrFromDatahub (
429 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
434 EFI_DATA_HUB_PROTOCOL
*Datahub
;
436 EFI_DATA_RECORD_HEADER
*Record
;
437 EFI_SUBCLASS_TYPE1_HEADER
*DataHdr
;
439 EFI_MISC_ONBOARD_DEVICE_DATA
*Ob
;
440 EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA
*Port
;
443 CopyGuid (&MiscGuid
, &gEfiMiscSubClassGuid
);
445 Status
= gBS
->LocateProtocol (
446 &gEfiDataHubProtocolGuid
,
450 if (EFI_ERROR (Status
)) {
454 Status
= gRT
->GetTime (&CurTime
, NULL
);
455 if (EFI_ERROR (Status
)) {
461 Status
= Datahub
->GetNextRecord (Datahub
, &Count
, NULL
, &Record
);
463 if (EFI_ERROR (Status
)) {
467 if (Record
->DataRecordClass
== EFI_DATA_RECORD_CLASS_DATA
&& CompareGuid (&Record
->DataRecordGuid
, &MiscGuid
)) {
469 // This record is what we need
471 DataHdr
= (EFI_SUBCLASS_TYPE1_HEADER
*) (Record
+ 1);
472 if (EFI_MISC_ONBOARD_DEVICE_RECORD_NUMBER
== DataHdr
->RecordType
) {
473 Ob
= (EFI_MISC_ONBOARD_DEVICE_DATA
*) (DataHdr
+ 1);
474 if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL
*) &Ob
->OnBoardDevicePath
, DevPath
)) {
475 GetProducerString (&Record
->ProducerName
, Ob
->OnBoardDeviceDescription
, &Desc
);
480 if (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_RECORD_NUMBER
== DataHdr
->RecordType
) {
481 Port
= (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA
*) (DataHdr
+ 1);
482 if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL
*) &Port
->PortPath
, DevPath
)) {
483 GetProducerString (&Record
->ProducerName
, Port
->PortExternalConnectorDesignator
, &Desc
);
489 } while (TimeCompare (&Record
->LogTime
, &CurTime
) && Count
!= 0);