+EFI_STATUS\r
+SearchSectionByType (\r
+ IN EFI_FILE_SECTION_POINTER FirstSection,\r
+ IN UINT8 *SearchEnd,\r
+ IN EFI_SECTION_TYPE SectionType,\r
+ IN OUT UINTN *StartIndex,\r
+ IN UINTN Instance,\r
+ OUT EFI_FILE_SECTION_POINTER *Section\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Helper function to search a sequence of sections from the section pointed\r
+ by FirstSection to SearchEnd for the Instance-th section of type SectionType.\r
+ The current counter is saved in StartIndex and when the section is found, it's\r
+ saved in Section. GUID-defined sections, if special processing is not required,\r
+ are searched recursively in a depth-first manner.\r
+\r
+Arguments:\r
+\r
+ FirstSection The first section to start searching from.\r
+ SearchEnd The end address to stop search.\r
+ SectionType The type of section to search.\r
+ StartIndex The current counter is saved.\r
+ Instance The requested n-th section number.\r
+ Section The found section returned.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS The function completed successfully.\r
+ EFI_NOT_FOUND The section is not found.\r
+--*/\r
+{\r
+ EFI_FILE_SECTION_POINTER CurrentSection;\r
+ EFI_FILE_SECTION_POINTER InnerSection;\r
+ EFI_STATUS Status;\r
+ UINTN SectionSize;\r
+\r
+ CurrentSection = FirstSection;\r
+\r
+ while ((UINTN) CurrentSection.CommonHeader < (UINTN) SearchEnd) {\r
+ if (CurrentSection.CommonHeader->Type == SectionType) {\r
+ (*StartIndex)++;\r
+ }\r
+\r
+ if (*StartIndex == Instance) {\r
+ *Section = CurrentSection;\r
+ return EFI_SUCCESS;\r
+ }\r
+ //\r
+ // If the requesting section is not GUID-defined and\r
+ // we find a GUID-defined section that doesn't need\r
+ // special processing, go ahead to search the requesting\r
+ // section inside the GUID-defined section.\r
+ //\r
+ if (SectionType != EFI_SECTION_GUID_DEFINED &&\r
+ CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED &&\r
+ !(CurrentSection.GuidDefinedSection->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {\r
+ InnerSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *)\r
+ ((UINTN) CurrentSection.CommonHeader + CurrentSection.GuidDefinedSection->DataOffset);\r
+ SectionSize = CurrentSection.CommonHeader->Size[0] +\r
+ (CurrentSection.CommonHeader->Size[1] << 8) + \r
+ (CurrentSection.CommonHeader->Size[2] << 16);\r
+ Status = SearchSectionByType (\r
+ InnerSection,\r
+ (UINT8 *) ((UINTN) CurrentSection.CommonHeader + SectionSize),\r
+ SectionType,\r
+ StartIndex,\r
+ Instance,\r
+ Section\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ //\r
+ // Find next section (including compensating for alignment issues.\r
+ //\r
+ CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r