⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 efibis_persist.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.


Module Name:
  
  efibis_persist.c



Abstract:


Revision History

--*/

#include <efi.h>
#include <efidriverlib.h>
//#include <efibis.h>
#include <bisbasecode.h>

static EFI_GUID	BISPersistProto= EFI_BIS_PERSISTENCE_PROTOCOL;

#define VarBISPersistentStorage             L"BISPersistentStorage"
#define VarBISPersistentStorageFragments    L"NumOfBISPersistentStorageFragments"
#define BISPersistentStorageSize            4096
#define EFI_MAXIMUM_VARIABLE_SIZE           1024
#define PERSIST_MAX_EFI_VAR_SIZE            EFI_MAXIMUM_VARIABLE_SIZE

BOOLEAN
BisGrowBuffer(
  IN OUT EFI_STATUS   *Status,
  IN OUT VOID         **Buffer,
  IN UINTN            BufferSize
  )
/*++

Routine Description:

    Helper function called as part of the code needed
    to allocate the proper sized buffer for various 
    EFI interfaces.

Arguments:

    Status      - Current status

    Buffer      - Current allocated buffer, or NULL

    BufferSize  - Current buffer size needed
    
Returns:
    
    TRUE - if the buffer was reallocated and the caller 
    should try the API again.

--*/
{
  BOOLEAN         TryAgain;

  //
  // If this is an initial request, buffer will be null with a new buffer size
  //

  if (!*Buffer && BufferSize) {
    *Status = EFI_BUFFER_TOO_SMALL;
  }

  //
  // If the status code is "buffer too small", resize the buffer
  //
      
  TryAgain = FALSE;
  if (*Status == EFI_BUFFER_TOO_SMALL) {

    if (*Buffer) {
      gBS->FreePool (*Buffer);
    }

//    *Buffer = AllocatePool (BufferSize);
  *Status = gBS->AllocatePool (
                  EfiBootServicesData, BufferSize, Buffer
                  );

    if (*Buffer) {
      TryAgain = TRUE;
    } else {    
      *Status = EFI_OUT_OF_RESOURCES;
    } 
  }

  //
  // If there's an error, free the buffer
  //

  if (!TryAgain && EFI_ERROR(*Status) && *Buffer) {
    gBS->FreePool (*Buffer);
    *Buffer = NULL;
  }

  return TryAgain;
}
VOID *
BisLibGetVariableAndSize (
    IN CHAR16               *Name,
    IN EFI_GUID             *VendorGuid,
    OUT UINTN               *VarSize
    )
/*++

Routine Description:
  Function returns the value of the specified variable and its size in bytes.

Arguments:
  Name                - A Null-terminated Unicode string that is 
                        the name of the vendor's variable.

  VendorGuid          - A unique identifier for the vendor.

  VarSize             - The size of the returned environment variable in bytes.

Returns:

  None

--*/
{
  EFI_STATUS              Status;
  VOID                    *Buffer;
  UINTN                   BufferSize;

  //
  // Initialize for BisGrowBuffer loop
  //

  Buffer = NULL;
  BufferSize = 100;

  //
  // Call the real function
  //

  while (BisGrowBuffer (&Status, &Buffer, BufferSize)) {
    Status = gRT->GetVariable (
                   Name,
                   VendorGuid,
                   NULL,
                   &BufferSize,
                   Buffer
                   );
  }
  if (Buffer) {
    *VarSize = BufferSize;
  } else {
    *VarSize = 0;
  }
  return Buffer;
}

    
VOID *
BisLibGetVariable (
  IN CHAR16               *Name,
  IN EFI_GUID             *VendorGuid
    )
/*++

Routine Description:
  Function returns the value of the specified variable.

Arguments:
  Name                - A Null-terminated Unicode string that is 
                        the name of the vendor's variable.

  VendorGuid          - A unique identifier for the vendor.

Returns:

  None

--*/
{
  UINTN   VarSize;

  return BisLibGetVariableAndSize (Name, VendorGuid, &VarSize);
}

UINTN
BisStrSize (
    IN CHAR16   *s1
    )
// string size
{
    UINTN        len;
    
    for (len=0; *s1; s1+=1, len+=1) ;
    return (len + 1) * sizeof(CHAR16);
}

UINTN
BisStrLen (
    IN CHAR16   *s1
    )
// string length
{
    UINTN        len;
    
    for (len=0; *s1; s1+=1, len+=1) ;
    return len;
}

///////////////////////////////////////////////////////////////////////////////
// Function: ValidateLength
//
// Purpose:  Verify the persistent storage data length is the length it was
//              initiallized to.  
//
// Parameters:			
//
// Function Returns:  EFI_SUCCESS if succefully returned, otherwise an error.
//
// Note:        It is caller's responsibility to free FragmentName.
///////////////////////////////////////////////////////////////////////////////
EFI_STATUS
ValidateLength(
     IN UINT32      Length)
{
    EFI_STATUS  retCode = EFI_SUCCESS;


    if (Length != BISPersistentStorageSize)
    {
        retCode = EFI_DEVICE_ERROR;
    }

    return retCode;
} // End of ValidateLength

///////////////////////////////////////////////////////////////////////////////
// Function: EnumerateFragmentNames
//
// Purpose:  Return the persistant storage variable names.  The usage model is
//				call EnumerateFramentNames with 0 as the fragment index.
//				It will return the first name if there is one and update
//				FragmentIndex with the next variable name.  It's value will be
//				zero if there are no more.  
//
// Parameters:			
//
// Function Returns:  EFI_SUCCESS if succefully returned, otherwise an error.
//
// Note:        It is caller's responsibility to free FragmentName.
///////////////////////////////////////////////////////////////////////////////
EFI_STATUS
EnumerateFragmentNames(
	OUT	UINT32    *FragmentIndex,
	OUT	CHAR16	  **FragmentName)
{
	EFI_STATUS      Status= EFI_SUCCESS;
    UINT32          *FragmentCount = 0;
    CHAR16          *LocalFragmentName;

	// Get the number of fragments that data was broken into

    FragmentCount = (UINT32*)BisLibGetVariable(
                        VarBISPersistentStorageFragments,   // Name
                        &BISPersistProto);                  // VendorGUID
    if (!FragmentCount)
    {
        DEBUG((EFI_D_ERROR,
            "PERSIST:  Missing Fragment Number variable.\n"));
        Status = EFI_NOT_FOUND;
    }

	if (EFI_SUCCESS == Status)
    {
        LocalFragmentName = x_malloc ((UINT32)(BisStrSize (VarBISPersistentStorage) + sizeof(UINT32)));
  
        // Get the variable name ready
        if (LocalFragmentName)
        {

            EfiCopyMem(LocalFragmentName,                  // Dest
                       VarBISPersistentStorage,            // Src
                       BisStrSize (VarBISPersistentStorage)); // len     

            LocalFragmentName[BisStrLen (VarBISPersistentStorage)]= (CHAR16)(*FragmentIndex + '0'); 

            if (*FragmentIndex < *FragmentCount)	
		    {										
			    (*FragmentIndex)++;
		    }
		    else
		    {
			    // That was the last fragment
			    *FragmentIndex = 0;
		    }

            *FragmentName = LocalFragmentName;

            if (FragmentCount)
            {
                gBS->FreePool(FragmentCount);
            }
        } // End of if (LocalFragmentName)
        else
        {
            // Failed to allocate pool
            DEBUG((EFI_D_ERROR,
                "PERSIST: Memory allocation failed\n"));
            Status = EFI_OUT_OF_RESOURCES;
        }
	}
	
	return Status;
} // End of EnumerateFragmentNames


///////////////////////////////////////////////////////////////////////////////
// Function: Persistentstorage_Read_Fn
//
// Purpose:  Return the data stored in persistent storage
//
// Parameters:  This            -
//              Buffer          - buffer to store the persistent data
//              Reserved        -
//
// Function Returns:  EFI_SUCCESS if succefully returned, otherwise an error.
//
// Note:        It is caller's responsibility to free Buffer.
///////////////////////////////////////////////////////////////////////////////
EFI_STATUS
Persistentstorage_Read_Fn(
	IN  EFI_BIS_PERSISTENCE_INTERFACE   *This,
	OUT UINT8						    *Buffer,
	IN  VOID                            *Reserved
	)
{
    EFI_STATUS              		Status= EFI_SUCCESS;
    UINT32                          BISPersistentStorageLen;
    UINT32                          TotalBISPersistentStorageLen = 0;
    UINT8                           *BISPersistentStorage;
    CHAR16                          *FragmentName;
	UINT32							FragmentIndex = 0;

    FragmentName = 0;

    // Check input parameters
    Status = EFI_INVALID_PARAMETER;     // assume failure till proven otherwise
    if (This)
    {
        if (Buffer)
        {
            if (Reserved == NULL)
            {
                Status = EFI_SUCCESS;
            }
        }
    } 

    if (EFI_SUCCESS == Status)
    {
		while (EFI_SUCCESS == Status)
		{
			Status = EnumerateFragmentNames(&FragmentIndex,
											&FragmentName);
            if (EFI_SUCCESS == Status)
			{	
				BISPersistentStorage = BisLibGetVariableAndSize (
										FragmentName,              // Name
										&BISPersistProto,          // VendorGUID
									   (UINTN*)&BISPersistentStorageLen); // var length
				if (BISPersistentStorage)
				{
					// Add this chunck to the big piece
                    EfiCopyMem (Buffer + TotalBISPersistentStorageLen ,  // Dest
                                BISPersistentStorage,                    // Src
                                BISPersistentStorageLen);                // len 
                    
                    // get the total space so far
					TotalBISPersistentStorageLen+= BISPersistentStorageLen;
                }
				else
				{
					 // Error in retrieving data from persistent storage
					DEBUG((EFI_D_ERROR,
				       	"PERSIST: Variable was not found.\n"));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -