Пример #1
0
        private BinaryXmlTemplate ReadBinaryXmlTemplateRecord(FragmentHeader fragmentHeader, EventRecord record, ref int offset)
        {
            BinaryXmlTemplate template = new BinaryXmlTemplate();

            ////first 4 bytes appear to be null
            offset += 4;
            this.guidBuffer.Initialize();

            Buffer.BlockCopy(this.buffer, offset, this.guidBuffer, 0, this.guidBuffer.Length);
            offset += this.guidBuffer.Length;

            template = new BinaryXmlTemplate();
            template.TemplateGuid = new Guid(this.guidBuffer);
            template.ChunkOffset  = fragmentHeader.TemplateDefinitionOffset;
            template.Size         = BitConverter.ToInt32(this.buffer, offset);

            this.templates.Add(fragmentHeader.TemplateDefinitionOffset, template);
            ////62-66 should be a new static fragment header
            offset += 4;

            int fragmentSignature = BitConverter.ToInt32(this.buffer, offset);

            if (fragmentSignature != FragmentHeader.Signature)
            {
                throw new FragmentHeaderNotFoundException(
                          string.Format("Fragment Header for BinaryXmlTemplate not found at offset {0} in ElfChnk offset {1}", offset, this.fileOffset),
                          this.fileOffset,
                          record.GetNextRecordOffset());
            }

            offset += 4;

            return(template);
        }
Пример #2
0
        public IEnumerable <EventRecord> ReadEventRecords(int startingOffset)
        {
            int offset = startingOffset;

            while (offset < this.buffer.Length)
            {
                ////verify header
                int signature = BitConverter.ToInt32(this.buffer, offset);
                if (signature != recordSignature)
                {
                    break;
                }

                EventRecord record = new EventRecord();
                record.ChunkOffset = offset;
                offset            += 4;
                record.BlockSize   = BitConverter.ToInt32(this.buffer, offset);

                offset         += 4;
                record.RecordId = BitConverter.ToUInt64(this.buffer, offset);

                offset           += 8;
                record.RecordTime = DateTime.FromFileTime(BitConverter.ToInt64(this.buffer, offset));

                offset += 8;
                FragmentHeader parentFragmentHeader = this.ReadFragmentHeader(record, ref offset);

                BinaryXmlTemplate template = null;
                if (parentFragmentHeader.ContainsTemplateDefinition)
                {
                    template = this.ReadBinaryXmlTemplateRecord(parentFragmentHeader, record, ref offset);
                    int recordOffset = offset;

                    try
                    {
                        template.RootElement = this.ReadBinaryXmlElement(ref recordOffset);
                        offset = recordOffset;
                    }
                    catch (Exception ex)
                    {
                        throw new BinaryXmlReadException(string.Format("Problem reading BinaryXml for record at offset {0} in ElfChunk offset {1}: {2}", record.ChunkOffset, this.fileOffset, ex.Message),
                                                         this.fileOffset,
                                                         record.GetNextRecordOffset());
                    }
                }

                template = this.templates[parentFragmentHeader.TemplateDefinitionOffset];

                ////whether we found a template or not, we should be in position to read value descriptors
                int valuesOffset = offset;
                ValueDescriptor[] descriptors = this.ReadValueDescriptors(ref valuesOffset);

                ////before enumerating the template elements check if the template found the event data yet.
                if (template.RootElement.ValueType == BinaryValueType.BinXmlType)
                {
                    if (!template.RootElement.Children.Any(e => e.Name == "EventData"))
                    {
                        valuesOffset = descriptors[template.RootElement.ValueIndex].Offset;

                        FragmentHeader childFragmentHeader = this.ReadFragmentHeader(record, ref valuesOffset);

                        ////Revisit to see if we really need to store the eventDataTemplate in the Dictionary
                        BinaryXmlTemplate eventDataTemplate = null;
                        if (childFragmentHeader.ContainsTemplateDefinition)
                        {
                            eventDataTemplate             = this.ReadBinaryXmlTemplateRecord(childFragmentHeader, record, ref valuesOffset);
                            eventDataTemplate.RootElement = this.ReadBinaryXmlElement(ref valuesOffset);
                        }

                        eventDataTemplate = this.templates[childFragmentHeader.TemplateDefinitionOffset];

                        template.RootElement.Children.Add(eventDataTemplate.RootElement);
                    }
                    else
                    {
                        ////move the offset forward to the inner value descriptors for event data
                        valuesOffset = descriptors[template.RootElement.ValueIndex].Offset;
                        FragmentHeader instanceHeader = this.ReadFragmentHeader(record, ref valuesOffset);
                    }
                }

                foreach (BinaryXmlElement element in template.RootElement.EnumerateAllChildren().Where(e => e.Name != "Data"))
                {
                    switch (element.Name)
                    {
                    case "Level":
                        byte eventLevel = this.buffer[descriptors[element.ValueIndex].Offset];
                        record.SetEventLevel(eventLevel);
                        break;

                    case "Provider":
                        if (element.Attributes.Count > 0)
                        {
                            if (!string.IsNullOrEmpty(element.Attributes[0].Value))
                            {
                                record.Provider = element.Attributes[0].Value;
                            }
                            else
                            {
                                ////might be optional substitution
                                record.Provider = Encoding.Unicode.GetString(
                                    this.buffer,
                                    descriptors[element.Attributes[0].ValueIndex].Offset,
                                    descriptors[element.Attributes[0].ValueIndex].Size);
                            }
                        }
                        else
                        {
                            record.Provider = "Unknown";
                        }

                        break;

                    case "TimeCreated":
                        BinaryXmlAttribute systemTimeAttribute = element.Attributes.FirstOrDefault(e => e.Name == "SystemTime");
                        if (systemTimeAttribute != null && systemTimeAttribute.ValueType == BinaryValueType.FileTime)
                        {
                            long fileTime = BitConverter.ToInt64(this.buffer, descriptors[systemTimeAttribute.ValueIndex].Offset);
                            record.TimeCreated = DateTime.FromFileTime(fileTime);
                        }

                        break;

                    case "EventData":
                        ValueDescriptor[] eventDataDescriptors = this.ReadValueDescriptors(ref valuesOffset);
                        StringBuilder     message = new StringBuilder();
                        foreach (BinaryXmlElement dataElement in element.EnumerateAllChildren().Where(e =>
                                                                                                      e.Name == "Data" &&
                                                                                                      e.ValueType == BinaryValueType.Utf16StringArray))
                        {
                            ////There is a null terminator at the end of these
                            int dataOffset = eventDataDescriptors[dataElement.ValueIndex].Offset;
                            int dataSize   = eventDataDescriptors[dataElement.ValueIndex].Size;
                            if (dataOffset + dataSize > this.buffer.Length)
                            {
                                ////I think the buffer is recycled by the writer, and not cleaned up afterwards.  I was seeing garbage data after the LastRecordId.
                                ////I believe it just so happened that the garbage started with 0x2A2A0000 which made the logic believe there was a next record in the chunk.
                                ////Even so, I will leave this here just in case this scenario really does occur.
                                throw new EventDataOutsideOfBufferException(
                                          string.Format("Event data is refrenced outside of buffer. Record Offset: {0} BinaryXmlElement.Offset: {1}", this.FileOffset + record.ChunkOffset, dataElement.Offset),
                                          this.fileOffset + 65536,
                                          (int)ElfChunk.HeaderSize);
                            }

                            message.Append(Encoding.Unicode.GetString(this.buffer, dataOffset, dataSize).TrimEnd('\0'));
                        }

                        record.Message = message.ToString();

                        break;
                    }
                }

                offset = record.GetNextRecordOffset();
                yield return(record);

                if (record.RecordId == this.lastRecordId)
                {
                    yield break;
                }
            }
        }