]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c
MdeModulePkg/Core: Decorate phase-transition functions with NORETURN.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / SectionExtraction / CoreSectionExtraction.c
index 8d8f9c8641d00b3f38a87013708dd84d13b2365e..3c4f3f58dbc1b8587ffff02e228d155c0d05131b 100644 (file)
@@ -27,7 +27,7 @@
   3) A support protocol is not found, and the data is not available to be read\r
      without it.  This results in EFI_PROTOCOL_ERROR.\r
 \r
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -66,6 +66,11 @@ typedef struct {
   //\r
   UINTN                       EncapsulatedStreamHandle;\r
   EFI_GUID                    *EncapsulationGuid;\r
+  //\r
+  // If the section REQUIRES an extraction protocol, register for RPN \r
+  // when the required GUIDed extraction protocol becomes available.\r
+  //\r
+  EFI_EVENT                   Event;\r
 } CORE_SECTION_CHILD_NODE;\r
 \r
 #define CORE_SECTION_STREAM_SIGNATURE SIGNATURE_32('S','X','S','S')\r
@@ -91,7 +96,6 @@ typedef struct {
   CORE_SECTION_CHILD_NODE     *ChildNode;\r
   CORE_SECTION_STREAM_NODE    *ParentStream;\r
   VOID                        *Registration;\r
-  EFI_EVENT                   Event;\r
 } RPN_EVENT_CONTEXT;\r
 \r
 \r
@@ -436,7 +440,7 @@ OpenSectionStream (
   return OpenSectionStreamEx (\r
            SectionStreamLength,\r
            SectionStream,\r
-           TRUE,\r
+           FALSE,\r
            0,\r
            SectionStreamHandle\r
            );\r
@@ -486,6 +490,55 @@ ChildIsType (
   }\r
 }\r
 \r
+/**\r
+  Verify the Guided Section GUID by checking if there is the Guided Section GUID configuration table recorded the GUID itself.\r
+\r
+  @param GuidedSectionGuid          The Guided Section GUID.\r
+  @param GuidedSectionExtraction    A pointer to the pointer to the supported Guided Section Extraction Protocol\r
+                                    for the Guided Section.\r
+\r
+  @return TRUE      The GuidedSectionGuid could be identified, and the pointer to\r
+                    the Guided Section Extraction Protocol will be returned to *GuidedSectionExtraction.\r
+  @return FALSE     The GuidedSectionGuid could not be identified, or \r
+                    the Guided Section Extraction Protocol has not been installed yet.\r
+\r
+**/\r
+BOOLEAN\r
+VerifyGuidedSectionGuid (\r
+  IN  EFI_GUID                                  *GuidedSectionGuid,\r
+  OUT EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL    **GuidedSectionExtraction\r
+  )\r
+{\r
+  EFI_GUID              *GuidRecorded;\r
+  VOID                  *Interface;\r
+  EFI_STATUS            Status;\r
+\r
+  Interface = NULL;\r
+\r
+  //\r
+  // Check if there is the Guided Section GUID configuration table recorded the GUID itself.\r
+  //\r
+  Status = EfiGetSystemConfigurationTable (GuidedSectionGuid, (VOID **) &GuidRecorded);\r
+  if (Status == EFI_SUCCESS) {\r
+    if (CompareGuid (GuidRecorded, GuidedSectionGuid)) {\r
+      //\r
+      // Found the recorded GuidedSectionGuid.\r
+      //\r
+      Status = CoreLocateProtocol (GuidedSectionGuid, NULL, (VOID **) &Interface);\r
+      if (!EFI_ERROR (Status) && Interface != NULL) {\r
+        //\r
+        // Found the supported Guided Section Extraction Porotocol for the Guided Section.\r
+        //\r
+        *GuidedSectionExtraction = (EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *) Interface;\r
+        return TRUE;\r
+      }\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
 /**\r
   RPN callback function. Initializes the section stream\r
   when GUIDED_SECTION_EXTRACTION_PROTOCOL is installed.\r
@@ -513,12 +566,11 @@ NotifyGuidedExtraction (
   \r
   GuidedHeader = (EFI_GUID_DEFINED_SECTION *) (Context->ParentStream->StreamBuffer + Context->ChildNode->OffsetInStream);\r
   ASSERT (GuidedHeader->CommonHeader.Type == EFI_SECTION_GUID_DEFINED);\r
-  \r
-  Status = gBS->LocateProtocol (Context->ChildNode->EncapsulationGuid, NULL, (VOID **)&GuidedExtraction);\r
-  if (EFI_ERROR (Status)) {\r
+\r
+  if (!VerifyGuidedSectionGuid (Context->ChildNode->EncapsulationGuid, &GuidedExtraction)) {\r
     return;\r
   }\r
-  \r
+\r
   Status = GuidedExtraction->ExtractSection (\r
                                GuidedExtraction,\r
                                GuidedHeader,\r
@@ -558,6 +610,7 @@ NotifyGuidedExtraction (
   //  Close the event when done.\r
   //\r
   gBS->CloseEvent (Event);\r
+  Context->ChildNode->Event = NULL;\r
   FreePool (Context);\r
 }  \r
 \r
@@ -585,13 +638,13 @@ CreateGuidedExtractionRpnEvent (
   Context->ChildNode = ChildNode;\r
   Context->ParentStream = ParentStream;\r
  \r
-  Context->Event = EfiCreateProtocolNotifyEvent (\r
-                    Context->ChildNode->EncapsulationGuid,\r
-                    TPL_NOTIFY,\r
-                    NotifyGuidedExtraction,\r
-                    Context,\r
-                    &Context->Registration\r
-                    );\r
+  Context->ChildNode->Event = EfiCreateProtocolNotifyEvent (\r
+                                Context->ChildNode->EncapsulationGuid,\r
+                                TPL_NOTIFY,\r
+                                NotifyGuidedExtraction,\r
+                                Context,\r
+                                &Context->Registration\r
+                                );\r
 }\r
 \r
 /**\r
@@ -646,7 +699,7 @@ CreateChildNode (
   //\r
   // Allocate a new node\r
   //\r
-  *ChildNode = AllocatePool (sizeof (CORE_SECTION_CHILD_NODE));\r
+  *ChildNode = AllocateZeroPool (sizeof (CORE_SECTION_CHILD_NODE));\r
   Node = *ChildNode;\r
   if (Node == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -788,8 +841,7 @@ CreateChildNode (
         Node->EncapsulationGuid = &GuidedHeader->SectionDefinitionGuid;\r
         GuidedSectionAttributes = GuidedHeader->Attributes;\r
       }\r
-      Status = CoreLocateProtocol (Node->EncapsulationGuid, NULL, (VOID **)&GuidedExtraction);\r
-      if (!EFI_ERROR (Status) && GuidedExtraction != NULL) {\r
+      if (VerifyGuidedSectionGuid (Node->EncapsulationGuid, &GuidedExtraction)) {\r
         //\r
         // NewStreamBuffer is always allocated by ExtractSection... No caller\r
         // allocation here.\r
@@ -851,6 +903,10 @@ CreateChildNode (
           //\r
           AuthenticationStatus = Stream->AuthenticationStatus;\r
 \r
+          if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {\r
+            AuthenticationStatus |= EFI_AUTH_STATUS_IMAGE_SIGNED | EFI_AUTH_STATUS_NOT_TESTED;\r
+          }\r
+\r
           if (IS_SECTION2 (GuidedHeader)) {\r
             Status = OpenSectionStreamEx (\r
                        SECTION2_SIZE (GuidedHeader) - ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->DataOffset,\r
@@ -1179,6 +1235,7 @@ GetSection (
   EFI_COMMON_SECTION_HEADER                             *Section;\r
 \r
 \r
+  ChildStreamNode = NULL;\r
   OldTpl = CoreRaiseTpl (TPL_NOTIFY);\r
   Instance = SectionInstance + 1;\r
 \r
@@ -1287,8 +1344,13 @@ FreeChildNode (
     // If it's an encapsulating section, we close the resulting section stream.\r
     // CloseSectionStream will free all memory associated with the stream.\r
     //\r
-    CloseSectionStream (ChildNode->EncapsulatedStreamHandle);\r
+    CloseSectionStream (ChildNode->EncapsulatedStreamHandle, TRUE);\r
   }\r
+\r
+  if (ChildNode->Event != NULL) {\r
+    gBS->CloseEvent (ChildNode->Event);\r
+  }\r
+\r
   //\r
   // Last, free the child node itself\r
   //\r
@@ -1300,6 +1362,8 @@ FreeChildNode (
   SEP member function.  Deletes an existing section stream\r
 \r
   @param  StreamHandleToClose    Indicates the stream to close\r
+  @param  FreeStreamBuffer       TRUE - Need to free stream buffer;\r
+                                 FALSE - No need to free stream buffer.\r
 \r
   @retval EFI_SUCCESS            The section stream is closed sucessfully.\r
   @retval EFI_OUT_OF_RESOURCES   Memory allocation failed.\r
@@ -1310,7 +1374,8 @@ FreeChildNode (
 EFI_STATUS\r
 EFIAPI\r
 CloseSectionStream (\r
-  IN  UINTN                                     StreamHandleToClose\r
+  IN  UINTN                                     StreamHandleToClose,\r
+  IN  BOOLEAN                                   FreeStreamBuffer\r
   )\r
 {\r
   CORE_SECTION_STREAM_NODE                      *StreamNode;\r
@@ -1335,7 +1400,9 @@ CloseSectionStream (
       ChildNode = CHILD_SECTION_NODE_FROM_LINK (Link);\r
       FreeChildNode (ChildNode);\r
     }\r
-    CoreFreePool (StreamNode->StreamBuffer);\r
+    if (FreeStreamBuffer) {\r
+      CoreFreePool (StreamNode->StreamBuffer);\r
+    }\r
     CoreFreePool (StreamNode);\r
     Status = EFI_SUCCESS;\r
   } else {\r