+/**\r
+ Evaluate opcode EFI_IFR_MATCH2.\r
+\r
+ @param FormSet Formset which contains this opcode.\r
+ @param SyntaxType Syntax type for match2.\r
+ @param Result Evaluation result for this opcode.\r
+\r
+ @retval EFI_SUCCESS Opcode evaluation success.\r
+ @retval Other Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrMatch2 (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN EFI_GUID *SyntaxType,\r
+ OUT EFI_HII_VALUE *Result\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_VALUE Value[2];\r
+ CHAR16 *String[2];\r
+ UINTN Index;\r
+ UINTN GuidIndex;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN BufferSize;\r
+ EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol;\r
+ UINTN RegExSyntaxTypeListSize;\r
+ EFI_REGEX_SYNTAX_TYPE *RegExSyntaxTypeList;\r
+ UINTN CapturesCount;\r
+\r
+ //\r
+ // String[0] - The string to search\r
+ // String[1] - pattern\r
+ //\r
+ String[0] = NULL;\r
+ String[1] = NULL;\r
+ HandleBuffer = NULL;\r
+ RegExSyntaxTypeList = NULL;\r
+ Status = EFI_SUCCESS;\r
+ ZeroMem (Value, sizeof (Value));\r
+\r
+ Status = PopExpression (&Value[0]);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Status = PopExpression (&Value[1]);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ for (Index = 0; Index < 2; Index++) {\r
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\r
+ String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle);\r
+ if (String [Index] == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ BufferSize = 0;\r
+ HandleBuffer = NULL;\r
+ Status = gBS->LocateHandle(\r
+ ByProtocol,\r
+ &gEfiRegularExpressionProtocolGuid,\r
+ NULL,\r
+ &BufferSize,\r
+ HandleBuffer);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HandleBuffer = AllocateZeroPool(BufferSize);\r
+ if (HandleBuffer == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ Status = gBS->LocateHandle(\r
+ ByProtocol,\r
+ &gEfiRegularExpressionProtocolGuid,\r
+ NULL,\r
+ &BufferSize,\r
+ HandleBuffer);\r
+\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\r
+ ASSERT (HandleBuffer != NULL);\r
+ for ( Index = 0; Index < BufferSize / sizeof(EFI_HANDLE); Index ++) {\r
+ Status = gBS->HandleProtocol (\r
+ HandleBuffer[Index],\r
+ &gEfiRegularExpressionProtocolGuid,\r
+ (VOID**)&RegularExpressionProtocol\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ RegExSyntaxTypeListSize = 0;\r
+ RegExSyntaxTypeList = NULL;\r
+\r
+ Status = RegularExpressionProtocol->GetInfo (\r
+ RegularExpressionProtocol, \r
+ &RegExSyntaxTypeListSize, \r
+ RegExSyntaxTypeList\r
+ );\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ RegExSyntaxTypeList = AllocateZeroPool(RegExSyntaxTypeListSize);\r
+ if (RegExSyntaxTypeList == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ Status = RegularExpressionProtocol->GetInfo (\r
+ RegularExpressionProtocol, \r
+ &RegExSyntaxTypeListSize, \r
+ RegExSyntaxTypeList\r
+ );\r
+ } else if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ for (GuidIndex = 0; GuidIndex < RegExSyntaxTypeListSize / sizeof(EFI_GUID); GuidIndex++) {\r
+ if (CompareGuid (&RegExSyntaxTypeList[GuidIndex], SyntaxType)) {\r
+ //\r
+ // Find the match type, return the value.\r
+ //\r
+ Result->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ Status = RegularExpressionProtocol->MatchString (\r
+ RegularExpressionProtocol, \r
+ String[0],\r
+ String[1],\r
+ SyntaxType,\r
+ &Result->Value.b,\r
+ NULL,\r
+ &CapturesCount\r
+ );\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ if (RegExSyntaxTypeList != NULL) {\r
+ FreePool (RegExSyntaxTypeList);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Type specified by SyntaxType is not supported \r
+ // in any of the EFI_REGULAR_EXPRESSION_PROTOCOL instances.\r
+ //\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+\r
+Done:\r
+ if (String[0] != NULL) {\r
+ FreePool (String[0]);\r
+ }\r
+ if (String[1] != NULL) {\r
+ FreePool (String[1]);\r
+ }\r
+ if (RegExSyntaxTypeList != NULL) {\r
+ FreePool (RegExSyntaxTypeList);\r
+ }\r
+ if (HandleBuffer != NULL) {\r
+ FreePool (HandleBuffer);\r
+ }\r
+ return Status;\r
+}\r