]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/IfrSupportLib/UefiIfrForm.c
Fix ECC issue.
[mirror_edk2.git] / MdePkg / Library / IfrSupportLib / UefiIfrForm.c
index d0da744240bdd493c39b1974194cd129d96d0094..ee981c93ff175e6b36e1455bc3d85b657065287c 100644 (file)
@@ -15,32 +15,65 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
 #include "UefiIfrLibraryInternal.h"
 
+STATIC CONST EFI_FORM_BROWSER2_PROTOCOL      *mFormBrowser2     = NULL;
+STATIC CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting = NULL;
+
+/**
+  This function locate FormBrowser2 protocols for later usage.
+
+  @return Status the status to locate protocol.
+**/
+EFI_STATUS
+LocateFormBrowser2Protocols (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  //
+  // Locate protocols for later usage
+  //
+  if (mFormBrowser2 == NULL) {
+    Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mFormBrowser2);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+  
+  if (mHiiConfigRouting == NULL) {
+    Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &mHiiConfigRouting);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
 //
 // Fake <ConfigHdr>
 //
-UINT16 mFakeConfigHdr[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=0";
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT16 mFakeConfigHdr[] = L"GUID=00000000000000000000000000000000&NAME=0000&PATH=0";
 
 /**
   Draw a dialog and return the selected key.
 
   @param  NumberOfLines          The number of lines for the dialog box
   @param  KeyValue               The EFI_KEY value returned if HotKey is TRUE..
-  @param  String                 Pointer to the first string in the list
-  @param  ...                    A series of (quantity == NumberOfLines) text
+  @param  Marker                 A series of (quantity == NumberOfLines - 1) text
                                  strings which will be used to construct the dialog
                                  box
 
   @retval EFI_SUCCESS            Displayed dialog and received user interaction
   @retval EFI_INVALID_PARAMETER  One of the parameters was invalid.
+  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.
 
 **/
 EFI_STATUS
 EFIAPI
-IfrLibCreatePopUp (
+IfrLibCreatePopUp2 (
   IN  UINTN                       NumberOfLines,
   OUT EFI_INPUT_KEY               *KeyValue,
-  IN  CHAR16                      *String,
-  ...
+  IN  VA_LIST                     Marker
   )
 {
   UINTN                         Index;
@@ -54,7 +87,6 @@ IfrLibCreatePopUp (
   UINTN                         BottomRow;
   UINTN                         DimensionsWidth;
   UINTN                         DimensionsHeight;
-  VA_LIST                       Marker;
   EFI_INPUT_KEY                 Key;
   UINTN                         LargestString;
   CHAR16                        *StackString;
@@ -66,7 +98,10 @@ IfrLibCreatePopUp (
   EFI_EVENT                     WaitList[2];
   UINTN                         CurrentAttribute;
   EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut;
+  CHAR16                        *String;
 
+  String = VA_ARG (Marker, CHAR16 *);
+  
   if ((KeyValue == NULL) || (String == NULL)) {
     return EFI_INVALID_PARAMETER;
   }
@@ -85,21 +120,28 @@ IfrLibCreatePopUp (
   CurrentAttribute = ConOut->Mode->Attribute;
 
   LineBuffer = AllocateZeroPool (DimensionsWidth * sizeof (CHAR16));
-  ASSERT (LineBuffer != NULL);
+  if (LineBuffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
 
   //
   // Determine the largest string in the dialog box
   // Notice we are starting with 1 since String is the first string
   //
   StringArray = AllocateZeroPool (NumberOfLines * sizeof (CHAR16 *));
+  if (StringArray == NULL) {
+    FreePool (LineBuffer);
+    return EFI_OUT_OF_RESOURCES;
+  }
   LargestString = StrLen (String);
   StringArray[0] = String;
 
-  VA_START (Marker, String);
   for (Index = 1; Index < NumberOfLines; Index++) {
     StackString = VA_ARG (Marker, CHAR16 *);
 
     if (StackString == NULL) {
+      FreePool (LineBuffer);
+      FreePool (StringArray);
       return EFI_INVALID_PARAMETER;
     }
 
@@ -211,10 +253,48 @@ IfrLibCreatePopUp (
   ConOut->SetAttribute (ConOut, CurrentAttribute);
   ConOut->EnableCursor (ConOut, TRUE);
 
+  FreePool (LineBuffer);
+  FreePool (StringArray);
+
   return Status;
 }
 
 
+/**
+  Draw a dialog and return the selected key.
+
+  @param  NumberOfLines          The number of lines for the dialog box
+  @param  KeyValue               The EFI_KEY value returned if HotKey is TRUE..
+  @param  String                 Pointer to the first string in the list
+  @param  ...                    A series of (quantity == NumberOfLines - 1) text
+                                 strings which will be used to construct the dialog
+                                 box
+
+  @retval EFI_SUCCESS            Displayed dialog and received user interaction
+  @retval EFI_INVALID_PARAMETER  One of the parameters was invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+IfrLibCreatePopUp (
+  IN  UINTN                       NumberOfLines,
+  OUT EFI_INPUT_KEY               *KeyValue,
+  IN  CHAR16                      *String,
+  ...
+  )
+{
+  EFI_STATUS                      Status;
+  VA_LIST                         Marker;
+
+  VA_START (Marker, KeyValue);
+
+  Status = IfrLibCreatePopUp2 (NumberOfLines, KeyValue, Marker);
+
+  VA_END (Marker);
+
+  return Status;
+}
+
 /**
   Swap bytes in the buffer. This is a internal function.
 
@@ -250,6 +330,7 @@ SwapBuffer (
 
 **/
 VOID
+EFIAPI
 ToLower (
   IN OUT CHAR16    *Str
   )
@@ -272,11 +353,12 @@ ToLower (
   @param  BufferSize             Size of the buffer in bytes.
 
   @retval EFI_SUCCESS            The function completed successfully.
+  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.
 
 **/
 EFI_STATUS
 EFIAPI
-BufferToHexString (
+BufInReverseOrderToHexString (
   IN OUT CHAR16    *Str,
   IN UINT8         *Buffer,
   IN UINTN         BufferSize
@@ -287,12 +369,15 @@ BufferToHexString (
   UINTN       StrBufferLen;
 
   NewBuffer = AllocateCopyPool (BufferSize, Buffer);
+  if (NewBuffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
   SwapBuffer (NewBuffer, BufferSize);
 
   StrBufferLen = BufferSize * sizeof (CHAR16) + 1;
   Status = BufToHexString (Str, &StrBufferLen, NewBuffer, BufferSize);
 
-  gBS->FreePool (NewBuffer);
+  FreePool (NewBuffer);
   //
   // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
   //
@@ -314,11 +399,13 @@ BufferToHexString (
   @param  Str                    String to be converted from.
 
   @retval EFI_SUCCESS            The function completed successfully.
+  @retval RETURN_BUFFER_TOO_SMALL   The input BufferSize is too small to hold the output. BufferSize
+                                 will be updated to the size required for the converstion.
 
 **/
 EFI_STATUS
 EFIAPI
-HexStringToBuffer (
+HexStringToBufInReverseOrder (
   IN OUT UINT8         *Buffer,
   IN OUT UINTN         *BufferSize,
   IN CHAR16            *Str
@@ -349,11 +436,12 @@ HexStringToBuffer (
                                       If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
   @param ConfigString   Binary representation of Unicode String, <string> := (<HexCh>4)+
 
-  @retval EFI_SUCCESS          Routine success.
+  @retval EFI_SUCCESS          Operation completes successfully.
   @retval EFI_BUFFER_TOO_SMALL The string buffer is too small.
 
 **/
 EFI_STATUS
+EFIAPI
 ConfigStringToUnicode (
   IN OUT CHAR16                *UnicodeString,
   IN OUT UINTN                 *StrBufferLen,
@@ -408,11 +496,12 @@ ConfigStringToUnicode (
                                       If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
   @param  UnicodeString  Original Unicode string.
 
-  @retval EFI_SUCCESS           Routine success.
+  @retval EFI_SUCCESS           Operation completes successfully.
   @retval EFI_BUFFER_TOO_SMALL  The string buffer is too small.
 
 **/
 EFI_STATUS
+EFIAPI
 UnicodeToConfigString (
   IN OUT CHAR16                *ConfigString,
   IN OUT UINTN                 *StrBufferLen,
@@ -469,7 +558,7 @@ UnicodeToConfigString (
   @param  DriverHandle           Driver handle which contains the routing
                                  information: PATH.
 
-  @retval EFI_SUCCESS            Routine success.
+  @retval EFI_SUCCESS            Operation completes successfully.
   @retval EFI_BUFFER_TOO_SMALL   The ConfigHdr string buffer is too small.
 
 **/
@@ -478,7 +567,7 @@ EFIAPI
 ConstructConfigHdr (
   IN OUT CHAR16                *ConfigHdr,
   IN OUT UINTN                 *StrBufferLen,
-  IN EFI_GUID                  *Guid,
+  IN CONST EFI_GUID            *Guid,
   IN CHAR16                    *Name, OPTIONAL
   IN EFI_HANDLE                *DriverHandle
   )
@@ -532,7 +621,7 @@ ConstructConfigHdr (
 
   StrCpy (StrPtr, L"GUID=");
   StrPtr += 5;
-  BufferToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID));
+  BufInReverseOrderToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID));
   StrPtr += 32;
 
   //
@@ -548,7 +637,7 @@ ConstructConfigHdr (
 
   StrCpy (StrPtr, L"&PATH=");
   StrPtr += 6;
-  BufferToHexString (StrPtr, (UINT8 *) DevicePath, DevicePathSize);
+  BufInReverseOrderToHexString (StrPtr, (UINT8 *) DevicePath, DevicePathSize);
 
   return EFI_SUCCESS;
 }
@@ -566,10 +655,11 @@ ConstructConfigHdr (
 
 **/
 BOOLEAN
+EFIAPI
 FindBlockName (
   IN OUT CHAR16                *String,
-  UINTN                        Offset,
-  UINTN                        Width
+  IN UINTN                     Offset,
+  IN UINTN                     Width
   )
 {
   EFI_STATUS  Status;
@@ -630,38 +720,32 @@ FindBlockName (
                                  desired.
   @param  Buffer                 Buffer to hold retrived data.
 
-  @retval EFI_SUCCESS            Routine success.
+  @retval EFI_SUCCESS            Operation completes successfully.
   @retval EFI_BUFFER_TOO_SMALL   The intput buffer is too small.
+  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.
 
 **/
 EFI_STATUS
 EFIAPI
 GetBrowserData (
-  EFI_GUID                   *VariableGuid, OPTIONAL
-  CHAR16                     *VariableName, OPTIONAL
-  UINTN                      *BufferSize,
-  UINT8                      *Buffer
+  IN CONST EFI_GUID              *VariableGuid, OPTIONAL
+  IN CONST CHAR16                *VariableName, OPTIONAL
+  IN OUT UINTN                   *BufferSize,
+  IN OUT UINT8                   *Buffer
   )
 {
   EFI_STATUS                      Status;
-  CHAR16                          *ConfigHdr;
+  CONST CHAR16                    *ConfigHdr;
   CHAR16                          *ConfigResp;
   CHAR16                          *StringPtr;
   UINTN                           HeaderLen;
   UINTN                           BufferLen;
   CHAR16                          *Progress;
-  EFI_FORM_BROWSER2_PROTOCOL      *FormBrowser2;
-  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
 
   //
   // Locate protocols for use
   //
-  Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
+  Status = LocateFormBrowser2Protocols ();
   if (EFI_ERROR (Status)) {
     return Status;
   }
@@ -671,16 +755,22 @@ GetBrowserData (
   //
   ConfigHdr = mFakeConfigHdr;
   HeaderLen = StrLen (ConfigHdr);
-
+  
+  //
+  // First try allocate 0x4000 buffer for the formet storage data.
+  //
   BufferLen = 0x4000;
   ConfigResp = AllocateZeroPool (BufferLen + HeaderLen);
+  if (ConfigResp == NULL) {
+    BufferLen = 0;
+  }
 
   StringPtr = ConfigResp + HeaderLen;
   *StringPtr = L'&';
   StringPtr++;
 
-  Status = FormBrowser2->BrowserCallback (
-                           FormBrowser2,
+  Status = mFormBrowser2->BrowserCallback (
+                           mFormBrowser2,
                            &BufferLen,
                            StringPtr,
                            TRUE,
@@ -688,15 +778,21 @@ GetBrowserData (
                            VariableName
                            );
   if (Status == EFI_BUFFER_TOO_SMALL) {
-    gBS->FreePool (ConfigResp);
+    if (ConfigResp != NULL) {
+      FreePool (ConfigResp);
+    }
+
     ConfigResp = AllocateZeroPool (BufferLen + HeaderLen);
+    if (ConfigResp == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
 
     StringPtr = ConfigResp + HeaderLen;
     *StringPtr = L'&';
     StringPtr++;
 
-    Status = FormBrowser2->BrowserCallback (
-                             FormBrowser2,
+    Status = mFormBrowser2->BrowserCallback (
+                             mFormBrowser2,
                              &BufferLen,
                              StringPtr,
                              TRUE,
@@ -705,7 +801,7 @@ GetBrowserData (
                              );
   }
   if (EFI_ERROR (Status)) {
-    gBS->FreePool (ConfigResp);
+    FreePool (ConfigResp);
     return Status;
   }
   CopyMem (ConfigResp, ConfigHdr, HeaderLen * sizeof (UINT16));
@@ -713,14 +809,14 @@ GetBrowserData (
   //
   // Convert <ConfigResp> to buffer data
   //
-  Status = HiiConfigRouting->ConfigToBlock (
-                               HiiConfigRouting,
+  Status = mHiiConfigRouting->ConfigToBlock (
+                               mHiiConfigRouting,
                                ConfigResp,
                                Buffer,
                                BufferSize,
                                &Progress
                                );
-  gBS->FreePool (ConfigResp);
+  FreePool (ConfigResp);
 
   return Status;
 }
@@ -741,42 +837,36 @@ GetBrowserData (
                                  Browser. <RequestElement> ::=
                                  &OFFSET=<Number>&WIDTH=<Number>*
 
-  @retval EFI_SUCCESS            Routine success.
+  @retval EFI_SUCCESS            Operation completes successfully.
+  @retval EFI_OUT_OF_RESOURCES   There is no enough available memory space.
   @retval Other                  Updating Browser uncommitted data failed.
 
 **/
 EFI_STATUS
 EFIAPI
 SetBrowserData (
-  EFI_GUID                   *VariableGuid, OPTIONAL
-  CHAR16                     *VariableName, OPTIONAL
-  UINTN                      BufferSize,
-  UINT8                      *Buffer,
-  CHAR16                     *RequestElement  OPTIONAL
+  IN CONST EFI_GUID          *VariableGuid, OPTIONAL
+  IN CONST CHAR16            *VariableName, OPTIONAL
+  IN UINTN                   BufferSize,
+  IN CONST UINT8             *Buffer,
+  IN CONST CHAR16            *RequestElement  OPTIONAL
   )
 {
   EFI_STATUS                      Status;
-  CHAR16                          *ConfigHdr;
+  CONST CHAR16                    *ConfigHdr;
   CHAR16                          *ConfigResp;
   CHAR16                          *StringPtr;
   UINTN                           HeaderLen;
   UINTN                           BufferLen;
   CHAR16                          *Progress;
-  EFI_FORM_BROWSER2_PROTOCOL      *FormBrowser2;
-  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
   CHAR16                          BlockName[33];
   CHAR16                          *ConfigRequest;
-  CHAR16                          *Request;
+  CONST CHAR16                    *Request;
 
   //
   // Locate protocols for use
   //
-  Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
+  Status = LocateFormBrowser2Protocols ();
   if (EFI_ERROR (Status)) {
     return Status;
   }
@@ -808,6 +898,9 @@ SetBrowserData (
 
   BufferLen = HeaderLen * sizeof (CHAR16) + StrSize (Request);
   ConfigRequest = AllocateZeroPool (BufferLen);
+  if (ConfigRequest == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
 
   CopyMem (ConfigRequest, ConfigHdr, HeaderLen * sizeof (CHAR16));
   StringPtr = ConfigRequest + HeaderLen;
@@ -816,8 +909,8 @@ SetBrowserData (
   //
   // Convert buffer to <ConfigResp>
   //
-  Status = HiiConfigRouting->BlockToConfig (
-                                HiiConfigRouting,
+  Status = mHiiConfigRouting->BlockToConfig (
+                                mHiiConfigRouting,
                                 ConfigRequest,
                                 Buffer,
                                 BufferSize,
@@ -825,7 +918,7 @@ SetBrowserData (
                                 &Progress
                                 );
   if (EFI_ERROR (Status)) {
-    gBS->FreePool (ConfigResp);
+    FreePool (ConfigRequest);
     return Status;
   }
 
@@ -837,14 +930,14 @@ SetBrowserData (
   //
   // Change uncommitted data in Browser
   //
-  Status = FormBrowser2->BrowserCallback (
-                           FormBrowser2,
+  Status = mFormBrowser2->BrowserCallback (
+                           mFormBrowser2,
                            &BufferSize,
                            StringPtr,
                            FALSE,
                            NULL,
                            NULL
                            );
-  gBS->FreePool (ConfigResp);
+  FreePool (ConfigRequest);
   return Status;
 }