/// <summary>
 /// This is called on the begining of each new file
 ///
 /// It should be noted that if rules are being processed in this function and if each rule can modify the propertyBag and affect other rules
 /// then the rules should be processed synchronously such that the first rule processed contains the longest scope that matches the file's path
 /// To avoid trying to do this on your own you can just process the rules in the DoesPropertyValueApply / GetPropertyValueToApply
 /// </summary>
 /// <param name="propertyBag">The fsrm property bag representing the current file</param>
 /// <param name="arrayRuleIds">An array of strings containg the string form of the guids that apply to this file, to convert them to guid's do new Guid(string)</param>
 public void OnBeginFile(
     IFsrmPropertyBag propertyBag,
     object[] arrayRuleIds
     )
 {
     m_propertyBag = propertyBag;
 }
        /// <summary>
        /// A function which returns a Stream object which encapsulates an IStream interface
        /// This makes it much easier to get the file contents in managed code / powershell
        /// </summary>
        /// <param name="parentObject">This will be the PSObject that encapsulates a IFsrmPropertyBag</param>
        /// <returns>A stream which wraps the parentObject's IStream</returns>
        public static StreamWrapperForIStream GetStream(PSObject parentObject)
        {
            IFsrmPropertyBag propertyBag = (IFsrmPropertyBag)parentObject.BaseObject;

            IStream istream = (IStream)propertyBag.GetFileStreamInterface(_FsrmFileStreamingMode.FsrmFileStreamingMode_Read, _FsrmFileStreamingInterfaceType.FsrmFileStreamingInterfaceType_IStream);

            return(new StreamWrapperForIStream(istream));
        }
Beispiel #3
0
        /*++
         *
         *  Routine RegexClassifier::OnBeginFile
         *
         * Description:
         *
         *  This routine implements the IFsrmClassifierModuleImplementation interface OnBeginFile.
         *  It is called by the pipeline for each file so that the classifier can process its rules for this file.
         *
         * Arguments:
         *
         *  propertyBag - The FSRM property bag object for this file.
         *  arrayRuleIds - The list of rules that are applicable for this file.
         *
         * Return value:
         *
         *  void
         *
         * Notes:
         *
         *
         * --*/

        public void OnBeginFile(
            IFsrmPropertyBag propertyBag,
            object[] arrayRuleIds
            )
        {
            //reset all rules
            foreach (KeyValuePair <Guid, FsrmClassificationRule> kvp in m_dictAllRules)
            {
                FsrmClassificationRule rule = (FsrmClassificationRule)kvp.Value;
                rule.ResetRule();
            }

            // create guid form of each id
            Guid[] ruleIdGuids = new Guid[arrayRuleIds.Length];
            for (int i = 0; i < arrayRuleIds.Length; ++i)
            {
                ruleIdGuids[i] = new Guid((string)arrayRuleIds[i]);
            }

            // wrap the istream in a stream, and use a streamreader to get each line
            // match each line against each rule's regexp
            // quit when all data has been read or all rules have been matched
            using (StreamWrapperForIStream stream = new StreamWrapperForIStream((IStream)propertyBag.GetFileStreamInterface(_FsrmFileStreamingMode.FsrmFileStreamingMode_Read, _FsrmFileStreamingInterfaceType.FsrmFileStreamingInterfaceType_IStream))) {
                StreamReader streamReader    = new StreamReader(stream, m_encoder);
                bool         matchedAllRules = false;

                do
                {
                    string line = streamReader.ReadLine();

                    matchedAllRules = true;
                    foreach (Guid ruleId in ruleIdGuids)
                    {
                        matchedAllRules &= m_dictAllRules[ruleId].DoesRegexSatisfy(line);
                    }
                } while (!streamReader.EndOfStream && !matchedAllRules);

                streamReader.Dispose();
            }
        }
 /// <summary>
 /// Sample code does nothing here but you can put any per file cleanup code here
 /// </summary>
 public void OnEndFile()
 {
     m_propertyBag = null;
 }
 /// <summary>
 /// This is called on the begining of each new file
 /// 
 /// It should be noted that if rules are being processed in this function and if each rule can modify the propertyBag and affect other rules
 /// then the rules should be processed synchronously such that the first rule processed contains the longest scope that matches the file's path
 /// To avoid trying to do this on your own you can just process the rules in the DoesPropertyValueApply / GetPropertyValueToApply
 /// </summary>
 /// <param name="propertyBag">The fsrm property bag representing the current file</param>
 /// <param name="arrayRuleIds">An array of strings containg the string form of the guids that apply to this file, to convert them to guid's do new Guid(string)</param>
 public void OnBeginFile(
     IFsrmPropertyBag propertyBag,
     object[] arrayRuleIds
     )
 {
     m_propertyBag = propertyBag;
 }
        /*++

            Routine RegexClassifier::OnBeginFile

        Description:

            This routine implements the IFsrmClassifierModuleImplementation interface OnBeginFile.
            It is called by the pipeline for each file so that the classifier can process its rules for this file.

        Arguments:

            propertyBag - The FSRM property bag object for this file.
            arrayRuleIds - The list of rules that are applicable for this file.

        Return value:

            void

        Notes:

        --*/
        public void OnBeginFile(
            IFsrmPropertyBag propertyBag,
            object[] arrayRuleIds
            )
        {
            //reset all rules
            foreach (KeyValuePair<Guid, FsrmClassificationRule> kvp in m_dictAllRules) {
                FsrmClassificationRule rule = (FsrmClassificationRule)kvp.Value;
                rule.ResetRule();
            }

            // create guid form of each id
            Guid[] ruleIdGuids = new Guid[arrayRuleIds.Length];
            for (int i = 0; i < arrayRuleIds.Length; ++i) {
                ruleIdGuids[i] = new Guid( (string)arrayRuleIds[i] );
            }

            // wrap the istream in a stream, and use a streamreader to get each line
            // match each line against each rule's regexp
            // quit when all data has been read or all rules have been matched
            using (StreamWrapperForIStream stream = new StreamWrapperForIStream( (IStream)propertyBag.GetFileStreamInterface( _FsrmFileStreamingMode.FsrmFileStreamingMode_Read, _FsrmFileStreamingInterfaceType.FsrmFileStreamingInterfaceType_IStream ) )) {

                StreamReader streamReader = new StreamReader( stream, m_encoder );
                bool matchedAllRules = false;

                do {
                    string line = streamReader.ReadLine();

                    matchedAllRules = true;
                    foreach (Guid ruleId in ruleIdGuids) {
                        matchedAllRules &= m_dictAllRules[ruleId].DoesRegexSatisfy( line );
                    }

                } while (!streamReader.EndOfStream && !matchedAllRules);

                streamReader.Dispose();
            }
        }
        /// <summary>
        /// Runs one step of the pipeline using propertyBag as the pipeline input
        /// Saves last outputed object
        /// Saves whether the pipeline returned 0 or 1 object
        /// throws exception if pipeline outputed more than 1 object
        /// <param name="propertyBag">The property bag to run the powershell script's pipeline on</param>
        public void StepPipeline(
            IFsrmPropertyBag propertyBag
            )
        {
            ResetRuleResults();

            m_waitHandleIndex lockIndex;
            bool readAValue = false;
            bool tooManyValues = false;
            m_ruleNoApply = false;

            // insert the property bag into the pipeline after adding the GetStream Method
            PSObject psPropertyBag = new PSObject(propertyBag);
            psPropertyBag.Methods.Add(new PSCodeMethod("GetStream", m_getStreamMethodInfo));
            m_propertyBagWriter.InsertData(psPropertyBag);

            // wait for either the pipeline to close or
            // for another property to be requested from the enumerator
            // If for input a in the script value 1 is emitted, it must be emitted before value b is requested
            // Handle multiple values being emitted but fail the current property bag if it happens
            do
            {
                lockIndex = (m_waitHandleIndex)WaitHandle.WaitAny(m_powershellPaused);

                //pipeline terminated unexpectedly save message and restart it
                if (m_pipeLine.Output.EndOfPipeline)
                {

                    string message;

                    if (m_pipeLine.PipelineStateInfo.State == PipelineState.Failed)
                    {
                        message = string.Format(CultureInfo.InvariantCulture,
                                                   "Powershell Classifier terminated abruptly due to failuer while processing file [{0}] in rule [{1}] - failure details: [{2}]",
                                                   propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                   m_ruleName,
                                                   m_pipeLine.PipelineStateInfo.Reason.Message);
                    }
                    else
                    {
                        message = string.Format(CultureInfo.InvariantCulture,
                                                   "Powershell Classifier exited abruptly without failures while processing file [{0}] in rule [{1}].",
                                                   propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                   m_ruleName);
                    }

                    propertyBag.AddMessage(message);
                    CreateAndBeginPipeline();
                    throw new COMException( message, m_pipeLine.PipelineStateInfo.Reason );
                }

                // if we haven't read a value pop one off and save it
                if (m_pipeLine.Output.Count >= 1 && !readAValue)
                {
                    readAValue = true;
                    m_propertyValue = m_pipeLine.Output.Read();
                }

                // if we have read a value and there are values in the pipeline, then
                // set the tooManyValues flag and eat everythign in the pipeline
                while (m_pipeLine.Output.Count > 0 && readAValue)
                {
                    // if the m_propertyValue currently points to the first value ouput for the pipeline
                    // the add a message for it, other wise output messages for duplicate values after popping them off
                    if (!tooManyValues)
                    {
                        string message1 = string.Format( CultureInfo.InvariantCulture,
                               "Powershell Classifier returned too many values while processing file [{0}] in rule [{1}] - returned object of type [{2}], and value [{3}]",
                               propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                               m_ruleName,
                               m_propertyValue.BaseObject.GetType().ToString(),
                               m_propertyValue.BaseObject.ToString() );
                        propertyBag.AddMessage(message1);

                    }

                    // cleanup pipeline
                    m_propertyValue = m_pipeLine.Output.Read();

                    // ouput message for current object
                    string message2 = string.Format( CultureInfo.InvariantCulture,
                               "Powershell Classifier returned too many values while processing file [{0}] in rule [{1}] - returned object of type [{2}], and value [{3}]",
                               propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                               m_ruleName,
                               m_propertyValue.BaseObject.GetType().ToString(),
                               m_propertyValue.BaseObject.ToString() );
                    propertyBag.AddMessage(message2);

                    tooManyValues = true;
                }

            } while (lockIndex != m_waitHandleIndex.Enumerator && m_pipeLine.Output.IsOpen);

            // if script didn't output any values for this property bag record it
            if (!readAValue)
            {
                m_ruleNoApply = true;
            }

            // if output too many values finish failing this property
            if (tooManyValues)
            {
                //already added messages for reason why we are failing
                string message3 = string.Format( CultureInfo.InvariantCulture,
                               "Powershell Classifier returned too many values while processing file [{0}] in rule [{1}]",
                               propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                               m_ruleName );
                throw new COMException( message3, HRESULTS.PS_CLS_E_TOO_MANY_VALUES );
            }

            // if there were errors in the pipeline pop them all off and then fail current property bag
            if (m_pipeLine.Error.Count > 0)
            {

                Exception firstError = null;
                while(m_pipeLine.Error.Count > 0)
                {
                    Exception exception = (Exception)m_pipeLine.Error.Read();
                    if (firstError == null)
                    {
                        firstError = exception;
                    }
                    // add message to pipeline
                    propertyBag.AddMessage(exception.Message);
                }

                throw (Exception)firstError;
            }
        }
        /// <summary>
        /// Runs one step of the pipeline using propertyBag as the pipeline input
        /// Saves last outputed object
        /// Saves whether the pipeline returned 0 or 1 object
        /// throws exception if pipeline outputed more than 1 object
        /// <param name="propertyBag">The property bag to run the powershell script's pipeline on</param>
        public void StepPipeline(
            IFsrmPropertyBag propertyBag
            )
        {
            ResetRuleResults();

            m_waitHandleIndex lockIndex;
            bool readAValue    = false;
            bool tooManyValues = false;

            m_ruleNoApply = false;

            // insert the property bag into the pipeline after adding the GetStream Method
            PSObject psPropertyBag = new PSObject(propertyBag);

            psPropertyBag.Methods.Add(new PSCodeMethod("GetStream", m_getStreamMethodInfo));
            m_propertyBagWriter.InsertData(psPropertyBag);

            // wait for either the pipeline to close or
            // for another property to be requested from the enumerator
            // If for input a in the script value 1 is emitted, it must be emitted before value b is requested
            // Handle multiple values being emitted but fail the current property bag if it happens
            do
            {
                lockIndex = (m_waitHandleIndex)WaitHandle.WaitAny(m_powershellPaused);

                //pipeline terminated unexpectedly save message and restart it
                if (m_pipeLine.Output.EndOfPipeline)
                {
                    string message;

                    if (m_pipeLine.PipelineStateInfo.State == PipelineState.Failed)
                    {
                        message = string.Format(CultureInfo.InvariantCulture,
                                                "Powershell Classifier terminated abruptly due to failuer while processing file [{0}] in rule [{1}] - failure details: [{2}]",
                                                propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                m_ruleName,
                                                m_pipeLine.PipelineStateInfo.Reason.Message);
                    }
                    else
                    {
                        message = string.Format(CultureInfo.InvariantCulture,
                                                "Powershell Classifier exited abruptly without failures while processing file [{0}] in rule [{1}].",
                                                propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                m_ruleName);
                    }

                    propertyBag.AddMessage(message);
                    CreateAndBeginPipeline();
                    throw new COMException(message, m_pipeLine.PipelineStateInfo.Reason);
                }

                // if we haven't read a value pop one off and save it
                if (m_pipeLine.Output.Count >= 1 && !readAValue)
                {
                    readAValue      = true;
                    m_propertyValue = m_pipeLine.Output.Read();
                }

                // if we have read a value and there are values in the pipeline, then
                // set the tooManyValues flag and eat everythign in the pipeline
                while (m_pipeLine.Output.Count > 0 && readAValue)
                {
                    // if the m_propertyValue currently points to the first value ouput for the pipeline
                    // the add a message for it, other wise output messages for duplicate values after popping them off
                    if (!tooManyValues)
                    {
                        string message1 = string.Format(CultureInfo.InvariantCulture,
                                                        "Powershell Classifier returned too many values while processing file [{0}] in rule [{1}] - returned object of type [{2}], and value [{3}]",
                                                        propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                        m_ruleName,
                                                        m_propertyValue.BaseObject.GetType().ToString(),
                                                        m_propertyValue.BaseObject.ToString());
                        propertyBag.AddMessage(message1);
                    }

                    // cleanup pipeline
                    m_propertyValue = m_pipeLine.Output.Read();

                    // ouput message for current object
                    string message2 = string.Format(CultureInfo.InvariantCulture,
                                                    "Powershell Classifier returned too many values while processing file [{0}] in rule [{1}] - returned object of type [{2}], and value [{3}]",
                                                    propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                    m_ruleName,
                                                    m_propertyValue.BaseObject.GetType().ToString(),
                                                    m_propertyValue.BaseObject.ToString());
                    propertyBag.AddMessage(message2);

                    tooManyValues = true;
                }
            } while (lockIndex != m_waitHandleIndex.Enumerator && m_pipeLine.Output.IsOpen);

            // if script didn't output any values for this property bag record it
            if (!readAValue)
            {
                m_ruleNoApply = true;
            }

            // if output too many values finish failing this property
            if (tooManyValues)
            {
                //already added messages for reason why we are failing
                string message3 = string.Format(CultureInfo.InvariantCulture,
                                                "Powershell Classifier returned too many values while processing file [{0}] in rule [{1}]",
                                                propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                m_ruleName);
                throw new COMException(message3, HRESULTS.PS_CLS_E_TOO_MANY_VALUES);
            }

            // if there were errors in the pipeline pop them all off and then fail current property bag
            if (m_pipeLine.Error.Count > 0)
            {
                Exception firstError = null;
                while (m_pipeLine.Error.Count > 0)
                {
                    Exception exception = (Exception)m_pipeLine.Error.Read();
                    if (firstError == null)
                    {
                        firstError = exception;
                    }
                    // add message to pipeline
                    propertyBag.AddMessage(exception.Message);
                }

                throw (Exception)firstError;
            }
        }
 /// <summary>
 /// Sample code does nothing here but you can put any per file cleanup code here
 /// </summary>
 public void OnEndFile()
 {
     m_propertyBag = null;
 }