Dijji / XstReader

Xst Reader is an open source viewer for Microsoft Outlook’s .ost and .pst files, written entirely in C#. To download an executable of the current version, go to the releases tab.
Microsoft Public License
485 stars 70 forks source link

Sender Name not showing for Office 2016 OST #3

Closed tsanjev closed 5 years ago

tsanjev commented 5 years ago

Thank you for a great effort on this. Stumbled upon this where if an ost was created by Outlook 2016 the FromTo value is Null the for each of the "m in ms". I tried to debug it but could not get to it.. if you have any pointers I'll can try to get to it.

Dijji commented 5 years ago

I'm seeing the same. I'll take a look and get back to you shortly.

Dijji

Dijji commented 5 years ago

The bug is quite subtle. XstFile.cs contains:

 public void ReadMessages(Folder f)
 {
    if (f.ContentCount > 0)
    {
        using (var fs = ndb.GetReadStream())
        {
            // Get the Contents table for the folder
            var ms = ltp.ReadTable<Message>(fs, NID.TypedNID(EnidType.CONTENTS_TABLE, f.Nid),
                  ndb.IsUnicode4K ? pgMessageList4K : pgMessageList, (m, id) => m.Nid = new NID(id));

            if (ndb.IsUnicode4K)
            { 
                foreach (var m in ms)
                    ltp.ReadProperties<Message>(fs, m.Nid, pgMessageDetail4K, m);
            }

            // We may be called on a background thread, so we need to dispatch this to the UI thread
            Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                f.Messages.Clear();
                foreach (var m in ms)
                {
                    f.AddMessage(m);
                }
            }));
        }
    }
 }

ms is a query, so the first foreach, conditional on it being a 4K file, executes the query and adds the name properties, which are missing from the contents table.

However, at the time of the second foreach, used to populate the messages in the view, ms is still a query, so it executes it again and adds Messages to the view, this time without the name properties.

A simple fix is to execute the query only once, and make ms a concrete set of objects, for instance by saying:

var ms = ltp.ReadTable<Message>(fs, NID.TypedNID(EnidType.CONTENTS_TABLE, f.Nid),
      ndb.IsUnicode4K ? pgMessageList4K : pgMessageList, (m, id) => m.Nid = new NID(id)).ToArray();

I will submit a change in response to this issue.

Dijji

Dijji commented 5 years ago

Fixed in Version 1.3