예제 #1
0
        //
        //  This helper converts a serialized CFG grammar header into an in-memory header
        //
        internal static ScriptRef[] LoadScriptRefs(StreamMarshaler streamHelper, CfgSerializedHeader pFH)
        {
            //
            //  Because in 64-bit code, pointers != sizeof(ULONG) we copy each member explicitly.
            //
            if (pFH.FormatId != CfgGrammar._SPGDF_ContextFree)
            {
                return(null);
            }

            //We know that in SAPI 5.0 grammar format pszWords follows header immediately.
            if (pFH.pszWords < Marshal.SizeOf <CfgSerializedHeader>())
            {
                // Must be SAPI 6.0 or above to hold a .NET script
                return(null);
            }

            // Get the symbols
            StringBlob symbols = LoadStringBlob(streamHelper, pFH.pszSymbols, pFH.cchSymbols);

            // Get the script refs
            CfgScriptRef[] cfgScripts = Load <CfgScriptRef>(streamHelper, pFH.pScripts, pFH.cScripts);

            // Convert the CFG script reference to ScriptRef
            ScriptRef[] scripts = new ScriptRef[cfgScripts.Length];
            for (int i = 0; i < cfgScripts.Length; i++)
            {
                CfgScriptRef cfgScript = cfgScripts[i];
                scripts[i] = new ScriptRef(symbols[cfgScript._idRule], symbols[cfgScript._idMethod], cfgScript._method);
            }

            return(scripts);
        }
예제 #2
0
 internal static ScriptRef[] LoadIL(Stream stream)
 {
     using (StreamMarshaler streamMarshaler = new StreamMarshaler(stream))
     {
         CfgSerializedHeader cfgSerializedHeader = new CfgSerializedHeader();
         streamMarshaler.ReadStream(cfgSerializedHeader);
         return(LoadScriptRefs(streamMarshaler, cfgSerializedHeader));
     }
 }
예제 #3
0
        private static void CheckValidCfgFormat(CfgSerializedHeader pFH, CfgHeader header, bool includeAllGrammarData)
        {
            if (pFH.pszWords < 100)
            {
                XmlParser.ThrowSrgsException(SRID.UnsupportedFormat);
            }
            int start = (int)pFH.pszWords;

            CheckSetOffsets(pFH.pszWords, pFH.cchWords * 2, ref start, pFH.ulTotalSerializedSize);
            CheckSetOffsets(pFH.pszSymbols, pFH.cchSymbols * 2, ref start, pFH.ulTotalSerializedSize);
            if (pFH.cRules > 0)
            {
                CheckSetOffsets(pFH.pRules, pFH.cRules * Marshal.SizeOf(typeof(CfgRule)), ref start, pFH.ulTotalSerializedSize);
            }
            if (pFH.cArcs > 0)
            {
                CheckSetOffsets(pFH.pArcs, pFH.cArcs * Marshal.SizeOf(typeof(CfgArc)), ref start, pFH.ulTotalSerializedSize);
            }
            if (pFH.pWeights != 0)
            {
                CheckSetOffsets(pFH.pWeights, pFH.cArcs * Marshal.SizeOf(typeof(float)), ref start, pFH.ulTotalSerializedSize);
            }
            if (pFH.cTags > 0)
            {
                CheckSetOffsets(pFH.tags, pFH.cTags * Marshal.SizeOf(typeof(CfgSemanticTag)), ref start, pFH.ulTotalSerializedSize);
                if (includeAllGrammarData)
                {
                    for (int i = 0; i < header.tags.Length; i++)
                    {
                        int startArcIndex = (int)header.tags[i].StartArcIndex;
                        int endArcIndex   = (int)header.tags[i].EndArcIndex;
                        int num           = header.arcs.Length;
                        if (startArcIndex == 0 || startArcIndex >= num || endArcIndex == 0 || endArcIndex >= num || (header.tags[i].PropVariantType != 0 && header.tags[i].PropVariantType == VarEnum.VT_BSTR && header.tags[i].PropVariantType == VarEnum.VT_BOOL && header.tags[i].PropVariantType == VarEnum.VT_R8 && header.tags[i].PropVariantType == VarEnum.VT_I4))
                        {
                            XmlParser.ThrowSrgsException(SRID.UnsupportedFormat);
                        }
                    }
                }
            }
            if (pFH.cScripts > 0)
            {
                CheckSetOffsets(pFH.pScripts, pFH.cScripts * Marshal.SizeOf(typeof(CfgScriptRef)), ref start, pFH.ulTotalSerializedSize);
            }
            if (pFH.cIL > 0)
            {
                CheckSetOffsets(pFH.pIL, pFH.cIL * Marshal.SizeOf(typeof(byte)), ref start, pFH.ulTotalSerializedSize);
            }
            if (pFH.cPDB > 0)
            {
                CheckSetOffsets(pFH.pPDB, pFH.cPDB * Marshal.SizeOf(typeof(byte)), ref start, pFH.ulTotalSerializedSize);
            }
        }
예제 #4
0
        internal static CfgHeader ConvertCfgHeader(StreamMarshaler streamHelper, bool includeAllGrammarData, bool loadSymbols, out CfgSerializedHeader cfgSerializedHeader)
        {
            cfgSerializedHeader = new CfgSerializedHeader(streamHelper.Stream);
            CfgHeader cfgHeader = default(CfgHeader);

            cfgHeader.FormatId            = cfgSerializedHeader.FormatId;
            cfgHeader.GrammarGUID         = cfgSerializedHeader.GrammarGUID;
            cfgHeader.langId              = cfgSerializedHeader.LangID;
            cfgHeader.pszGlobalTags       = cfgSerializedHeader.pszSemanticInterpretationGlobals;
            cfgHeader.cArcsInLargestState = cfgSerializedHeader.cArcsInLargestState;
            cfgHeader.rules = Load <CfgRule>(streamHelper, cfgSerializedHeader.pRules, cfgSerializedHeader.cRules);
            if (includeAllGrammarData || loadSymbols)
            {
                cfgHeader.pszSymbols = LoadStringBlob(streamHelper, cfgSerializedHeader.pszSymbols, cfgSerializedHeader.cchSymbols);
            }
            if (includeAllGrammarData)
            {
                cfgHeader.pszWords = LoadStringBlob(streamHelper, cfgSerializedHeader.pszWords, cfgSerializedHeader.cchWords);
                cfgHeader.arcs     = Load <CfgArc>(streamHelper, cfgSerializedHeader.pArcs, cfgSerializedHeader.cArcs);
                cfgHeader.tags     = Load <CfgSemanticTag>(streamHelper, cfgSerializedHeader.tags, cfgSerializedHeader.cTags);
                cfgHeader.weights  = Load <float>(streamHelper, cfgSerializedHeader.pWeights, cfgSerializedHeader.cArcs);
            }
            if (cfgSerializedHeader.pszWords < Marshal.SizeOf(typeof(CfgSerializedHeader)))
            {
                cfgHeader.ulRootRuleIndex = uint.MaxValue;
                cfgHeader.GrammarOptions  = GrammarOptions.KeyValuePairs;
                cfgHeader.BasePath        = null;
                cfgHeader.GrammarMode     = GrammarType.VoiceGrammar;
            }
            else
            {
                cfgHeader.ulRootRuleIndex = cfgSerializedHeader.ulRootRuleIndex;
                cfgHeader.GrammarOptions  = cfgSerializedHeader.GrammarOptions;
                cfgHeader.GrammarMode     = (GrammarType)cfgSerializedHeader.GrammarMode;
                if (includeAllGrammarData)
                {
                    cfgHeader.scripts = Load <CfgScriptRef>(streamHelper, cfgSerializedHeader.pScripts, cfgSerializedHeader.cScripts);
                }
                if (cfgSerializedHeader.cBasePath != 0)
                {
                    streamHelper.Stream.Position = (int)cfgSerializedHeader.pRules + cfgHeader.rules.Length * Marshal.SizeOf(typeof(CfgRule));
                    cfgHeader.BasePath           = streamHelper.ReadNullTerminatedString();
                }
            }
            CheckValidCfgFormat(cfgSerializedHeader, cfgHeader, includeAllGrammarData);
            return(cfgHeader);
        }
예제 #5
0
        internal static ScriptRef[] LoadScriptRefs(StreamMarshaler streamHelper, CfgSerializedHeader pFH)
        {
            if (pFH.FormatId != _SPGDF_ContextFree)
            {
                return(null);
            }
            if (pFH.pszWords < Marshal.SizeOf(typeof(CfgSerializedHeader)))
            {
                return(null);
            }
            StringBlob stringBlob = LoadStringBlob(streamHelper, pFH.pszSymbols, pFH.cchSymbols);

            CfgScriptRef[] array  = Load <CfgScriptRef>(streamHelper, pFH.pScripts, pFH.cScripts);
            ScriptRef[]    array2 = new ScriptRef[array.Length];
            for (int i = 0; i < array.Length; i++)
            {
                CfgScriptRef cfgScriptRef = array[i];
                array2[i] = new ScriptRef(stringBlob[cfgScriptRef._idRule], stringBlob[cfgScriptRef._idMethod], cfgScriptRef._method);
            }
            return(array2);
        }
예제 #6
0
 internal static bool LoadIL(Stream stream, out byte[] assemblyContent, out byte[] assemblyDebugSymbols, out ScriptRef[] scripts)
 {
     assemblyContent = (assemblyDebugSymbols = null);
     scripts         = null;
     using (StreamMarshaler streamMarshaler = new StreamMarshaler(stream))
     {
         CfgSerializedHeader cfgSerializedHeader = new CfgSerializedHeader();
         streamMarshaler.ReadStream(cfgSerializedHeader);
         scripts = LoadScriptRefs(streamMarshaler, cfgSerializedHeader);
         if (scripts == null)
         {
             return(false);
         }
         if (cfgSerializedHeader.cIL == 0)
         {
             return(false);
         }
         assemblyContent      = Load <byte>(streamMarshaler, cfgSerializedHeader.pIL, cfgSerializedHeader.cIL);
         assemblyDebugSymbols = ((cfgSerializedHeader.cPDB > 0) ? Load <byte>(streamMarshaler, cfgSerializedHeader.pPDB, cfgSerializedHeader.cPDB) : null);
     }
     return(true);
 }
예제 #7
0
        private static void CheckValidCfgFormat(CfgSerializedHeader pFH, CfgHeader header, bool includeAllGrammarData)
        {
            //See backend commit method to understand the layout of cfg format
            if (pFH.pszWords < SP_SPCFGSERIALIZEDHEADER_500)
            {
                XmlParser.ThrowSrgsException(SRID.UnsupportedFormat);
            }

            int ullStartOffset = (int)pFH.pszWords;

            //Check the word offset
            //See stringblob implementation. pFH.cchWords * sizeof(WCHAR) isn't exactly the serialized size, but it is close and must be less than the serialized size
            CheckSetOffsets(pFH.pszWords, pFH.cchWords * Helpers._sizeOfChar, ref ullStartOffset, pFH.ulTotalSerializedSize);

            //Check the symbol offset
            //symbol is right after word
            //pFH.pszSymbols is very close to pFH.pszWords + pFH.cchWords * sizeof(WCHAR)
            CheckSetOffsets(pFH.pszSymbols, pFH.cchSymbols * Helpers._sizeOfChar, ref ullStartOffset, pFH.ulTotalSerializedSize);

            //Check the rule offset
            if (pFH.cRules > 0)
            {
                CheckSetOffsets(pFH.pRules, pFH.cRules * Marshal.SizeOf <CfgRule>(), ref ullStartOffset, pFH.ulTotalSerializedSize);
            }

            //Check the arc offset
            if (pFH.cArcs > 0)
            {
                CheckSetOffsets(pFH.pArcs, pFH.cArcs * Marshal.SizeOf <CfgArc>(), ref ullStartOffset, pFH.ulTotalSerializedSize);
            }

            //Check the weight offset
            if (pFH.pWeights > 0)
            {
                CheckSetOffsets(pFH.pWeights, pFH.cArcs * sizeof(float), ref ullStartOffset, pFH.ulTotalSerializedSize);
            }

            //Check the semantic tag offset
            if (pFH.cTags > 0)
            {
                CheckSetOffsets(pFH.tags, pFH.cTags * Marshal.SizeOf <CfgSemanticTag>(), ref ullStartOffset, pFH.ulTotalSerializedSize);

                if (includeAllGrammarData)
                {
                    //Validate the SPCFGSEMANTICTAG array pointed to by tags
                    //We use header for easy array access
                    //The first arc is dummy, so the start and end arcindex for semantic tag won't be zero
                    for (int i = 0; i < header.tags.Length; i++)
                    {
                        int startArc = (int)header.tags[i].StartArcIndex;
                        int endArc   = (int)header.tags[i].EndArcIndex;
                        int cArcs    = header.arcs.Length;
#pragma warning disable 0618 // VarEnum is obsolete
                        if (startArc == 0 ||
                            startArc >= cArcs ||
                            endArc == 0 ||
                            endArc >= cArcs ||
                            (
                                header.tags[i].PropVariantType != VarEnum.VT_EMPTY &&
                                header.tags[i].PropVariantType != VarEnum.VT_BSTR &&
                                header.tags[i].PropVariantType != VarEnum.VT_BOOL &&
                                header.tags[i].PropVariantType != VarEnum.VT_R8 &&
                                header.tags[i].PropVariantType != VarEnum.VT_I4)
                            )
                        {
                            XmlParser.ThrowSrgsException(SRID.UnsupportedFormat);
                        }
#pragma warning restore 0618
                    }
                }
            }

            //Check the offset for the scripts
            if (pFH.cScripts > 0)
            {
                CheckSetOffsets(pFH.pScripts, pFH.cScripts * Marshal.SizeOf <CfgScriptRef>(), ref ullStartOffset, pFH.ulTotalSerializedSize);
            }

            if (pFH.cIL > 0)
            {
                CheckSetOffsets(pFH.pIL, pFH.cIL * sizeof(byte), ref ullStartOffset, pFH.ulTotalSerializedSize);
            }

            if (pFH.cPDB > 0)
            {
                CheckSetOffsets(pFH.pPDB, pFH.cPDB * sizeof(byte), ref ullStartOffset, pFH.ulTotalSerializedSize);
            }
        }
예제 #8
0
        internal static CfgHeader ConvertCfgHeader(StreamMarshaler streamHelper, bool includeAllGrammarData, bool loadSymbols, out CfgSerializedHeader cfgSerializedHeader)
        {
            cfgSerializedHeader = new CfgSerializedHeader(streamHelper.Stream);

            //
            //  Because in 64-bit code, pointers != sizeof(ULONG) we copy each member explicitly.
            //

            CfgHeader header = new();

            header.FormatId            = cfgSerializedHeader.FormatId;
            header.GrammarGUID         = cfgSerializedHeader.GrammarGUID;
            header.langId              = cfgSerializedHeader.LangID;
            header.pszGlobalTags       = cfgSerializedHeader.pszSemanticInterpretationGlobals;
            header.cArcsInLargestState = cfgSerializedHeader.cArcsInLargestState;

            // read all the common fields
            header.rules = Load <CfgRule>(streamHelper, cfgSerializedHeader.pRules, cfgSerializedHeader.cRules);

            if (includeAllGrammarData || loadSymbols)
            {
                header.pszSymbols = LoadStringBlob(streamHelper, cfgSerializedHeader.pszSymbols, cfgSerializedHeader.cchSymbols);
            }

            if (includeAllGrammarData)
            {
                header.pszWords = LoadStringBlob(streamHelper, cfgSerializedHeader.pszWords, cfgSerializedHeader.cchWords);
                header.arcs     = Load <CfgArc>(streamHelper, cfgSerializedHeader.pArcs, cfgSerializedHeader.cArcs);
                header.tags     = Load <CfgSemanticTag>(streamHelper, cfgSerializedHeader.tags, cfgSerializedHeader.cTags);
                header.weights  = Load <float>(streamHelper, cfgSerializedHeader.pWeights, cfgSerializedHeader.cArcs);
            }

            //We know that in SAPI 5.0 grammar format pszWords follows header immediately.
            if (cfgSerializedHeader.pszWords < Marshal.SizeOf <CfgSerializedHeader>())
            {
                //This is SAPI 5.0 and SAPI 5.1 grammar format
                header.ulRootRuleIndex = 0xFFFFFFFF;
                header.GrammarOptions  = GrammarOptions.KeyValuePairs;
                header.BasePath        = null;
                header.GrammarMode     = GrammarType.VoiceGrammar;
            }
            else
            {
                //This is SAPI 5.2 and beyond grammar format
                header.ulRootRuleIndex = cfgSerializedHeader.ulRootRuleIndex;
                header.GrammarOptions  = cfgSerializedHeader.GrammarOptions;
                header.GrammarMode     = (GrammarType)cfgSerializedHeader.GrammarMode;
                if (includeAllGrammarData)
                {
                    header.scripts = Load <CfgScriptRef>(streamHelper, cfgSerializedHeader.pScripts, cfgSerializedHeader.cScripts);
                }
                // The BasePath string is written after the rules - no offset is provided
                // Get the chars and build the string
                if (cfgSerializedHeader.cBasePath > 0)
                {
                    streamHelper.Stream.Position = (int)cfgSerializedHeader.pRules + (header.rules.Length * Marshal.SizeOf <CfgRule>());
                    header.BasePath = streamHelper.ReadNullTerminatedString();
                }
            }

            // Check the content - should be valid for both SAPI 5.0 and SAPI 5.2 grammars
            CheckValidCfgFormat(cfgSerializedHeader, header, includeAllGrammarData);

            return(header);
        }
예제 #9
0
        //
        //  This helper converts a serialized CFG grammar header into an in-memory header
        //
        internal static CfgHeader ConvertCfgHeader(StreamMarshaler streamHelper)
        {
            CfgSerializedHeader cfgSerializedHeader = null;

            return(ConvertCfgHeader(streamHelper, true, true, out cfgSerializedHeader));
        }