예제 #1
0
 public void IsFileStreamWhenInitialCapacityIsLargerThenDefaultThreshold()
 {
     using (VirtualStream stream = VirtualStream.Create(VirtualStream.ThresholdMax + 1))
     {
         Assert.True(stream.UnderlyingStream is FileStream);
     }
 }
예제 #2
0
        /// <summary>
        /// Retrieve the contents of a message into a stream
        /// </summary>
        /// <param name="message"></param>
        /// <param name="bufferSize"></param>
        /// <param name="thresholdSize"></param>
        /// <returns></returns>
        public Stream ProcessRequestReturnStream(XLANGMessage message, int bufferSize, int thresholdSize)
        {
            Stream partStream = null;

            try
            {
                using (VirtualStream virtualStream = new VirtualStream(bufferSize, thresholdSize))
                {
                    using (partStream = (Stream)message[0].RetrieveAs(typeof(Stream)))

                        //Note that when calling this code, if the XmlDocument is quite large, keeping it in a memory with a MemoryStream may have an adverse effect on performance.
                        //In this case, it may be worthwhile to consider an approach that uses a VirtualStream + ReadonlySeekableStream to buffer it to the file system,
                        //if its size is bigger than the thresholdSize parameter.
                        //Keep in mind that:
                        // - If the message size is smaller than the threshold size, the VirtualStream class buffers the stream to a MemoryStream.
                        // - If the message size is bigger than the threshold size, the VirtualStream class buffers the stream to a temporary file.
                        using (ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(partStream, virtualStream, bufferSize))
                        {
                            using (XmlReader reader = XmlReader.Create(readOnlySeekableStream))
                            {
                            }
                        }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                message.Dispose();
            }

            return(partStream);
        }
예제 #3
0
 public void IsFileStreamWhenInitialCapacityIsLargerThenSpecifiedThreshold()
 {
     using (VirtualStream stream = VirtualStream.Create(10, 7))
     {
         Assert.True(stream.UnderlyingStream is FileStream);
     }
 }
        public ListFormatOverrideTable(FileInformationBlock fib, VirtualStream tableStream)
        {
            if (fib.lcbPlfLfo > 0)
            {
                var reader = new VirtualStreamReader(tableStream);
                reader.BaseStream.Seek((long)fib.fcPlfLfo, System.IO.SeekOrigin.Begin);

                //read the count of LFOs
                int count = reader.ReadInt32();

                //read the LFOs
                for (int i = 0; i < count; i++)
                {
                    this.Add(new ListFormatOverride(reader, LFO_LENGTH));
                }

                //read the LFOLVLs
                for (int i = 0; i < count; i++)
                {
                    for (int j = 0; j < this[i].clfolvl; j++)
                    {
                        this[i].rgLfoLvl[j] = new ListFormatOverrideLevel(reader, LFOLVL_LENGTH);
                    }
                }
            }
        }
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pc">Pipeline context</param>
        /// <param name="inmsg">Input message.</param>
        /// <returns>Processed input message with appended or prepended data.</returns>
        /// <remarks>
        /// Converts xsl-fo transformed messages to pdf
        /// </remarks>
        public IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
        {
            IBaseMessagePart bodyPart = inmsg.BodyPart;

            if (bodyPart.Data != null)
            {
                VirtualStream vtstm = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk);

                FonetDriver driver = FonetDriver.Make();
                driver.CloseOnExit = false;//important for biztalk to work ... set position = 0

                PdfRendererOptions options = new PdfRendererOptions();
                options.Title        = Title;
                options.Subject      = Subject;
                options.UserPassword = Password;

                driver.Options = options;

                Stream stm = bodyPart.GetOriginalDataStream();
                stm.Seek(0, SeekOrigin.Begin);

                driver.Render(stm, vtstm);

                vtstm.Seek(0, SeekOrigin.Begin);

                bodyPart.Data = vtstm;
            }
            return(inmsg);
        }
예제 #6
0
        public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
        {
            string errorMessage;

            if (!Validate(out errorMessage))
            {
                throw new ArgumentException(errorMessage);
            }

            String value = null;

            IBaseMessagePart bodyPart = pInMsg.BodyPart;

            Stream                 inboundStream          = bodyPart.GetOriginalDataStream();
            VirtualStream          virtualStream          = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk);
            ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream);

            XmlTextReader   xmlTextReader   = new XmlTextReader(readOnlySeekableStream);
            XPathCollection xPathCollection = new XPathCollection();
            XPathReader     xPathReader     = new XPathReader(xmlTextReader, xPathCollection);

            xPathCollection.Add(XPath);

            while (xPathReader.ReadUntilMatch())
            {
                if (xPathReader.Match(0))
                {
                    if (xPathReader.NodeType == XmlNodeType.Attribute)
                    {
                        value = xPathReader.GetAttribute(xPathReader.Name);
                    }
                    else
                    {
                        value = xPathReader.ReadString();
                    }

                    if (PromoteProperty)
                    {
                        pInMsg.Context.Promote(new ContextProperty(PropertyPath), value);
                    }
                    else
                    {
                        pInMsg.Context.Write(new ContextProperty(PropertyPath), value);
                    }

                    break;
                }
            }

            if (string.IsNullOrEmpty(value) && ThrowIfNoMatch)
            {
                throw new InvalidOperationException("The specified XPath did not exist or contained an empty value.");
            }

            readOnlySeekableStream.Position = 0;
            pContext.ResourceTracker.AddResource(readOnlySeekableStream);
            bodyPart.Data = readOnlySeekableStream;

            return(pInMsg);
        }
예제 #7
0
        /// <summary>
        /// Returnes a list of all ParagraphPropertyExceptions which correspond to text
        /// between the given offsets.
        /// </summary>
        /// <param name="fcMin">The lower boundary</param>
        /// <param name="fcMax">The upper boundary</param>
        /// <param name="fib">The FileInformationBlock</param>
        /// <param name="wordStream">The VirtualStream "WordStream"</param>
        /// <param name="tableStream">The VirtualStream "0Table" or "1Table"</param>
        /// <returns>The FCs</returns>
        public static List <ParagraphPropertyExceptions> GetParagraphPropertyExceptions(
            Int32 fcMin,
            Int32 fcMax,
            FileInformationBlock fib,
            VirtualStream wordStream,
            VirtualStream tableStream,
            VirtualStream dataStream)
        {
            List <ParagraphPropertyExceptions> list = new List <ParagraphPropertyExceptions>();
            List <FormattedDiskPagePAPX>       fkps = FormattedDiskPagePAPX.GetAllPAPXFKPs(fib, wordStream, tableStream, dataStream);

            for (int i = 0; i < fkps.Count; i++)
            {
                FormattedDiskPagePAPX fkp = fkps[i];

                for (int j = 0; j < fkp.grppapx.Length; j++)
                {
                    if (fkp.rgfc[j] >= fcMin && fkp.rgfc[j] < fcMax)
                    {
                        list.Add(fkp.grppapx[j]);
                    }
                }
            }

            return(list);
        }
예제 #8
0
        private void BlockField_CreateDataBlock(BlockField field, long baseOffset, ref long offset)
        {
            //Create a condensed block
            if (field.BlockList.Count > 0)
            {
                //Prepare
                ITagBlock block       = field.BlockList[0];
                int       localOffset = (int)(field.BlockAddress - baseOffset);

                //Create
                using (VirtualStream vs = new VirtualStream(offset))
                    using (BinaryWriter writer = new BinaryWriter(vs))
                    {
                        //Align
                        vs.Align(block.Alignment);

                        //Write
                        foreach (ITagBlock child in field.BlockList)
                        {
                            child.Write(writer);
                        }

                        //Add
                        tagBlockView.Blocks.Add(localOffset, (int)vs.Length, block.BlockName);
                        offset = field.BlockAddress + vs.Length;
                    }
            }

            //Create child blocks
            foreach (ITagBlock block in field.BlockList)
            {
                TagBlock_CreateChildBlocks(block, baseOffset, ref offset);
            }
        }
예제 #9
0
        private static void AddAttachmentToMultipart(Multipart bodyMultipart, Attachment attachment)
        {
            // A stream that is passed to a ContentObject must be seekable.  If this is not the case,
            // we'll have to create a new stream which is seekable and assign it to the Attachment.Content.
            if (attachment.Content.CanSeek == false)
            {
                var tempStream = new VirtualStream(forAsync: true);
                attachment.Content.CopyTo(tempStream);
                tempStream.Position = 0;
                attachment.UpdateContent(tempStream, attachment.ContentType);
            }

            try
            {
                var attachmentMimePart = new MimePart(attachment.ContentType)
                {
                    ContentId               = attachment.Id,
                    ContentObject           = new ContentObject(attachment.Content),
                    ContentDisposition      = new ContentDisposition(ContentDisposition.Attachment),
                    ContentTransferEncoding = ContentEncoding.Binary

                                              // We need to explicitly set this to binary,
                                              // otherwise we can enounter issues with CRLFs & signing.
                };
                bodyMultipart.Add(attachmentMimePart);
            }
            catch (ArgumentException ex)
            {
                Logger.Error(ex);
                throw new NotSupportedException($"Attachment {attachment.Id} has a content-type that is not supported ({attachment.ContentType}).");
            }
        }
예제 #10
0
        public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
        {
            if (DocumentSpecName == null)
            {
                throw new ArgumentException("DocSpec must be specified");
            }

            this.WorkBook = WorkbookFactory.Create(pInMsg.BodyPart.Data, ImportOption.SheetContentOnly);

            IFormulaEvaluator formulaEvaluator = null;

            if (this.WorkBook is XSSFWorkbook)
            {
                formulaEvaluator = new XSSFFormulaEvaluator(this.WorkBook);
            }
            else
            {
                formulaEvaluator = new HSSFFormulaEvaluator(this.WorkBook);
            }


            this.WorkBookSchema = GetWorkBookSchema(pContext, formulaEvaluator);

            VirtualStream outSstm = ProcessWorkbook();

            pInMsg.BodyPart.Data = outSstm;

            pInMsg.Context.Promote(new ContextProperty(SystemProperties.MessageType), $"{this.WorkBookSchema.Namespace}#{this.WorkBookSchema.Name}");
            pInMsg.Context.Write(new ContextProperty(SystemProperties.SchemaStrongName), DocumentSpecName.SchemaName);

            pContext.ResourceTracker.AddResource(outSstm);

            return(pInMsg);
        }
예제 #11
0
        private void CompressAttachment(Attachment attachment)
        {
            PartInfo referenced = _partInfos.FirstOrDefault(attachment.Matches);

            if (referenced == null)
            {
                throw new InvalidOperationException(
                          $"Can't compress attachment {attachment.Id} because no matching PartInfo element was found in UserMessage");
            }

            VirtualStream outputStream =
                VirtualStream.Create(
                    attachment.EstimatedContentSize > -1
                        ? attachment.EstimatedContentSize
                        : VirtualStream.ThresholdMax);

            CompressionLevel compressionLevel = DetermineCompressionLevelFor(attachment);

            using (var gzipCompression = new GZipStream(outputStream, compressionLevel, leaveOpen: true))
            {
                attachment.Content.CopyTo(gzipCompression);
            }

            outputStream.Position      = 0;
            attachment.MimeType        = attachment.ContentType;
            attachment.CompressionType = CompressionType;
            referenced.CompressionType = CompressionType;
            attachment.UpdateContent(outputStream, CompressionType);
        }
        private Stream Apply(XslCompiledTransform xsl, XsltArgumentList arguments, Encoding encoding)
        {
            var output = new VirtualStream(DEFAULT_BUFFER_SIZE, DEFAULT_THRESHOLD_SIZE);
            // Clone() to get a modifiable copy of the transform's settings
            var settings = xsl.OutputSettings.Clone();

            settings.CloseOutput = false;
            settings.Encoding    = encoding;
            using (var writer = XmlWriter.Create(output, settings))
            {
                if (_streams.Length == 1)
                {
                    if (_streams[0] is CompositeStream compositeStream)
                    {
                        xsl.Transform(compositeStream.Streams, arguments, writer);
                    }
                    else
                    {
                        xsl.Transform(_streams[0], arguments, writer);
                    }
                }
                else
                {
                    xsl.Transform(_streams, arguments, writer);
                }

                output.Seek(0, SeekOrigin.Begin);
                return(output);
            }
        }
예제 #13
0
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pc">Pipeline context</param>
        /// <param name="inmsg">Input message</param>
        /// <returns>Original input message</returns>
        /// <remarks>
        /// IComponent.Execute method is used to initiate
        /// the processing of the message in this pipeline component.
        /// </remarks>
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
        {
            string                 ActivityID    = Guid.NewGuid().ToString();
            string                 ShareLocation = "D:\\Share\\TrackingArchive\\"; // Should be an UNC Path with desired access granted to the User Account
            string                 FileExtension = ".txt";
            string                 FullFilePath  = ShareLocation + ActivityID + FileExtension;
            StringBuilder          SBContext     = new StringBuilder();
            ReadOnlySeekableStream stream        = new ReadOnlySeekableStream(inmsg.BodyPart.GetOriginalDataStream());
            Stream                 sourceStream  = inmsg.BodyPart.GetOriginalDataStream();

            if (!sourceStream.CanSeek)
            {
                ReadOnlySeekableStream seekableStream = new ReadOnlySeekableStream(sourceStream);

                inmsg.BodyPart.Data = seekableStream;

                sourceStream = inmsg.BodyPart.Data;
            }

            if (inmsg.BodyPart != null)
            {
                VirtualStream virtualStream = new VirtualStream(sourceStream);

                PipelineHelper.ArchiveToFileLocation(virtualStream, FullFilePath);
                PipelineHelper.ArchivetoStorage(pc, inmsg, FullFilePath, true);

                sourceStream.Position        = 0;
                inmsg.BodyPart.Data          = sourceStream;
                inmsg.BodyPart.Data.Position = 0;
            }

            return(inmsg);

            #endregion
        }
예제 #14
0
        public static void ArchiveToFileLocation(VirtualStream dataStream, string FullFilePath)
        {
            try
            {
                //string saveTo = "C:\\Projects\\Unicer.Archive\\ArchiveFolder\\teste.xml";
                // create a write stream
                FileStream   FileArchiveStream = new FileStream(FullFilePath, FileMode.Create, FileAccess.Write);
                BinaryWriter FileBinaryWriter  = new BinaryWriter(FileArchiveStream);

                // Read the stream and write to the archive file
                byte[] Buffer = new byte[256];
                int    SizeRead;
                while ((SizeRead = dataStream.Read(Buffer, 0, 256)) != 0)
                {
                    FileBinaryWriter.Write(Buffer, 0, SizeRead);
                }

                // Flush and close the output stream
                FileBinaryWriter.Flush();
                FileBinaryWriter.Close();
            }
            catch (IOException Ex)
            {
                //System.Diagnostics.EventLog.WriteEntry(EventData.EVENT_LOG_SOURCE, "An error occured creating the archive file - the file has not been archived.\n\nThe following error was raised: " + Ex.Message, EventLogEntryType.Error);
            }

            // dataStream.Seek(0, SeekOrigin.Begin); //(ERROR IS THROW HERE)
            // return (dataStream);
        }
예제 #15
0
        public List <char> GetAllChars(VirtualStream wordStream)
        {
            List <char> chars = new List <char>();

            foreach (PieceDescriptor pcd in this.Pieces)
            {
                //get the FC end of this piece
                Int32 pcdFcEnd = pcd.cpEnd - pcd.cpStart;
                if (pcd.encoding == Encoding.Unicode)
                {
                    pcdFcEnd *= 2;
                }
                pcdFcEnd += (Int32)pcd.fc;

                int    cb    = pcdFcEnd - (Int32)pcd.fc;
                byte[] bytes = new byte[cb];

                //read all bytes
                wordStream.Read(bytes, 0, cb, (Int32)pcd.fc);

                //get the chars
                char[] plainChars = pcd.encoding.GetString(bytes).ToCharArray();

                //add to list
                foreach (char c in plainChars)
                {
                    chars.Add(c);
                }
            }
            return(chars);
        }
        public void AS4ComponentDoesntAlterEncryptedDataFromOriginalHolodeckMessage()
        {
            // Arrange
            Holodeck.CopyPModeToHolodeckB("8.1.22-pmode.xml");

            AS4Component.OverrideSettings(DynamicDiscoverySettings);
            AS4Component.Start();

            InsertSmpConfigurationForAS4Component(ReceiveAgentEndpoint, enableEncryption: false);

            var str = VirtualStream.Create();

            str.Write(Properties.Resources._8_1_22_message, 0, Properties.Resources._8_1_22_message.Length);
            str.Position = 0;

            const string contentType =
                "multipart/related; boundary= \"MIMEBoundary_4ac2a25e8a3af891754f9f7316ac08062c50de1368ddfada\"; type=\"application/soap+xml\";";

            // Act
            new StubSender().SendMessage(str, contentType);

            // Assert
            Assert.True(
                PollingAt(AS4ReceiptsPath),
                "No Receipt found at AS4.NET Component for Encrypted Dynamic Forwarding Test");
        }
예제 #17
0
        /// <summary>
        /// Create the output message when validation errors are captured
        /// </summary>
        /// <param name="pContext">Pipeline context</param>
        /// <param name="pInMsg">Input message in  the pipeline</param>
        /// <param name="errorStream">Stream for the Validation Errors</param>
        /// <param name="requestId">Request Id</param>
        /// <returns></returns>
        public static IBaseMessage CreateOutPutMessage(IPipelineContext pContext, IBaseMessage pInMsg, VirtualStream errorStream, string requestId)
        {
            VirtualStream seekableStream = new VirtualStream(pInMsg.BodyPart.GetOriginalDataStream());

            seekableStream.Position = 0;
            errorStream.Position    = 0;
            VirtualStream outMsgStream = CreateValidationErrorMessage(seekableStream, errorStream, requestId);

            outMsgStream.Position = 0;

            IBaseMessageFactory messageFactory  = pContext.GetMessageFactory();
            IBaseMessage        pOutMsg         = messageFactory.CreateMessage();
            IBaseMessagePart    pOutMsgBodyPart = messageFactory.CreateMessagePart();
            IBasePropertyBag    pOutPb          = PipelineUtil.CopyPropertyBag(pInMsg.BodyPart.PartProperties, messageFactory);

            pOutMsg.Context = PipelineUtil.CloneMessageContext(pInMsg.Context);

            pOutMsgBodyPart.Charset     = Constants.BodyPartCharSet;
            pOutMsgBodyPart.ContentType = Constants.BodyPartContentType;
            pOutMsgBodyPart.Data        = outMsgStream;
            string outMessageType = string.Format("{0}#{1}", Constants.AIBPValidationErrorNameSpace, Constants.AIBPValidationErrorRootNode);

            pOutMsg.Context.Promote(Constants.MessageTypePropName, Constants.SystemPropertiesNamespace, outMessageType);

            pOutMsg.AddPart("Body", pOutMsgBodyPart, true);

            // Add resources to the resource tracker to be disposed of at correct time
            pContext.ResourceTracker.AddResource(seekableStream);
            pContext.ResourceTracker.AddResource(outMsgStream);
            pContext.ResourceTracker.AddResource(errorStream);
            return(pOutMsg);
        }
예제 #18
0
        /// <summary>
        /// Create a new <see cref="AS4Response"/> instance.
        /// </summary>
        /// <param name="requestMessage"></param>
        /// <param name="webResponse"></param>
        /// <returns></returns>
        public static async Task <AS4Response> Create(MessagingContext requestMessage, HttpWebResponse webResponse)
        {
            var response       = new AS4Response(requestMessage, webResponse);
            var responseStream = webResponse.GetResponseStream() ?? Stream.Null;
            var contentStream  = VirtualStream.Create(webResponse.ContentLength, forAsync: true);

            await responseStream.CopyToFastAsync(contentStream);

            contentStream.Position = 0;

            response.ReceivedStream =
                new ReceivedMessage(
                    contentStream,
                    webResponse.ContentType,
                    webResponse.ResponseUri?.AbsolutePath ?? "unknown",
                    webResponse.ContentLength);

            response.ReceivedAS4Message = await TryDeserializeReceivedStream(response.ReceivedStream, CancellationToken.None);

            if (Logger.IsInfoEnabled)
            {
                if (response.ReceivedAS4Message.IsEmpty == false)
                {
                    LogReceivedAS4Response(
                        requestMessage.AS4Message,
                        response.ReceivedAS4Message);
                }
            }

            return(response);
        }
예제 #19
0
        /// <summary>
        /// Loads a <see cref="Stream" /> at a given stored <paramref name="location" />.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <returns></returns>
        public async Task <Stream> LoadMessageBodyAsync(string location)
        {
            if (location == null)
            {
                throw new ArgumentNullException(nameof(location));
            }

            string fileLocation = SubstringWithoutFileUri(location);

            if (string.IsNullOrEmpty(fileLocation))
            {
                return(null);
            }

            if (File.Exists(fileLocation))
            {
                using (FileStream fileStream = FileUtils.OpenReadAsync(fileLocation, options: FileOptions.SequentialScan))
                {
                    VirtualStream virtualStream =
                        VirtualStream.Create(
                            fileStream.CanSeek ? fileStream.Length : VirtualStream.ThresholdMax,
                            forAsync: true);

                    await fileStream.CopyToFastAsync(virtualStream).ConfigureAwait(false);

                    virtualStream.Position = 0;

                    return(virtualStream);
                }
            }

            return(null);
        }
예제 #20
0
        /// <summary>
        /// Parses the bytes to retrieve a AuthorTable
        /// </summary>
        /// <param name="bytes">The bytes</param>
        public AuthorTable(FileInformationBlock fib, VirtualStream tableStream)
        {
            int pos = 8;

            byte[]        uniChar = new byte[2];
            StringBuilder name    = new StringBuilder();

            while (pos < fib.lcbSttbfRMark)
            {
                tableStream.Read(uniChar, 0, 2, (int)(fib.fcSttbfRMark + pos));
                char cPos = Encoding.Unicode.GetString(uniChar).ToCharArray()[0];
                if ((int)cPos > 0x1F)
                {
                    name.Append(cPos);
                }
                else
                {
                    //there is a seperator that terminates this name
                    this.Add(name.ToString());
                    name = new StringBuilder();
                }
                pos += 2;
            }
            //add last name
            this.Add(name.ToString());
        }
        private static Stream Transform(XmlReader reader, Type map, System.Xml.Xsl.XsltArgumentList arguments)
        {
            if (_logger.IsDebugEnabled)
            {
                _logger.DebugFormat("About to execute transform '{0}'.", map.AssemblyQualifiedName);
            }
            var transformDescriptor = XsltCache.Instance[map];

            using (reader)
            {
                var outputStream   = new VirtualStream(DEFAULT_BUFFER_SIZE, DEFAULT_THRESHOLD_SIZE);
                var writerSettings = transformDescriptor.XslCompiledTransform.OutputSettings.Override(
                    s => {
                    s.CloseOutput = false;
                    s.Encoding    = Encoding.UTF8;
                });
                using (var writer = XmlWriter.Create(outputStream, writerSettings))
                {
                    if (_logger.IsDebugEnabled)
                    {
                        _logger.DebugFormat("Executing transform '{0}'.", map.AssemblyQualifiedName);
                    }
                    var xsltArguments = transformDescriptor.Arguments.Union(arguments);
                    transformDescriptor.XslCompiledTransform.Transform(reader, xsltArguments, writer);
                }
                outputStream.Seek(0, SeekOrigin.Begin);
                return(outputStream);
            }
        }
예제 #22
0
        /// <summary>
        /// Parses an StwUser structure into a dictionary of key-value-pairs
        /// </summary>
        /// <param name="tableStream">The input table stream</param>
        /// <param name="fcStwUser">fcStwUser (4 bytes): An unsigned integer that specifies an offset into the Table Stream.
        /// An StwUser that specifies the user-defined variables and VBA digital signature (2), as specified by
        /// [MS-OSHARED] section 2.3.2, begins at this offset.
        ///
        /// If lcbStwUser is zero, fcStwUser is undefined and MUST be ignored.</param>
        /// <param name="lcbStwUser">lcbStwUser (4 bytes): An unsigned integer that specifies the size, in bytes,
        /// of the StwUser at offset fcStwUser</param>
        public StwUser(VirtualStream tableStream, UInt32 fcStwUser, UInt32 lcbStwUser)
        {
            if (lcbStwUser == 0)
            {
                return;
            }
            tableStream.Seek(fcStwUser, System.IO.SeekOrigin.Begin);

            // parse the names
            var names = new StringTable(typeof(string), tableStream, fcStwUser, lcbStwUser);

            // parse the values
            var values = new List <string>();

            while (tableStream.Position < fcStwUser + lcbStwUser)
            {
                values.Add(Utils.ReadXst(tableStream));
            }

            // map to the dictionary
            if (names.Strings.Count == values.Count)
            {
                for (int i = 0; i < names.Strings.Count; i++)
                {
                    this.Add(names.Strings[i], values[i]);
                }
            }
        }
예제 #23
0
        public ListTable(FileInformationBlock fib, VirtualStream tableStream)
        {
            if (fib.lcbPlfLst > 0)
            {
                var reader = new VirtualStreamReader(tableStream);
                reader.BaseStream.Seek(fib.fcPlfLst, System.IO.SeekOrigin.Begin);

                //the ListTable is not a real plex:
                //it starts with a count, followed by the array of LSTF structs,
                //followed by the array of LVLF structs

                //read count
                short count = reader.ReadInt16();

                //read the LSTF structs
                for (int i = 0; i < count; i++)
                {
                    this.Add(new ListData(reader, ByteStructure.VARIABLE_LENGTH));
                }

                //read the LVLF structs
                for (int i = 0; i < count; i++)
                {
                    var lstf = this[i];
                    for (int j = 0; j < lstf.rglvl.Length; j++)
                    {
                        lstf.rglvl[j] = new ListLevel(reader, ByteStructure.VARIABLE_LENGTH);
                    }
                }
            }
        }
예제 #24
0
        private static async Task <ReceivedMessage> WrapRequestInSeekableMessageAsync(HttpListenerRequest request, long contentLength)
        {
            Logger.Trace("Start copying to VirtualStream");
            var dest = new VirtualStream(
                request.ContentLength64 > VirtualStream.ThresholdMax
                    ? VirtualStream.MemoryFlag.OnlyToDisk
                    : VirtualStream.MemoryFlag.AutoOverFlowToDisk,
                forAsync: true);

            if (contentLength > 0)
            {
                dest.SetLength(contentLength);
            }

            await request.InputStream
            .CopyToFastAsync(dest)
            .ConfigureAwait(false);

            dest.Position = 0;

            return(new ReceivedMessage(
                       underlyingStream: dest,
                       contentType: request.ContentType,
                       origin: request.UserHostAddress,
                       length: request.ContentLength64));
        }
예제 #25
0
        /// <summary>
        /// Checks seekability of the data stream in the body part of specified message and returns a new <see cref="Microsoft.BizTalk.Streaming.ReadOnlySeekableStream"/>
        /// stream should the original stream fail to support the Seek operation.
        /// </summary>
        /// <param name="msg">The message instance represented by the <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> object.</param>
        /// <param name="pContext">A reference to <see cref="Microsoft.BizTalk.Component.Interop.IPipelineContext"/> object that contains the current pipeline context.</param>
        /// <returns>Either the original data stream or a new stream wrapping the original stream and providing support for the Seek operation, or a null reference if the specified message doesn't contain a body part.</returns>
        public static Stream EnsureSeekableStream(IBaseMessage msg, IPipelineContext pContext)
        {
            if (msg != null && msg.BodyPart != null)
            {
                Stream messageDataStream = msg.BodyPart.GetOriginalDataStream();

                if (!messageDataStream.CanSeek)
                {
                    Stream virtualStream = new VirtualStream(VirtualStreamBufferSize, VirtualStreamThresholdSize);
                    pContext.ResourceTracker.AddResource(virtualStream);

                    Stream seekableStream = new ReadOnlySeekableStream(messageDataStream, virtualStream, VirtualStreamBufferSize);
                    msg.BodyPart.Data = seekableStream;

                    return(seekableStream);
                }
                else
                {
                    return(messageDataStream);
                }
            }
            else
            {
                return(null);
            }
        }
예제 #26
0
        /// <summary>
        /// Returns a list of all PAPX FCs between they given boundaries.
        /// </summary>
        /// <param name="fcMin">The lower boundary</param>
        /// <param name="fcMax">The upper boundary</param>
        /// <param name="fib">The FileInformationBlock</param>
        /// <param name="wordStream">The VirtualStream "WordStream"</param>
        /// <param name="tableStream">The VirtualStream "0Table" or "1Table"</param>
        /// <returns>The FCs</returns>
        public static List <Int32> GetFileCharacterPositions(
            Int32 fcMin,
            Int32 fcMax,
            FileInformationBlock fib,
            VirtualStream wordStream,
            VirtualStream tableStream,
            VirtualStream dataStream)
        {
            List <Int32> list = new List <Int32>();
            List <FormattedDiskPagePAPX> fkps = FormattedDiskPagePAPX.GetAllPAPXFKPs(fib, wordStream, tableStream, dataStream);

            for (int i = 0; i < fkps.Count; i++)
            {
                FormattedDiskPage fkp = fkps[i];

                //the last entry of each is always the same as the first entry of the next FKP
                //so, ignore all last _entries except for the last FKP.
                int max = fkp.rgfc.Length;
                if (i < fkps.Count - 1)
                {
                    max--;
                }

                for (int j = 0; j < max; j++)
                {
                    if (fkp.rgfc[j] >= fcMin && fkp.rgfc[j] < fcMax)
                    {
                        list.Add(fkp.rgfc[j]);
                    }
                }
            }

            return(list);
        }
예제 #27
0
        /// <summary>
        /// Removes the byte order mask.
        /// </summary>
        /// <param name="inStream">Input stream.</param>
        /// <returns>New stream without the byte order mask.</returns>
        public static Stream RemoveByteOrderMark(Stream inStream)
        {
            if (inStream == null)
            {
                throw new ArgumentNullException("inStream");
            }

            int num = MatchByteOrderMarkSequence(inStream);

            if (num <= 0)
            {
                return(inStream);
            }
            VirtualStream virtualStream = new VirtualStream((int)inStream.Length);

            byte[] buffer = new byte[BUFFER_SIZE];
            inStream.Position = (long)num;
            int count;

            while ((count = inStream.Read(buffer, 0, BUFFER_SIZE)) > 0)
            {
                virtualStream.Write(buffer, 0, count);
            }
            virtualStream.Flush();
            virtualStream.Position = 0L;
            return(virtualStream);
        }
예제 #28
0
        private Stream Apply(XslCompiledTransform xsl, XsltArgumentList arguments, Encoding encoding)
        {
            var output = new VirtualStream(DEFAULT_BUFFER_SIZE, DEFAULT_THRESHOLD_SIZE);
            // Clone() to have a modifiable copy of the transform's settings
            var settings = xsl.OutputSettings.Clone();

            settings.CloseOutput = false;
            settings.Encoding    = encoding;
            using (var writer = XmlWriter.Create(output, settings))
            {
                if (_streams.Length == 1)
                {
                    // TODO ?? *always* skip CompositeStream.Read() and wraps CompositeStream.Streams in a CompositeXmlReader instead ??
                    //var compositeStream = _streams[0] as CompositeStream;
                    //if (compositeStream != null)
                    //   xsl.Transform(compositeStream.Streams, arguments, writer);
                    //else
                    xsl.Transform(_streams[0], arguments, writer);
                }
                else
                {
                    xsl.Transform(_streams, arguments, writer);
                }
                output.Seek(0, SeekOrigin.Begin);
                return(output);
            }
        }
예제 #29
0
        private int TagGroup_CalculateChecksum(ITagGroup tagGroup)
        {
            int checksum = 0;

            using (VirtualStream tagStream = new VirtualStream(TagGroupHeader.Size))
                using (BinaryWriter writer = new BinaryWriter(tagStream))
                {
                    tagGroup.Write(writer);
                    tagStream.Align(4);

                    if (tagStream.Length == 0)
                    {
                        return(0);
                    }

                    byte[] tagGroupBuffer = tagStream.ToArray();
                    checksum = BitConverter.ToInt32(tagGroupBuffer, 0);
                    for (int i = 1; i < tagGroupBuffer.Length / 4; i++)
                    {
                        checksum ^= BitConverter.ToInt32(tagGroupBuffer, i * 4);
                    }
                }

            return(checksum);
        }
예제 #30
0
        /// <summary>
        /// Transform to a <see cref="MessagingContext" />
        /// with a <see cref="AS4Message" /> included
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task <MessagingContext> TransformAsync(ReceivedMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (message.UnderlyingStream == null)
            {
                throw new InvalidDataException(
                          $"The incoming stream from {message.Origin} is not an ebMS Message");
            }

            if (!ContentTypeSupporter.IsContentTypeSupported(message.ContentType))
            {
                throw new InvalidDataException(
                          $"ContentType {nameof(message.ContentType)} is not supported");
            }

            VirtualStream messageStream = await CopyIncomingStreamToVirtualStream(message);

            AS4Message as4Message = await DeserializeMessage(message.ContentType, messageStream, CancellationToken.None);

            return(new MessagingContext(as4Message, message, MessagingContextMode.Unknown));
        }
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            IBaseMessagePart bodyPart = pInMsg.BodyPart;
            Stream inboundStream = bodyPart.GetOriginalDataStream();
            VirtualStream virtualStream = new VirtualStream(0x280, 0x100000);
            ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream, 0x280);
            string tempFile = Path.GetTempFileName();

            using (FileStream fs = new FileStream(tempFile, FileMode.Open, FileAccess.Write, FileShare.Read))
            {
                byte[] buffer = new byte[0x280];
                int bytesRead = readOnlySeekableStream.Read(buffer, 0, buffer.Length);
                while (bytesRead != 0)
                {
                    fs.Write(buffer, 0, bytesRead);
                    fs.Flush();
                    bytesRead = readOnlySeekableStream.Read(buffer, 0, buffer.Length);
                }
            }
            VirtualStream outputStream = new VirtualStream();

            using (XmlWriter xw = XmlWriter.Create(outputStream))
            {
                const string NameSpace = "http://Codit.LFT.Schemas";
                xw.WriteStartDocument();
                xw.WriteStartElement("ns0", "LFT", NameSpace);
                xw.WriteElementString("TempFile", tempFile);
                xw.WriteEndDocument();
            }

            outputStream.Position = 0;
            pContext.ResourceTracker.AddResource(outputStream);
            pInMsg.BodyPart.Data = outputStream;
            return pInMsg;
        }
        private ReadOnlySeekableStream GetSeekableStream(IBaseMessage msg)
        {
            Stream inboundStream = msg.BodyPart.GetOriginalDataStream();
            VirtualStream virtualStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk);
            ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream);

            readOnlySeekableStream.Position = 0;
            readOnlySeekableStream.Seek(0, SeekOrigin.Begin);

            return readOnlySeekableStream;
        }
        public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
        {
            string errorMessage;

            if (!Validate(out errorMessage))
            {
                throw new ArgumentException(errorMessage);
            }

            String value = null;

            IBaseMessagePart bodyPart = pInMsg.BodyPart;

            Stream inboundStream = bodyPart.GetOriginalDataStream();
            VirtualStream virtualStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk);
            ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream);

            XmlTextReader xmlTextReader = new XmlTextReader(readOnlySeekableStream);
            XPathCollection xPathCollection = new XPathCollection();
            XPathReader xPathReader = new XPathReader(xmlTextReader, xPathCollection);
            xPathCollection.Add(XPath);

            while (xPathReader.ReadUntilMatch())
            {
                if (xPathReader.Match(0))
                {
                    value = xPathReader.ReadString();

                    if (PromoteProperty)
                    {
                        pInMsg.Context.Promote(new ContextProperty(PropertyPath), value);
                    }
                    else
                    {
                        pInMsg.Context.Write(new ContextProperty(PropertyPath), value);
                    }

                    break;
                }
            }

            if (string.IsNullOrEmpty(value) && ThrowIfNoMatch)
            {
                throw new InvalidOperationException("The specified XPath did not exist or contained an empty value.");
            }

            readOnlySeekableStream.Position = 0;
            pContext.ResourceTracker.AddResource(readOnlySeekableStream);
            bodyPart.Data = readOnlySeekableStream;

            return pInMsg;
        }
        public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
        {
            string errorMessage;

            if (!Validate(out errorMessage))
            {
                throw new ArgumentException(errorMessage);
            }

            //Get a reference to the BizTalk schema.
            var documentSpec = pContext.GetDocumentSpecByName(DocumentSpecName);

            //Get a list of properties defined in the schema.
            var annotations = documentSpec.GetPropertyAnnotationEnumerator();
            var doc = new XmlDocument();
            using (var sw = new StringWriter(new StringBuilder()))
            {
                //Create a new instance of the schema.
                doc.Load(((IFFDocumentSpec)documentSpec).CreateXmlInstance(sw));
            }

            //Write all properties to the message body.
            while (annotations.MoveNext())
            {
                var annotation = (IPropertyAnnotation)annotations.Current;
                var node = doc.SelectSingleNode(annotation.XPath);
                object propertyValue;

                if (pInMsg.Context.TryRead(new ContextProperty(annotation.Name, annotation.Namespace), out propertyValue))
                {
                    node.InnerText = propertyValue.ToString();
                }
            }

            var data = new VirtualStream();
            pContext.ResourceTracker.AddResource(data);
            doc.Save(data);
            data.Seek(0, SeekOrigin.Begin);

            var outMsg = pInMsg;
            outMsg.BodyPart.Data = data;

            //Promote message type and SchemaStrongName
            outMsg.Context.Promote(new ContextProperty(SystemProperties.MessageType), documentSpec.DocType);
            outMsg.Context.Promote(new ContextProperty(SystemProperties.SchemaStrongName), documentSpec.DocSpecStrongName);

            _outputQueue.Enqueue(outMsg);
        }
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            IBaseMessagePart bodyPart = pInMsg.BodyPart;
            Stream inboundStream = bodyPart.GetOriginalDataStream();
            VirtualStream virtualStream = new VirtualStream(0x280, 0x100000);
            ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream, 0x280);
            XmlTextReader xmlTextReader = new XmlTextReader(readOnlySeekableStream);
            XPathCollection xPathCollection = new XPathCollection();
            xPathCollection.Add("/*[local-name()='LFT' and namespace-uri()='http://Codit.LFT.Schemas']/*[local-name()='TempFile' and namespace-uri()='']");
            XPathReader xPathReader = new XPathReader(xmlTextReader, xPathCollection);
            bool ok = false;
            string val = string.Empty;
            while (xPathReader.ReadUntilMatch())
            {
                if (xPathReader.Match(0) && !ok)
                {
                    val = xPathReader.ReadString();
                    ok = true;
                }
            }
            if (ok)
            {
                VirtualStream outboundStream = new VirtualStream(0x280, 0xA00000);
                using (FileStream fs = new FileStream(val, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    byte[] buffer = new byte[4096];
                    int bytesRead = fs.Read(buffer, 0, buffer.Length);
                    while (bytesRead != 0)
                    {
                        outboundStream.Write(buffer, 0, bytesRead);
                        outboundStream.Flush();
                        bytesRead = fs.Read(buffer, 0, buffer.Length);
                    }
                }
                outboundStream.Position = 0;
                bodyPart.Data = outboundStream;
            }

            return pInMsg;
        }
        private static Stream MessageWriter(
            Action<XmlWriter, XmlReader, string, string, NamespaceFormEnum, string> writeElement, Stream stream,
            Encoding encoding, string nsToModify = null, string newNamespace = null,
            NamespaceFormEnum namespaceForm = NamespaceFormEnum.Unqualified, string xPath = "")
        {
            var outStream = new VirtualStream();

            using (var reader = XmlReader.Create(stream))
            {
                using (var writer = XmlWriter.Create(outStream, new XmlWriterSettings {Encoding = encoding}))
                {
                    while (reader.Read())
                    {
                        switch (reader.NodeType)
                        {
                            case XmlNodeType.CDATA:
                                writer.WriteCData(reader.Value);
                                break;

                            case XmlNodeType.Comment:
                                writer.WriteComment(reader.Value);
                                break;

                            case XmlNodeType.DocumentType:
                                writer.WriteDocType(reader.Name, reader.GetAttribute("PUBLIC"),
                                    reader.GetAttribute("SYSTEM"), reader.Value);
                                break;

                            case XmlNodeType.Element:
                                var isEmpty = reader.IsEmptyElement;

                                // Will call the injected action depending if it's add, modify or remove
                                writeElement(writer, reader, nsToModify, newNamespace, namespaceForm, xPath);

                                while (reader.MoveToNextAttribute())
                                {
                                    // Copy all attributed that aren't namespaces
                                    if (reader.Value != nsToModify &&
                                        reader.NamespaceURI != "http://www.w3.org/2000/xmlns/")
                                        writer.WriteAttributeString(reader.Prefix, reader.LocalName, reader.NamespaceURI,
                                            reader.Value);
                                }

                                if (isEmpty)
                                    writer.WriteEndElement();

                                break;

                            case XmlNodeType.EndElement:
                                writer.WriteFullEndElement();
                                break;

                            case XmlNodeType.EntityReference:
                                writer.WriteEntityRef(reader.Name);
                                break;

                            case XmlNodeType.XmlDeclaration:
                            case XmlNodeType.ProcessingInstruction:
                                writer.WriteProcessingInstruction(reader.Name, reader.Value);
                                break;

                            case XmlNodeType.Text:
                                writer.WriteString(reader.Value);
                                break;

                            case XmlNodeType.SignificantWhitespace:
                            case XmlNodeType.Whitespace:
                                writer.WriteWhitespace(reader.Value);
                                break;
                        }
                    }
                }
            }

            stream.Seek(0, SeekOrigin.Begin);
            outStream.Seek(0, SeekOrigin.Begin);

            return outStream;
        }
예제 #37
0
 private static Stream GetSeekeableMessageStream(IBaseMessage message)
 {
     var messageStream = message.BodyPart.GetOriginalDataStream();
     if (messageStream.CanSeek) return messageStream;
     // Create a virtual and seekable stream
     const int bufferSize = 0x280;
     const int thresholdSize = 0x100000;
     Stream virtualReadStream = new VirtualStream(bufferSize, thresholdSize);
     Stream seekableReadStream = new ReadOnlySeekableStream(messageStream, virtualReadStream, bufferSize);
     messageStream = seekableReadStream;
     message.BodyPart.Data = messageStream;
     return messageStream;
 }
예제 #38
0
        private static void writeMessage(Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg, XmlDocument xmlDoc)
        {
            var outputStream = new VirtualStream();

            using (var writer = XmlWriter.Create(outputStream, new XmlWriterSettings()
            {
                CloseOutput = false,
                Encoding = Encoding.UTF8
            }))
            {
                xmlDoc.WriteTo(writer);
                writer.Flush();
            }

            outputStream.Seek(0, SeekOrigin.Begin);

            inmsg.BodyPart.Charset = Encoding.UTF8.WebName;
            inmsg.BodyPart.Data = outputStream;
        }
예제 #39
0
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pc">Pipeline context</param>
        /// <param name="inmsg">Input message</param>
        /// <returns>Original input message</returns>
        /// <remarks>
        /// IComponent.Execute method is used to initiate
        /// the processing of the message in this pipeline component.
        /// </remarks>
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
        {
            
            #region Handle CORS Requests

            // Detect of the incoming message is an HTTP CORS request
            // http://www.w3.org/TR/cors/

            object httpMethod = null;
            httpMethod = inmsg.Context.Read(HTTP_METHOD_PROPNAME, WCF_PROPERTIES_NS);

            if (httpMethod != null && (httpMethod as string) == OPTIONS_METHOD)
            {
                // Remove the message body before returning
                var emptyOutputStream = new VirtualStream();
                inmsg.BodyPart.Data = emptyOutputStream;

                return inmsg;
            }

            #endregion


            // Make message seekable
            if (!inmsg.BodyPart.Data.CanSeek)
            {
                var originalStream = inmsg.BodyPart.Data;
                Stream seekableStream = new ReadOnlySeekableStream(originalStream);
                inmsg.BodyPart.Data = seekableStream;
                pc.ResourceTracker.AddResource(originalStream);
            }

            // Here again we are loading the entire document into memory
            // this is still a bad plan, and shouldn't be done in production
            // if you expect larger message sizes

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(inmsg.BodyPart.Data);

            if (xmlDoc.FirstChild.LocalName == "xml")
                xmlDoc.RemoveChild(xmlDoc.FirstChild);

            // Remove any root-level attributes added in the process of creating the XML
            // (Think xmlns attributes that have no meaning in JSON)

            xmlDoc.DocumentElement.Attributes.RemoveAll();

            string jsonString = JsonConvert.SerializeXmlNode(xmlDoc, Newtonsoft.Json.Formatting.Indented, true);

            #region Handle JSONP Request

            // Here we are detecting if there has been any value promoted to the jsonp callback property
            // which will contain the name of the function that should be passed the JSON data returned
            // by the service.

            object jsonpCallback = inmsg.Context.Read(JSONP_CALLBACK_PROPNAME, JSON_SCHEMAS_NS);
            string jsonpCallbackName = (jsonpCallback ?? (object)string.Empty) as string;

            if (!string.IsNullOrWhiteSpace(jsonpCallbackName))
                jsonString = string.Format("{0}({1});", jsonpCallbackName, jsonString);

            #endregion

            var outputStream = new VirtualStream(new MemoryStream(Encoding.UTF8.GetBytes(jsonString)));
            inmsg.BodyPart.Data = outputStream;

            return inmsg;
        }
예제 #40
0
        /// <summary>
        /// Implements IComponent.Execute method.
        /// </summary>
        /// <param name="pc">Pipeline context</param>
        /// <param name="inmsg">Input message</param>
        /// <returns>Original input message</returns>
        /// <remarks>
        /// IComponent.Execute method is used to initiate
        /// the processing of the message in this pipeline component.
        /// </remarks>
        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
        {

            Stream dataStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk);
            pc.ResourceTracker.AddResource(dataStream);

            using (XmlWriter writer = XmlWriter.Create(dataStream))
            {

                // Start creating the message body
                writer.WriteStartDocument();
                writer.WriteStartElement("ns0", ROOT_NODE_NAME, TARGET_NAMESPACE);

                for (int i = 0; i < inmsg.Context.CountProperties; i++)
                {

                    // Read in current property information
                    string propName = null;
                    string propNamespace = null;
                    object propValue = inmsg.Context.ReadAt(i, out propName, out propNamespace);

                    // Skip properties that we don't care about due to configuration (default is to allow all properties)
                    if (ExcludeSystemProperties && propNamespace == SYSTEM_NAMESPACE) continue;

                    if (!String.IsNullOrWhiteSpace(CustomPropertyNamespace) &&
                            propNamespace != CustomPropertyNamespace) continue;

                    // Create Property element
                    writer.WriteStartElement(PROPERTY_NODE_NAME);

                    // Create attributes on Property element
                    writer.WriteStartAttribute(NAMESPACE_ATTRIBUTE);
                    writer.WriteString(propNamespace);
                    writer.WriteEndAttribute();

                    writer.WriteStartAttribute(NAME_ATTRIBUTE);
                    writer.WriteString(propName);
                    writer.WriteEndAttribute();

                    // Write value inside property element
                    writer.WriteString(Convert.ToString(propValue));

                    writer.WriteEndElement();
                }

                // Finish out the message
                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Flush();

            }

            dataStream.Seek(0, SeekOrigin.Begin);

            var outmsg = Utility.CloneMessage(inmsg, pc);
            outmsg.BodyPart.Data = dataStream;

            return outmsg;
        }