Esempio n. 1
0
        /// <summary>
        /// Translates IFR logic Opcodes into human readable string
        /// </summary>
        /// <param name="ifrelem">IFR element holding the input data</param>
        /// <returns>Human readable string</returns>
        public string GetIfrLogicString(HiiIfrOpCode ifrelem)
        {
            IfrLogicStack Stack = new IfrLogicStack();
            string        LogicString;

            ParseIfrLogicStack(ifrelem, Stack);

            if (Stack.Elements.Count != 1)
            {
                string StackElements = "";
                foreach (string element in Stack.Elements)
                {
                    StackElements += Environment.NewLine + "   " + element;
                }
                CreateLogEntryParser(LogSeverity.WARNING, "Logic stack has " + Stack.Elements.Count + " elements but must have 1 only [" + ifrelem.UniqueID + "]!" + StackElements);

                StackElements = "INVALIDSTACK(";
                foreach (string element in Stack.Elements)
                {
                    StackElements += element + ",";
                }
                LogicString = StackElements + ")";
            }
            else
            {
                LogicString = Stack.Elements[0];
            }

            return(LogicString);
        }
Esempio n. 2
0
        /// <summary>
        /// Parses IFR logic Opcodes and returns the remaining IFR logic stack
        /// </summary>
        /// <param name="ifrelem">IFR element holding the input data</param>
        /// <param name="Stack">Input: Current stack, Output: Remaining stack</param>
        private void ParseIfrLogicStack(HiiIfrOpCode ifrelem, IfrLogicStack Stack)
        {
            switch (ifrelem.OpCode)
            {
                #region Logic OpCodes
            // Built-in functions:
            // EFI_IFR_DUP // Unclear what it does, therefore no implementation by now. If you know it, let me know ;)
            case EFI_IFR_OPCODE_e.EFI_IFR_EQ_ID_VAL_OP:
            {
                EFI_IFR_EQ_ID_VAL ifr_hdr = (EFI_IFR_EQ_ID_VAL)ifrelem.Header;
                Stack.Push("(ValueOfId(" + ifr_hdr.QuestionId.ToDecimalString(5) + ") == " + ifr_hdr.Value.ToString() + ")");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_EQ_ID_ID_OP:
            {
                EFI_IFR_EQ_ID_ID ifr_hdr = (EFI_IFR_EQ_ID_ID)ifrelem.Header;
                Stack.Push("(ValueOfId(" + ifr_hdr.QuestionId1.ToDecimalString(5) + ") == ValueOfId(" + ifr_hdr.QuestionId2.ToString("#####") + "))");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_EQ_ID_VAL_LIST_OP:
            {
                string ValueListStr = "";
                foreach (IfrTypeUINT16 value in (List <IfrTypeUINT16>)ifrelem.Payload)
                {
                    ValueListStr += value.u16.ToString() + ",";
                }
                Stack.Push("(ValueOfId(" + ((EFI_IFR_EQ_ID_VAL_LIST)ifrelem.Header).QuestionId.ToDecimalString(5) + ") is in [" + ValueListStr + "])");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_GET_OP:
            {
                EFI_IFR_GET ifr_hdr = (EFI_IFR_GET)ifrelem.Header;
                Stack.Push("GetVarValue(Id = " + ifr_hdr.VarStoreId.ToDecimalString(5)
                           + ", Offset/Name = " + ifr_hdr.VarStoreInfo.VarOffset.ToDecimalString(5)
                           + ", Type = " + ifr_hdr.VarStoreType.ToString() + ")");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_QUESTION_REF1_OP: Stack.Push("ValueOfId(" + ((EFI_IFR_QUESTION_REF1)ifrelem.Header).QuestionId.ToDecimalString(5) + ")"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_QUESTION_REF3_OP:
            {
                switch (ifrelem.Header.GetType().Name)
                {
                case "EFI_IFR_QUESTION_REF3": Stack.Push("ValueOfId(" + Stack.Pop() + ")"); break;

                case "EFI_IFR_QUESTION_REF3_2":
                {
                    EFI_IFR_QUESTION_REF3_2 ifr_hdr = (EFI_IFR_QUESTION_REF3_2)ifrelem.Header;
                    Stack.Push("ValueOfId(" + Stack.Pop() + (ifr_hdr.DevicePath == 0 ? "" : ", DevicePath = \"" + GetString(ifr_hdr.DevicePath, ifrelem.UniqueID) + "\"") + ")");
                }
                break;

                case "EFI_IFR_QUESTION_REF3_3":
                {
                    EFI_IFR_QUESTION_REF3_3 ifr_hdr = (EFI_IFR_QUESTION_REF3_3)ifrelem.Header;
                    Stack.Push("ValueOfId(" + Stack.Pop() + ", Guid = " + ifr_hdr.Guid.Guid.ToString() + (ifr_hdr.DevicePath == 0 ? "" : ", DevicePath = \"" + GetString(ifr_hdr.DevicePath, ifrelem.UniqueID) + "\"") + ")");
                }
                break;

                default:
                    Stack.Push("UNKNWONOPCODE(" + ifrelem.OpCode.ToString() + ")");
                    CreateLogEntryParser(LogSeverity.UNIMPLEMENTED, "Logic reference type " + ifrelem.OpCode.ToString() + " [" + ifrelem.UniqueID + "]!");
                    break;
                }
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_RULE_REF_OP: Stack.Push(((EFI_IFR_RULE_REF)ifrelem.Header).RuleId.ToString()); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_STRING_REF1_OP:
            {
                UInt16 StringID = ((EFI_IFR_STRING_REF1)ifrelem.Header).StringId;
                Stack.Push("GetString(Id = " + StringID.ToDecimalString(5) + " [\"" + GetString(StringID, ifrelem.UniqueID) + "\"])");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_THIS_OP: Stack.Push("THIS"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_SECURITY_OP: Stack.Push(((EFI_IFR_SECURITY)ifrelem.Header).Permissions.Guid.ToString()); break;

            // Constants
            case EFI_IFR_OPCODE_e.EFI_IFR_FALSE_OP: Stack.Push("FALSE"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_ONE_OP: Stack.Push("1"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_ONES_OP: Stack.Push("0xFFFFFFFFFFFFFFFF"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_TRUE_OP: Stack.Push("TRUE"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_UINT8_OP: Stack.Push("0x" + ((EFI_IFR_UINT8)ifrelem.Header).Value.ToString("X2")); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_UINT16_OP: Stack.Push("0x" + ((EFI_IFR_UINT16)ifrelem.Header).Value.ToString("X4")); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_UINT32_OP: Stack.Push("0x" + ((EFI_IFR_UINT32)ifrelem.Header).Value.ToString("X8")); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_UINT64_OP: Stack.Push("0x" + ((EFI_IFR_UINT64)ifrelem.Header).Value.ToString("X16")); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_UNDEFINED_OP: Stack.Push("Undefined"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_VERSION_OP: Stack.Push("GetUefiVersion()"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_ZERO_OP: Stack.Push("0"); break;

            // Binary operations
            case EFI_IFR_OPCODE_e.EFI_IFR_ADD_OP: Stack.Op21("+"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_AND_OP: Stack.Op12("&&"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_BITWISE_AND_OP: Stack.Op12("&"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_BITWISE_OR_OP: Stack.Op12("|"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_CATENATE_OP:
            {
                string str1 = Stack.Pop();
                string str2 = Stack.Pop();
                Stack.Push("Concat(" + str1 + " , " + str2 + ")");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_DIVIDE_OP: Stack.Op21("/"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_EQUAL_OP: Stack.Op12("=="); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_GREATER_EQUAL_OP: Stack.Op12(">="); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_GREATER_THAN_OP: Stack.Op12(">"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_LESS_EQUAL_OP: Stack.Op12("<="); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_LESS_THAN_OP: Stack.Op12("<"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_MATCH_OP:
            {
                string str1 = Stack.Pop();
                string str2 = Stack.Pop();
                Stack.Push("Match(" + str1 + " /w pattern " + str2 + ")");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_MATCH2_OP:
            {
                string str1 = Stack.Pop();
                string str2 = Stack.Pop();
                Stack.Push("Match(" + str1 + " /w regex " + str2 + " syntax " + ((EFI_IFR_MATCH2)ifrelem.Header).SyntaxType.Guid.ToString() + ")");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_MODULO_OP: Stack.Op21("%"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_MULTIPLY_OP: Stack.Op21("*"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_NOT_EQUAL_OP: Stack.Op12("!="); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_OR_OP: Stack.Op12("||"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_SHIFT_LEFT_OP: Stack.Op21("<<"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_SHIFT_RIGHT_OP: Stack.Op21("<<"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_SUBTRACT_OP: Stack.Op21("-"); break;

            // Unary operations
            case EFI_IFR_OPCODE_e.EFI_IFR_LENGTH_OP: Stack.Push("Length(" + Stack.Pop() + ")"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_NOT_OP: Stack.Push("!" + Stack.Pop()); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_BITWISE_NOT_OP: Stack.Push("~" + Stack.Pop()); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_QUESTION_REF2_OP: Stack.Push("ValueOfId(" + Stack.Pop() + ")"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_SET_OP:
            {
                EFI_IFR_SET ifr_hdr = (EFI_IFR_SET)ifrelem.Header;
                Stack.Push("SetVarValue(Id = " + ifr_hdr.VarStoreId.ToDecimalString(5)
                           + ", Offset/Name = " + ifr_hdr.VarStoreInfo.VarOffset.ToDecimalString(5)
                           + ", Type = " + ifr_hdr.VarStoreType.ToString()
                           + ", Value = (" + Stack.Pop() + "))");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_STRING_REF2_OP:
            {
                UInt16 StringID;
                string expr = Stack.Pop();
                if (UInt16.TryParse(expr, out StringID))
                {
                    Stack.Push("GetString(Id = " + StringID.ToDecimalString(5) + " [\"" + GetString(StringID, ifrelem.UniqueID) + "\"])");
                }
                else
                {
                    Stack.Push("GetString(Id = (" + expr + "))");
                }
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_TO_BOOLEAN_OP: Stack.Push("ToBoolen(" + Stack.Pop() + ")"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_TO_STRING_OP: Stack.Push("ToString((" + Stack.Pop() + ")), Format = 0x" + ((EFI_IFR_TO_STRING)ifrelem.Header).Format.ToString("X2") + ")"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_TO_UINT_OP: Stack.Push("ToUint(" + Stack.Pop() + ")"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_TO_UPPER_OP: Stack.Push("ToUpper(" + Stack.Pop() + ")"); break;

            case EFI_IFR_OPCODE_e.EFI_IFR_TO_LOWER_OP: Stack.Push("ToLower(" + Stack.Pop() + ")"); break;

            // -- ternary-op
            case EFI_IFR_OPCODE_e.EFI_IFR_CONDITIONAL_OP:
            {
                string expr1 = Stack.Pop();
                string expr2 = Stack.Pop();
                string expr3 = Stack.Pop();
                Stack.Push("(" + expr3 + " ? " + expr1 + " : " + expr2 + ")");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_FIND_OP:
            {
                string expr1 = Stack.Pop();
                string expr2 = Stack.Pop();
                string expr3 = Stack.Pop();
                Stack.Push("Find(" + expr3 + " in " + expr2 + ", Start = " + expr1 + ", Format = " + ((EFI_IFR_FIND)ifrelem.Header).Format.ToString() + ")");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_MID_OP:
            {
                string expr1 = Stack.Pop();
                string expr2 = Stack.Pop();
                string expr3 = Stack.Pop();
                Stack.Push("Mid(" + expr3 + ", Start = " + expr2 + ", Length = " + expr1 + ")");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_TOKEN_OP:
            {
                string expr1 = Stack.Pop();
                string expr2 = Stack.Pop();
                string expr3 = Stack.Pop();
                Stack.Push("Token(" + expr3 + ", Delimiters = " + expr2 + ", return #" + expr1 + ")");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_SPAN_OP:
            {
                string expr1 = Stack.Pop();
                string expr2 = Stack.Pop();
                string expr3 = Stack.Pop();
                Stack.Push("Span(" + expr3 + ", FromToCharPairs = " + expr2 + ", Start = " + expr1 + ", Flags = " + ((EFI_IFR_SPAN)ifrelem.Header).Flags.ToString() + ")");
            }
            break;

            case EFI_IFR_OPCODE_e.EFI_IFR_MAP_OP:
            {
                string expr = Stack.Pop();
                if ((ifrelem.Childs.Count % 2) != 0)
                {
                    Stack.Push("INVALIDOPCODEPARAMETERS(" + ifrelem.OpCode.ToString() + ", Value = " + expr + ")");
                    CreateLogEntryParser(LogSeverity.WARNING, "Map has invalid expression pairs [" + ifrelem.UniqueID + "]!");
                }
                else
                {
                    string result = "Switch(" + expr;
                    for (int i = 0; i < ifrelem.Childs.Count; i += 2)                                    // for each expression pair
                    {
                        result += ", {" + GetIfrLogicString((HiiIfrOpCode)ifrelem.Childs[i])             // Match expression
                                  + ", " + GetIfrLogicString((HiiIfrOpCode)ifrelem.Childs[i + 1]) + "}"; // Result expression
                    }
                    result += ")";
                    Stack.Push(result);
                }
            }
            break;

                #endregion
            case EFI_IFR_OPCODE_e.EFI_IFR_VALUE_OP: break;     // Nothing to show, the value is nested..

            case EFI_IFR_OPCODE_e.EFI_IFR_END_OP: return;

            default:
                Stack.Push("UNKNWONOPCODE(" + ifrelem.OpCode.ToString() + ")");
                CreateLogEntryParser(LogSeverity.UNIMPLEMENTED, "Logic OpCode " + ifrelem.OpCode.ToString() + " [" + ifrelem.UniqueID + "]!");
                break;
            }

            if (ifrelem.HasOwnScope)
            {
                foreach (HiiIfrOpCode child in ifrelem.Childs)
                {
                    ParseIfrLogicStack(child, Stack);
                }
            }
        }