]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmulatorPkg/Library/SmbiosLib/SmbiosLib.c
EmulatorPkg: formalize line endings
[mirror_edk2.git] / EmulatorPkg / Library / SmbiosLib / SmbiosLib.c
index 3382d7d2a6632e4b522f44677b9f16905fce645d..7bdadb32a3faa611bc3eccd835f6400b85e759d0 100644 (file)
-/** @file
-  Provides library functions for common SMBIOS operations. Only available to DXE
-  and UEFI module types.
-
-
-Copyright (c) 2012, Apple Inc. All rights reserved.
-Portitions Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials are licensed and made available under 
-the terms and conditions of the BSD License that accompanies this distribution.  
-The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php.
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-  
-#include <PiDxe.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-#include <Library/SmbiosLib.h>
-
-
-EFI_SMBIOS_PROTOCOL *gSmbios = NULL;
-
-
-/**
-  Create an initial SMBIOS Table from an array of SMBIOS_TEMPLATE_ENTRY 
-  entries. SMBIOS_TEMPLATE_ENTRY.NULL indicates the end of the table.
-
-  @param  Template   Array of SMBIOS_TEMPLATE_ENTRY entries.
-  @retval EFI_SUCCESS          New SMBIOS tables were created.
-  @retval EFI_OUT_OF_RESOURCES New SMBIOS tables were not created. 
-**/
-EFI_STATUS
-EFIAPI
-SmbiosLibInitializeFromTemplate (
-  IN  SMBIOS_TEMPLATE_ENTRY   *Template
-  )
-{
-  EFI_STATUS    Status;
-  UINTN         Index;
-
-  if (Template == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Status = EFI_SUCCESS;
-
-  for (Index = 0; Template[Index].Entry != NULL; Index++) {
-    Status = SmbiosLibCreateEntry (Template[Index].Entry, Template[Index].StringArray);
-  }
-
-  return Status;
-}
-
-
-
-/**
-  Create SMBIOS record.
-
-  Converts a fixed SMBIOS structure and an array of pointers to strings into
-  an SMBIOS record where the strings are cat'ed on the end of the fixed record
-  and terminated via a double NULL and add to SMBIOS table.
-
-  SMBIOS_TABLE_TYPE32 gSmbiosType12 = {
-    { EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS, sizeof (SMBIOS_TABLE_TYPE12), 0 },
-    1 // StringCount
-  };
-  CHAR8 *gSmbiosType12Strings[] = {
-    "Not Found",
-    NULL
-  };
-  
-  ...
-  CreateSmbiosEntry (
-    (EFI_SMBIOS_TABLE_HEADER*)&gSmbiosType12, 
-    gSmbiosType12Strings
-    );
-
-  @param  SmbiosEntry   Fixed SMBIOS structure
-  @param  StringArray   Array of strings to convert to an SMBIOS string pack. 
-                        NULL is OK.
-
-**/
-EFI_STATUS
-EFIAPI
-SmbiosLibCreateEntry (
-  IN  SMBIOS_STRUCTURE *SmbiosEntry,
-  IN  CHAR8            **StringArray 
-  )
-{
-  EFI_STATUS                Status;
-  EFI_SMBIOS_HANDLE         SmbiosHandle;
-  EFI_SMBIOS_TABLE_HEADER   *Record;
-  UINTN                     Index;
-  UINTN                     StringSize;
-  UINTN                     Size;
-  CHAR8                     *Str;
-
-  // Calculate the size of the fixed record and optional string pack
-  Size = SmbiosEntry->Length;
-  if (StringArray == NULL) { 
-    Size += 2; // Min string section is double null
-  } else if (StringArray[0] == NULL) {
-    Size += 2; // Min string section is double null
-  } else {
-    for (Index = 0; StringArray[Index] != NULL; Index++) {
-      StringSize = AsciiStrSize (StringArray[Index]);
-      Size += StringSize;
-    }
-    // Don't forget the terminating double null
-    Size += 1;
-  }
-
-  // Copy over Template
-  Record = (EFI_SMBIOS_TABLE_HEADER *)AllocateZeroPool (Size);
-  if (Record == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-  CopyMem (Record, SmbiosEntry, SmbiosEntry->Length);
-
-  if (StringArray != NULL) {
-    // Append string pack
-    Str = ((CHAR8 *)Record) + Record->Length;
-    for (Index = 0; StringArray[Index] != NULL; Index++) {
-      StringSize = AsciiStrSize (StringArray[Index]);
-      CopyMem (Str, StringArray[Index], StringSize);
-      Str += StringSize;
-    }
-    *Str = 0;
-  }  
-
-  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
-  Status = gSmbios->Add (
-                     gSmbios,
-                     gImageHandle,
-                     &SmbiosHandle,
-                     Record
-                     );
-  
-  FreePool (Record);
-  return Status;
-}
-
-
-
-/**
-  Update the string associated with an existing SMBIOS record.
-  
-  This function allows the update of specific SMBIOS strings. The number of valid strings for any
-  SMBIOS record is defined by how many strings were present when Add() was called.
-  
-  @param[in]    SmbiosHandle    SMBIOS Handle of structure that will have its string updated.
-  @param[in]    StringNumber    The non-zero string number of the string to update.
-  @param[in]    String          Update the StringNumber string with String.
-  
-  @retval EFI_SUCCESS           SmbiosHandle had its StringNumber String updated.
-  @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid.
-  @retval EFI_UNSUPPORTED       String was not added because it is longer than the SMBIOS Table supports.
-  @retval EFI_NOT_FOUND         The StringNumber.is not valid for this SMBIOS record.    
-**/
-EFI_STATUS
-EFIAPI
-SmbiosLibUpdateString (
-  IN  EFI_SMBIOS_HANDLE     SmbiosHandle,
-  IN  SMBIOS_TABLE_STRING   StringNumber,
-  IN  CHAR8                 *String
-  )
-{
-  UINTN StringIndex;
-
-  if (String == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (*String == '\0') {
-    // A string with no data is not legal in SMBIOS
-    return EFI_INVALID_PARAMETER;
-  }
-
-  StringIndex = StringNumber;
-  return gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, String);
-}
-
-
-/**
-  Update the string associated with an existing SMBIOS record.
-  
-  This function allows the update of specific SMBIOS strings. The number of valid strings for any
-  SMBIOS record is defined by how many strings were present when Add() was called.
-  
-  @param[in]    SmbiosHandle    SMBIOS Handle of structure that will have its string updated.
-  @param[in]    StringNumber    The non-zero string number of the string to update.
-  @param[in]    String          Update the StringNumber string with String.
-  
-  @retval EFI_SUCCESS           SmbiosHandle had its StringNumber String updated.
-  @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid.
-  @retval EFI_UNSUPPORTED       String was not added because it is longer than the SMBIOS Table supports.
-  @retval EFI_NOT_FOUND         The StringNumber.is not valid for this SMBIOS record.    
-**/
-EFI_STATUS
-EFIAPI
-SmbiosLibUpdateUnicodeString (
-  IN  EFI_SMBIOS_HANDLE     SmbiosHandle,
-  IN  SMBIOS_TABLE_STRING   StringNumber,
-  IN  CHAR16                *String
-  )
-{
-  EFI_STATUS  Status;
-  UINTN       StringIndex;
-  CHAR8       *Ascii;
-
-  if (String == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (*String == '\0') {
-    // A string with no data is not legal in SMBIOS
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Ascii = AllocateZeroPool (StrSize (String));
-  if (Ascii == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-  UnicodeStrToAsciiStr (String, Ascii);
-
-  StringIndex = StringNumber;
-  Status = gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, Ascii);
-  
-  FreePool (Ascii);
-  return Status;
-}
-
-
-/**
-  Allow caller to read a specific SMBIOS string
-  
-  @param[in]    Header          SMBIOS record that contains the string. 
-  @param[in[    StringNumber    Instance of SMBIOS string 1 - N. 
-
-  @retval NULL                  Instance of Type SMBIOS string was not found. 
-  @retval Other                 Pointer to matching SMBIOS string. 
-**/
-CHAR8 *
-EFIAPI
-SmbiosLibReadString (
-  IN SMBIOS_STRUCTURE   *Header,
-  IN EFI_SMBIOS_STRING  StringNumber
-  )
-{
-  CHAR8       *Data;
-  UINTN       Match;
-  
-  Data = (CHAR8 *)Header + Header->Length;
-  for (Match = 1;!(*Data == 0 && *(Data+1) == 0); ) {
-    if (StringNumber == Match) {
-      return Data;
-    }
-    Data++;
-    if (*(Data - 1) == '\0') {
-      Match++;
-    }
-  } 
-
-  return NULL;
-}
-
-
-/**
-  Allow the caller to discover a specific SMBIOS entry, and patch it if necissary. 
-  
-  @param[in]    Type            Type of the next SMBIOS record to return. 
-  @param[in[    Instance        Instance of SMBIOS record 0 - N-1. 
-  @param[out]   SmbiosHandle    Returns SMBIOS handle for the matching record. 
-
-  @retval NULL                  Instance of Type SMBIOS record was not found. 
-  @retval Other                 Pointer to matching SMBIOS record. 
-**/
-SMBIOS_STRUCTURE *
-EFIAPI
-SmbiosLibGetRecord (
-  IN  EFI_SMBIOS_TYPE   Type,
-  IN  UINTN             Instance,
-  OUT EFI_SMBIOS_HANDLE *SmbiosHandle
-  )
-{
-  EFI_STATUS              Status;
-  EFI_SMBIOS_TABLE_HEADER *Record;
-  UINTN                   Match;
-
-  Match         = 0;
-  *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
-  do {
-    Status = gSmbios->GetNext (gSmbios, SmbiosHandle, &Type, &Record, NULL);
-    if (!EFI_ERROR (Status)) {
-      if (Match == Instance) {
-        return (SMBIOS_STRUCTURE *)Record;
-      }
-      Match++;
-    }
-  } while (!EFI_ERROR (Status));
-
-  return NULL;
-}
-
-
-/**
-  Remove an SMBIOS record.
-  
-  This function removes an SMBIOS record using the handle specified by SmbiosHandle.
-  
-  @param[in]    SmbiosHandle        The handle of the SMBIOS record to remove.
-  
-  @retval EFI_SUCCESS               SMBIOS record was removed.
-  @retval EFI_INVALID_PARAMETER     SmbiosHandle does not specify a valid SMBIOS record.
-**/
-EFI_STATUS
-EFIAPI
-SmbiosLibRemove (
-  OUT EFI_SMBIOS_HANDLE SmbiosHandle
-  )
-{
-  return gSmbios->Remove (gSmbios, SmbiosHandle);
-}
-
-
-
-/**
-  
-  @param  ImageHandle  ImageHandle of the loaded driver.
-  @param  SystemTable  Pointer to the EFI System Table.
-
-  @retval  EFI_SUCCESS            Register successfully.
-  @retval  EFI_OUT_OF_RESOURCES   No enough memory to register this handler.
-**/
-EFI_STATUS
-EFIAPI
-SmbiosLibConstructor (
-  IN EFI_HANDLE        ImageHandle,
-  IN EFI_SYSTEM_TABLE  *SystemTable
-  )
-{
-  return gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&gSmbios);
-}
-
+/** @file\r
+  Provides library functions for common SMBIOS operations. Only available to DXE\r
+  and UEFI module types.\r
+\r
+\r
+Copyright (c) 2012, Apple Inc. All rights reserved.\r
+Portitions Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under\r
+the terms and conditions of the BSD License that accompanies this distribution.\r
+The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php.\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/SmbiosLib.h>\r
+\r
+\r
+EFI_SMBIOS_PROTOCOL *gSmbios = NULL;\r
+\r
+\r
+/**\r
+  Create an initial SMBIOS Table from an array of SMBIOS_TEMPLATE_ENTRY\r
+  entries. SMBIOS_TEMPLATE_ENTRY.NULL indicates the end of the table.\r
+\r
+  @param  Template   Array of SMBIOS_TEMPLATE_ENTRY entries.\r
+\r
+  @retval EFI_SUCCESS          New SMBIOS tables were created.\r
+  @retval EFI_OUT_OF_RESOURCES New SMBIOS tables were not created.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosLibInitializeFromTemplate (\r
+  IN  SMBIOS_TEMPLATE_ENTRY   *Template\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINTN         Index;\r
+\r
+  if (Template == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  for (Index = 0; Template[Index].Entry != NULL; Index++) {\r
+    Status = SmbiosLibCreateEntry (Template[Index].Entry, Template[Index].StringArray);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Create SMBIOS record.\r
+\r
+  Converts a fixed SMBIOS structure and an array of pointers to strings into\r
+  an SMBIOS record where the strings are cat'ed on the end of the fixed record\r
+  and terminated via a double NULL and add to SMBIOS table.\r
+\r
+  SMBIOS_TABLE_TYPE32 gSmbiosType12 = {\r
+    { EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS, sizeof (SMBIOS_TABLE_TYPE12), 0 },\r
+    1 // StringCount\r
+  };\r
+  CHAR8 *gSmbiosType12Strings[] = {\r
+    "Not Found",\r
+    NULL\r
+  };\r
+\r
+  ...\r
+  CreateSmbiosEntry (\r
+    (EFI_SMBIOS_TABLE_HEADER*)&gSmbiosType12,\r
+    gSmbiosType12Strings\r
+    );\r
+\r
+  @param  SmbiosEntry   Fixed SMBIOS structure\r
+  @param  StringArray   Array of strings to convert to an SMBIOS string pack.\r
+                        NULL is OK.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosLibCreateEntry (\r
+  IN  SMBIOS_STRUCTURE *SmbiosEntry,\r
+  IN  CHAR8            **StringArray\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_SMBIOS_HANDLE         SmbiosHandle;\r
+  EFI_SMBIOS_TABLE_HEADER   *Record;\r
+  UINTN                     Index;\r
+  UINTN                     StringSize;\r
+  UINTN                     Size;\r
+  CHAR8                     *Str;\r
+\r
+  // Calculate the size of the fixed record and optional string pack\r
+  Size = SmbiosEntry->Length;\r
+  if (StringArray == NULL) {\r
+    Size += 2; // Min string section is double null\r
+  } else if (StringArray[0] == NULL) {\r
+    Size += 2; // Min string section is double null\r
+  } else {\r
+    for (Index = 0; StringArray[Index] != NULL; Index++) {\r
+      StringSize = AsciiStrSize (StringArray[Index]);\r
+      Size += StringSize;\r
+    }\r
+    // Don't forget the terminating double null\r
+    Size += 1;\r
+  }\r
+\r
+  // Copy over Template\r
+  Record = (EFI_SMBIOS_TABLE_HEADER *)AllocateZeroPool (Size);\r
+  if (Record == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  CopyMem (Record, SmbiosEntry, SmbiosEntry->Length);\r
+\r
+  if (StringArray != NULL) {\r
+    // Append string pack\r
+    Str = ((CHAR8 *)Record) + Record->Length;\r
+    for (Index = 0; StringArray[Index] != NULL; Index++) {\r
+      StringSize = AsciiStrSize (StringArray[Index]);\r
+      CopyMem (Str, StringArray[Index], StringSize);\r
+      Str += StringSize;\r
+    }\r
+    *Str = 0;\r
+  }\r
+\r
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
+  Status = gSmbios->Add (\r
+                     gSmbios,\r
+                     gImageHandle,\r
+                     &SmbiosHandle,\r
+                     Record\r
+                     );\r
+\r
+  FreePool (Record);\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Update the string associated with an existing SMBIOS record.\r
+\r
+  This function allows the update of specific SMBIOS strings. The number of valid strings for any\r
+  SMBIOS record is defined by how many strings were present when Add() was called.\r
+\r
+  @param[in]    SmbiosHandle    SMBIOS Handle of structure that will have its string updated.\r
+  @param[in]    StringNumber    The non-zero string number of the string to update.\r
+  @param[in]    String          Update the StringNumber string with String.\r
+\r
+  @retval EFI_SUCCESS           SmbiosHandle had its StringNumber String updated.\r
+  @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid.\r
+  @retval EFI_UNSUPPORTED       String was not added because it is longer than the SMBIOS Table supports.\r
+  @retval EFI_NOT_FOUND         The StringNumber.is not valid for this SMBIOS record.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosLibUpdateString (\r
+  IN  EFI_SMBIOS_HANDLE     SmbiosHandle,\r
+  IN  SMBIOS_TABLE_STRING   StringNumber,\r
+  IN  CHAR8                 *String\r
+  )\r
+{\r
+  UINTN StringIndex;\r
+\r
+  if (String == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (*String == '\0') {\r
+    // A string with no data is not legal in SMBIOS\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  StringIndex = StringNumber;\r
+  return gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, String);\r
+}\r
+\r
+\r
+/**\r
+  Update the string associated with an existing SMBIOS record.\r
+\r
+  This function allows the update of specific SMBIOS strings. The number of valid strings for any\r
+  SMBIOS record is defined by how many strings were present when Add() was called.\r
+\r
+  @param[in]    SmbiosHandle    SMBIOS Handle of structure that will have its string updated.\r
+  @param[in]    StringNumber    The non-zero string number of the string to update.\r
+  @param[in]    String          Update the StringNumber string with String.\r
+\r
+  @retval EFI_SUCCESS           SmbiosHandle had its StringNumber String updated.\r
+  @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid.\r
+  @retval EFI_UNSUPPORTED       String was not added because it is longer than the SMBIOS Table supports.\r
+  @retval EFI_NOT_FOUND         The StringNumber.is not valid for this SMBIOS record.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosLibUpdateUnicodeString (\r
+  IN  EFI_SMBIOS_HANDLE     SmbiosHandle,\r
+  IN  SMBIOS_TABLE_STRING   StringNumber,\r
+  IN  CHAR16                *String\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       StringIndex;\r
+  CHAR8       *Ascii;\r
+\r
+  if (String == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (*String == '\0') {\r
+    // A string with no data is not legal in SMBIOS\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Ascii = AllocateZeroPool (StrSize (String));\r
+  if (Ascii == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  UnicodeStrToAsciiStr (String, Ascii);\r
+\r
+  StringIndex = StringNumber;\r
+  Status = gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, Ascii);\r
+\r
+  FreePool (Ascii);\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Allow caller to read a specific SMBIOS string\r
+\r
+  @param[in]    Header          SMBIOS record that contains the string.\r
+  @param[in[    StringNumber    Instance of SMBIOS string 1 - N.\r
+\r
+  @retval NULL                  Instance of Type SMBIOS string was not found.\r
+  @retval Other                 Pointer to matching SMBIOS string.\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+SmbiosLibReadString (\r
+  IN SMBIOS_STRUCTURE   *Header,\r
+  IN EFI_SMBIOS_STRING  StringNumber\r
+  )\r
+{\r
+  CHAR8       *Data;\r
+  UINTN       Match;\r
+\r
+  Data = (CHAR8 *)Header + Header->Length;\r
+  for (Match = 1;!(*Data == 0 && *(Data+1) == 0); ) {\r
+    if (StringNumber == Match) {\r
+      return Data;\r
+    }\r
+    Data++;\r
+    if (*(Data - 1) == '\0') {\r
+      Match++;\r
+    }\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+\r
+/**\r
+  Allow the caller to discover a specific SMBIOS entry, and patch it if necissary.\r
+\r
+  @param[in]    Type            Type of the next SMBIOS record to return.\r
+  @param[in[    Instance        Instance of SMBIOS record 0 - N-1.\r
+  @param[out]   SmbiosHandle    Returns SMBIOS handle for the matching record.\r
+\r
+  @retval NULL                  Instance of Type SMBIOS record was not found.\r
+  @retval Other                 Pointer to matching SMBIOS record.\r
+**/\r
+SMBIOS_STRUCTURE *\r
+EFIAPI\r
+SmbiosLibGetRecord (\r
+  IN  EFI_SMBIOS_TYPE   Type,\r
+  IN  UINTN             Instance,\r
+  OUT EFI_SMBIOS_HANDLE *SmbiosHandle\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_SMBIOS_TABLE_HEADER *Record;\r
+  UINTN                   Match;\r
+\r
+  Match         = 0;\r
+  *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
+  do {\r
+    Status = gSmbios->GetNext (gSmbios, SmbiosHandle, &Type, &Record, NULL);\r
+    if (!EFI_ERROR (Status)) {\r
+      if (Match == Instance) {\r
+        return (SMBIOS_STRUCTURE *)Record;\r
+      }\r
+      Match++;\r
+    }\r
+  } while (!EFI_ERROR (Status));\r
+\r
+  return NULL;\r
+}\r
+\r
+\r
+/**\r
+  Remove an SMBIOS record.\r
+\r
+  This function removes an SMBIOS record using the handle specified by SmbiosHandle.\r
+\r
+  @param[in]    SmbiosHandle        The handle of the SMBIOS record to remove.\r
+\r
+  @retval EFI_SUCCESS               SMBIOS record was removed.\r
+  @retval EFI_INVALID_PARAMETER     SmbiosHandle does not specify a valid SMBIOS record.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosLibRemove (\r
+  OUT EFI_SMBIOS_HANDLE SmbiosHandle\r
+  )\r
+{\r
+  return gSmbios->Remove (gSmbios, SmbiosHandle);\r
+}\r
+\r
+\r
+\r
+/**\r
+\r
+  @param  ImageHandle  ImageHandle of the loaded driver.\r
+  @param  SystemTable  Pointer to the EFI System Table.\r
+\r
+  @retval  EFI_SUCCESS            Register successfully.\r
+  @retval  EFI_OUT_OF_RESOURCES   No enough memory to register this handler.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  return gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&gSmbios);\r
+}\r
+\r