3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Boot Maintainence Helper functions
22 #include "bootmaint.h"
25 EfiLibLocateProtocol (
26 IN EFI_GUID
*ProtocolGuid
,
33 Find the first instance of this Protocol
34 in the system and return it's interface
38 ProtocolGuid - Provides the protocol to search for
39 Interface - On return, a pointer to the first interface
40 that matches ProtocolGuid
44 EFI_SUCCESS - A protocol instance matching ProtocolGuid was found
46 EFI_NOT_FOUND - No protocol instances were found that match ProtocolGuid
52 Status
= gBS
->LocateProtocol (
62 IN EFI_HANDLE DeviceHandle
68 Function opens and returns a file handle to the root directory of a volume.
72 DeviceHandle - A handle for a device
76 A valid file handle or NULL is returned
81 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
87 // File the file system interface to the device
89 Status
= gBS
->HandleProtocol (
91 &gEfiSimpleFileSystemProtocolGuid
,
96 // Open the root directory of the volume
98 if (!EFI_ERROR (Status
)) {
99 Status
= Volume
->OpenVolume (
107 return EFI_ERROR (Status
) ? NULL
: File
;
112 IN OUT EFI_STATUS
*Status
,
113 IN OUT VOID
**Buffer
,
120 Helper function called as part of the code needed
121 to allocate the proper sized buffer for various
126 Status - Current status
128 Buffer - Current allocated buffer, or NULL
130 BufferSize - Current buffer size needed
134 TRUE - if the buffer was reallocated and the caller
135 should try the API again.
142 // If this is an initial request, buffer will be null with a new buffer size
144 if (!*Buffer
&& BufferSize
) {
145 *Status
= EFI_BUFFER_TOO_SMALL
;
148 // If the status code is "buffer too small", resize the buffer
151 if (*Status
== EFI_BUFFER_TOO_SMALL
) {
153 SafeFreePool (*Buffer
);
155 *Buffer
= AllocateZeroPool (BufferSize
);
160 *Status
= EFI_OUT_OF_RESOURCES
;
164 // If there's an error, free the buffer
166 if (!TryAgain
&& EFI_ERROR (*Status
) && *Buffer
) {
167 SafeFreePool (*Buffer
);
177 IN EFI_GUID
*VendorGuid
182 Function returns the value of the specified variable.
185 Name - A Null-terminated Unicode string that is
186 the name of the vendor's variable.
188 VendorGuid - A unique identifier for the vendor.
198 return BdsLibGetVariableAndSize (Name
, VendorGuid
, &VarSize
);
202 EfiLibDeleteVariable (
209 Function deletes the variable specified by VarName and VarGuid.
212 VarName - A Null-terminated Unicode string that is
213 the name of the vendor's variable.
215 VendorGuid - A unique identifier for the vendor.
219 EFI_SUCCESS - The variable was found and removed
221 EFI_UNSUPPORTED - The variable store was inaccessible
223 EFI_OUT_OF_RESOURCES - The temporary buffer was not available
225 EFI_NOT_FOUND - The variable was not found
232 VarBuf
= EfiLibGetVariable (VarName
, VarGuid
);
233 Status
= EFI_NOT_FOUND
;
237 // Delete variable from Storage
239 Status
= gRT
->SetVariable (VarName
, VarGuid
, VAR_FLAG
, 0, NULL
);
240 ASSERT (!EFI_ERROR (Status
));
241 SafeFreePool (VarBuf
);
247 EFI_FILE_SYSTEM_VOLUME_LABEL_INFO
*
248 EfiLibFileSystemVolumeLabelInfo (
249 IN EFI_FILE_HANDLE FHand
255 Function gets the file system information from an open file descriptor,
256 and stores it in a buffer allocated from pool.
260 Fhand - A file handle
264 A pointer to a buffer with file information or NULL is returned
269 EFI_FILE_SYSTEM_VOLUME_LABEL_INFO
*Buffer
;
272 // Initialize for GrowBuffer loop
275 BufferSize
= SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO
+ 200;
278 // Call the real function
280 while (EfiGrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
281 Status
= FHand
->GetInfo (
283 &gEfiFileSystemVolumeLabelInfoIdGuid
,
300 Size
= StrSize (Src
);
301 Dest
= AllocateZeroPool (Size
);
302 ASSERT (Dest
!= NULL
);
304 CopyMem (Dest
, Src
, Size
);
312 IN EFI_FILE_HANDLE FHand
318 Function gets the file information from an open file descriptor, and stores it
319 in a buffer allocated from pool.
323 Fhand - A file handle
327 A pointer to a buffer with file information or NULL is returned
332 EFI_FILE_INFO
*Buffer
;
336 // Initialize for GrowBuffer loop
339 BufferSize
= SIZE_OF_EFI_FILE_INFO
+ 200;
342 // Call the real function
344 while (EfiGrowBuffer (&Status
, (VOID
**) &Buffer
, BufferSize
)) {
345 Status
= FHand
->GetInfo (
357 EfiDevicePathInstanceCount (
358 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
363 Function is used to determine the number of device path instances
364 that exist in a device path.
367 DevicePath - A pointer to a device path data structure.
371 This function counts and returns the number of device path instances
380 while (GetNextDevicePathInstance (&DevicePath
, &Size
)) {
396 Adjusts the size of a previously allocated buffer.
399 OldPool - A pointer to the buffer whose size is being adjusted.
400 OldSize - The size of the current buffer.
401 NewSize - The size of the new buffer.
405 EFI_SUCEESS - The requested number of bytes were allocated.
407 EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.
409 EFI_INVALID_PARAMETER - The buffer was invalid.
417 NewPool
= AllocateZeroPool (NewSize
);
422 CopyMem (NewPool
, OldPool
, OldSize
< NewSize
? OldSize
: NewSize
);
425 SafeFreePool (OldPool
);
432 EfiLibGetStringFromToken (
433 IN EFI_GUID
*ProducerGuid
,
441 Acquire the string associated with the ProducerGuid and return it.
445 ProducerGuid - The Guid to search the HII database for
446 Token - The token value of the string to extract
447 String - The string that is extracted
451 EFI_SUCCESS - Buffer filled with the requested forms. BufferLength
453 EFI_BUFFER_TOO_SMALL - The buffer provided was not large enough to allow the form to be stored.
458 UINT16 HandleBufferLength
;
459 EFI_HII_HANDLE
*HiiHandleBuffer
;
460 UINTN StringBufferLength
;
461 UINTN NumberOfHiiHandles
;
465 EFI_HII_PROTOCOL
*Hii
;
467 HandleBufferLength
= 0x1000;
468 HiiHandleBuffer
= NULL
;
469 Status
= gBS
->LocateProtocol (
470 &gEfiHiiProtocolGuid
,
474 if (EFI_ERROR (Status
)) {
479 // Get all the Hii handles
481 HiiHandleBuffer
= AllocateZeroPool (HandleBufferLength
);
482 ASSERT (HiiHandleBuffer
!= NULL
);
484 Status
= Hii
->FindHandles (Hii
, &HandleBufferLength
, HiiHandleBuffer
);
485 ASSERT_EFI_ERROR (Status
);
488 // Get the Hii Handle that matches the StructureNode->ProducerName
490 NumberOfHiiHandles
= HandleBufferLength
/ sizeof (EFI_HII_HANDLE
);
491 for (Index
= 0; Index
< NumberOfHiiHandles
; Index
++) {
493 Status
= ExtractDataFromHiiHandle (
494 HiiHandleBuffer
[Index
],
499 if (CompareGuid (ProducerGuid
, &HiiGuid
)) {
504 // Find the string based on the current language
506 StringBufferLength
= 0x100;
507 *String
= AllocateZeroPool (0x100);
508 ASSERT (*String
!= NULL
);
510 Status
= Hii
->GetString (
512 HiiHandleBuffer
[Index
],
520 gBS
->FreePool (HiiHandleBuffer
);
527 IN EFI_TIME
*FirstTime
,
528 IN EFI_TIME
*SecondTime
533 Compare two EFI_TIME data.
537 FirstTime - A pointer to the first EFI_TIME data.
538 SecondTime - A pointer to the second EFI_TIME data.
541 TRUE The FirstTime is not later than the SecondTime.
542 FALSE The FirstTime is later than the SecondTime.
546 if (FirstTime
->Year
!= SecondTime
->Year
) {
547 return (BOOLEAN
) (FirstTime
->Year
< SecondTime
->Year
);
548 } else if (FirstTime
->Month
!= SecondTime
->Month
) {
549 return (BOOLEAN
) (FirstTime
->Month
< SecondTime
->Month
);
550 } else if (FirstTime
->Day
!= SecondTime
->Day
) {
551 return (BOOLEAN
) (FirstTime
->Day
< SecondTime
->Day
);
552 } else if (FirstTime
->Hour
!= SecondTime
->Hour
) {
553 return (BOOLEAN
) (FirstTime
->Hour
< SecondTime
->Hour
);
554 } else if (FirstTime
->Minute
!= SecondTime
->Minute
) {
555 return (BOOLEAN
) (FirstTime
->Minute
< FirstTime
->Minute
);
556 } else if (FirstTime
->Second
!= SecondTime
->Second
) {
557 return (BOOLEAN
) (FirstTime
->Second
< SecondTime
->Second
);
560 return (BOOLEAN
) (FirstTime
->Nanosecond
<= SecondTime
->Nanosecond
);
564 EfiLibStrFromDatahub (
565 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
570 EFI_DATA_HUB_PROTOCOL
*Datahub
;
572 EFI_DATA_RECORD_HEADER
*Record
;
573 EFI_SUBCLASS_TYPE1_HEADER
*DataHdr
;
574 EFI_GUID MiscGuid
= EFI_MISC_SUBCLASS_GUID
;
575 EFI_MISC_ONBOARD_DEVICE_DATA
*ob
;
576 EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA
*Port
;
579 Status
= gBS
->LocateProtocol (
580 &gEfiDataHubProtocolGuid
,
584 if (EFI_ERROR (Status
)) {
588 Status
= gRT
->GetTime (&CurTime
, NULL
);
589 if (EFI_ERROR (Status
)) {
595 Status
= Datahub
->GetNextRecord (Datahub
, &Count
, NULL
, &Record
);
597 if (EFI_ERROR (Status
)) {
601 if (Record
->DataRecordClass
== EFI_DATA_RECORD_CLASS_DATA
&& CompareGuid (&Record
->DataRecordGuid
, &MiscGuid
)) {
603 // This record is what we need
605 DataHdr
= (EFI_SUBCLASS_TYPE1_HEADER
*) (Record
+ 1);
606 if (EFI_MISC_ONBOARD_DEVICE_RECORD_NUMBER
== DataHdr
->RecordType
) {
607 ob
= (EFI_MISC_ONBOARD_DEVICE_DATA
*) (DataHdr
+ 1);
608 if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL
*) &ob
->OnBoardDevicePath
, DevPath
)) {
609 EfiLibGetStringFromToken (&Record
->ProducerName
, ob
->OnBoardDeviceDescription
, &Desc
);
614 if (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_RECORD_NUMBER
== DataHdr
->RecordType
) {
615 Port
= (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA
*) (DataHdr
+ 1);
616 if (BdsLibMatchDevicePaths ((EFI_DEVICE_PATH_PROTOCOL
*) &Port
->PortPath
, DevPath
)) {
617 EfiLibGetStringFromToken (&Record
->ProducerName
, Port
->PortExternalConnectorDesignator
, &Desc
);
623 } while (TimeCompare (&Record
->LogTime
, &CurTime
) && Count
!= 0);