0

I am trying to read an event log file, but each time it attempts to read any file it puts out the exception 'Unable to read beyond end of the stream.' I can't figure out how to fix what is calling the exception.

This is the specific line that is calling the exception: uint length = br.ReadUInt32();

If you need any more information just ask

    public unsafe void Parse(string filename)
    {
        try
        {
            // Open the file
            using (FileStream fs = new FileStream(filename, FileMode.Open))
            {
                // Use BinaryReader to read the file
                using (BinaryReader br = new BinaryReader(fs))
                {
                    //Read the header of the file
                    byte[] header = new byte[sizeof(EventLogHeader)];
                    br.Read(header, 0, header.Length);
                    EventLogHeader _h = new EventLogHeader(header);
                    /*
                    // Validate the file
                    if (!Validate(_h))
                    {
                        this.OnAction("Invalid file format.");
                        return;
                    }
                    */
                    int totalEvents = (int)(_h.NextIndex - 1);
                    this.OnAction(String.Format("Found {0} events", totalEvents));

                    // Read the items
                    EventLogEntry e;
                    int cnt = 0;
                    uint offset = _h.FooterOffset;
                    while (true)
                    {
                        byte[] buff = ReadEntry(br, ref offset);
                        e = ReadEntry(buff);
                        cnt++;
                        DateTime dt = GetTime(e.rec.TimeGenerated);
                        this.OnFoundRecord(
                            new object[] { 
                                Enum.GetName(typeof(EventLogEntryType),e.rec.EventType),
                                dt.ToShortDateString(),
                                dt.ToShortTimeString(),
                                e.SourceName,
                                e.Strings,
                                e.rec.EventCategory,
                                e.rec.EventID,
                                e.UserSid, 
                                e.Computername});
                        if (cnt % 200 == 0) this.OnProgress(cnt, totalEvents);
                        if (offset == 48)
                            break;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            this.OnAction(String.Format("Error Occured! {0}", ex.Message));
        }
        return;
    }

ReadEntry Method:

    private byte[] ReadEntry(BinaryReader br, ref uint endPoint)
    {
        br.BaseStream.Seek(endPoint - 4, SeekOrigin.Begin);
        uint length = br.ReadUInt32();
        endPoint -= length;
        br.BaseStream.Seek(endPoint, SeekOrigin.Begin);
        byte[] buff = new byte[length];
        br.Read(buff, 0, buff.Length);
        return buff;
    }

uint offset = _h.FooterOffset;

Community
  • 1
  • 1
  • Do yo have exception handing turned on? It should give you a break on the error... – Trey Dec 15 '16 at 21:41
  • Which line is giving the exception? And can you show us the `ReadEntry(br, ref offset)` method because it may be the one reading off the end of `br`. Also, why are you reading the file directly, does that work correctly if the file is modified (new events coming in, old ones being removed) while you are reading it? Why not use the [`EventLog`](https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog(v=vs.110).aspx) class to handle that and possibly many other caveats? – Quantic Dec 15 '16 at 21:42
  • I am trying to put the data into a Microsoft Form, I used the EventLog class, but it didn't quite work with the form. – Brendon 'Shadow' Banville Dec 15 '16 at 21:50
  • This is the specific line that is calling the exception: uint length = br.ReadUInt32(); – Brendon 'Shadow' Banville Dec 15 '16 at 21:56
  • https://msdn.microsoft.com/en-us/library/system.io.binaryreader.readuint32(v=vs.110).aspx 'Reads a 4-byte unsigned integer from the current stream and advances the position of the stream by four bytes'. You try to read 4 bytes where no 4 bytes are left... – MarkusEgle Dec 15 '16 at 22:06
  • How would I fix that, because removing it just breaks the 'ReadEntry' method – Brendon 'Shadow' Banville Dec 15 '16 at 22:09
  • @MarkusEgle How can that be when he is rewinding by 4 bytes every time? `br.BaseStream.Seek(endPoint - 4, SeekOrigin.Begin);` -- He seeks 4 bytes back, then reads uint32 which is 4 bytes `uint length = br.ReadUInt32();`, if the seek was successful then there should be 4 bytes there to read, no? – Quantic Dec 15 '16 at 22:14
  • [Is it safe to use Stream.Seek when a BinaryReader is open](http://stackoverflow.com/a/19134329/3090544) Maybe it is a problem of the seek on the basestream? But more likely the variable endpoint is not correct -> [Reading eventlog file causes exception](http://stackoverflow.com/q/40186512/3090544) – MarkusEgle Dec 15 '16 at 22:31
  • by taking out the `- 4` from `br.BaseStream.Seek(endPoint - 4, SeekOrigin.Begin);` I was able to get it to not throw the exception the first time it runs through the rest of my code, but on the second time it gets to uint length = `br.ReadUInt32();` it again throws the same exception. – Brendon 'Shadow' Banville Dec 15 '16 at 22:54
  • The best I can come up with is that `_h.FooterOffset;` is not returning the value you think it is. Say the stream is 1000 bytes long, for all we know `_h.FooterOffset;` is returning 10,000, then you subtract 4 to get 9,996, then try to seek there which is off the end of the stream. Or it's between 0 and 3 and since it's unsigned when you subtract 4 it rolls over to uint.MaxValue. Maybe whatever byte description of an Event you are working with is wrong or outdated. – Quantic Dec 15 '16 at 23:25
  • Well, if I stop the scan when I am positive it is at the end of the stream, then do you think that would fix it? – Brendon 'Shadow' Banville Dec 16 '16 at 00:34
  • I don't know what will fix it because I don't know what the problem is. I can't even find a description online of how to read the bytes of an event log file and produce events out of it. I suspect this code is buggy on more than just this one level so I don't see the point of "fixing" this one issue when there are likely many other unknown issues. You tell me, how are you so sure `_h.FooterOffset;` is returning the byte position of the footer? How do you know? IMO you should use the `EventLog` class built in to .NET, not this random code that no one knows what it's doing. – Quantic Dec 16 '16 at 16:30

0 Answers0