Exemplo n.º 1
0
        public System.Collections.Generic.IEnumerable <Item> GetAllItems()
        {
            foreach (ItemDescriptor itemDescriptor in descriptorIndexTree.Nodes.Values)
            {
                if (itemDescriptor != null)
                {
                    Table itemTable = null;
                    LocalDescriptorList localDescriptorList = null;

                    DataStructure localDescriptorListNode = Util.GetLocalDescriptionListNode(reader.PstFile.DataIndexTree, itemDescriptor.LocalDescriptorListId);
                    DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(itemDescriptor.TableId);

                    if (dataNode != null)
                    {
                        localDescriptorList = Util.GetLocalDescriptorList(reader, localDescriptorListNode);
                        itemTable           = Util.GetTable(reader, dataNode, localDescriptorList);
                    }

                    if (itemTable != null)
                    {
                        if (!Util.IsFolder(itemTable))
                        {
                            Item item = Util.GetItem(reader, localDescriptorList, itemTable, itemDescriptor.Id, itemDescriptor.ParentItemDescriptorId);
                            yield return(item);
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets the folders.
        /// </summary>
        /// <returns>IList{Folder}.</returns>
        public IList <Folder> GetFolders()
        {
            IList <Folder> folders = new List <Folder>();

            for (int i = 0; i < descriptor.Children.Count; i++)
            {
                ItemDescriptor childDescriptor = descriptor.Children[i];

                DataStructure childLocalDescriptorListNode = Util.GetLocalDescriptionListNode(reader.PstFile.DataIndexTree, childDescriptor.LocalDescriptorListId);
                DataStructure childDataNode = reader.PstFile.DataIndexTree.GetDataStructure(childDescriptor.TableId);

                if (childDataNode != null)
                {
                    LocalDescriptorList localDescriptorList = Util.GetLocalDescriptorList(reader, childLocalDescriptorListNode);

                    Table childTable = Util.GetTable(reader, childDataNode, localDescriptorList);

                    if (childTable != null && Util.IsFolder(childTable))
                    {
                        Folder child = new Folder(reader, childDescriptor, childTable);
                        folders.Add(child);
                    }
                }
            }

            return(folders);
        }
Exemplo n.º 3
0
 internal TableBC(PstFileReader reader, byte[] tableBuffer, LocalDescriptorList localDescriptorList, DataStructure tableDataNode)
 {
     try
     {
         Parse(reader, tableBuffer, localDescriptorList, tableDataNode);
     }
     catch (Exception e)
     {
         System.Diagnostics.Trace.WriteLine(String.Format("\nTableBC parsing error - run ScanPST to correct, attempting to continue:\n{0}", e.Message));
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Gets the item.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>Item.</returns>
        public Item GetItem(long id)
        {
            ulong key = (ulong)id;

            ItemDescriptor itemDescriptor = descriptorIndexTree.Nodes.ContainsKey(key) ? (ItemDescriptor)descriptorIndexTree.Nodes[key] : null;

            if (itemDescriptor == null)
            {
                return(null);
            }

            Table itemTable = null;
            LocalDescriptorList localDescriptorList = null;

            DataStructure localDescriptorListNode = Util.GetLocalDescriptionListNode(reader.PstFile.DataIndexTree, itemDescriptor.LocalDescriptorListId);
            DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(itemDescriptor.TableId);

            if (dataNode != null)
            {
                localDescriptorList = Util.GetLocalDescriptorList(reader, localDescriptorListNode);
                try
                {
                    itemTable = Util.GetTable(reader, dataNode, localDescriptorList);
                }
                catch (Exception e)
                {
                    System.Diagnostics.Trace.TraceWarning("PstFile.GetItem({0}) Util.GetTable {1}", id, e.Message);
                }
            }

            if (itemTable == null)
            {
                return(null);
            }

            if (!Util.IsFolder(itemTable))
            {
                Item item = Util.GetItem(reader, localDescriptorList, itemTable, itemDescriptor.Id, itemDescriptor.ParentItemDescriptorId);
                return(item);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 5
0
        private void Parse(PstFileReader reader, byte[] tableBuffer, LocalDescriptorList localDescriptorList, DataStructure tableDataNode)
        {
            ushort indexOffset         = BitConverter.ToUInt16(tableBuffer, 0);
            ushort tableType           = BitConverter.ToUInt16(tableBuffer, 2);
            uint   tableValueReference = BitConverter.ToUInt32(tableBuffer, 4);

            TableIndex index = new TableIndex(tableBuffer, indexOffset, reader.PstFile.Is64Bit);

            TableIndexItem tableHeader9CIndexItem = index.GetItem(tableValueReference);

            uint tableHeaderB5Reference = BitConverter.ToUInt32(tableBuffer, tableHeader9CIndexItem.StartOffset);

            TableIndexItem tableHeaderB5IndexItem = index.GetItem(tableHeaderB5Reference);

            byte[] tableHeaderB5Buffer = new byte[tableHeaderB5IndexItem.EndOffset - tableHeaderB5IndexItem.StartOffset];
            System.Array.Copy(tableBuffer, tableHeaderB5IndexItem.StartOffset, tableHeaderB5Buffer, 0, tableHeaderB5Buffer.Length);

            TableHeaderB5 tableHeaderB5 = new TableHeaderB5(tableHeaderB5Buffer);

            if (tableHeaderB5.Type != 0xB5)
            {
                return;
            }

            if (tableHeaderB5.ValueEntriesIndexReference == 0)
            {
                return;
            }

            TableIndexItem valueEntiresIndexItem = index.GetItem(tableHeaderB5.ValueEntriesIndexReference);

            for (int i = 0; i < valueEntiresIndexItem.EndOffset - valueEntiresIndexItem.StartOffset; i += 20)
            {
                int startIndex = valueEntiresIndexItem.StartOffset + i;

                byte[] guid = new byte[16];
                System.Array.Copy(tableBuffer, startIndex, guid, 0, 16);

                uint descriptorId = BitConverter.ToUInt16(tableBuffer, startIndex + 16);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Gets the folder.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>Folder.</returns>
        public Folder GetFolder(long id)
        {
            ulong key = (ulong)id;

            ItemDescriptor itemDescriptor = descriptorIndexTree.Nodes.ContainsKey(key) ? (ItemDescriptor)descriptorIndexTree.Nodes[key] : null;

            if (itemDescriptor == null)
            {
                return(null);
            }

            Table folderTable = null;
            LocalDescriptorList localDescriptorList = null;

            DataStructure localDescriptorListNode = Util.GetLocalDescriptionListNode(reader.PstFile.DataIndexTree, itemDescriptor.LocalDescriptorListId);
            DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(itemDescriptor.TableId);

            if (dataNode != null)
            {
                localDescriptorList = Util.GetLocalDescriptorList(reader, localDescriptorListNode);
                folderTable         = Util.GetTable(reader, dataNode, localDescriptorList);
            }

            if (folderTable == null)
            {
                return(null);
            }

            if (Util.IsFolder(folderTable))
            {
                Folder folder = new Folder(reader, itemDescriptor, folderTable);
                return(folder);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Gets the items.
        /// </summary>
        /// <param name="startIndex">The start index.</param>
        /// <param name="endIndex">The end index.</param>
        /// <param name="includeAttachments">if set to <c>true</c> [include attachments].</param>
        /// <returns>IList{Item}.</returns>
        public IList <Item> GetItems(int startIndex, int endIndex, bool includeAttachments)
        {
            IList <Item> items = new List <Item>();

            if (startIndex < 0)
            {
                startIndex = 0;
            }

            if (endIndex > descriptor.Children.Count)
            {
                endIndex = descriptor.Children.Count;
            }

            for (int i = startIndex; i < endIndex; i++)
            {
                ItemDescriptor childDescriptor = descriptor.Children[i];

                DataStructure childLocalDescriptorListNode = Util.GetLocalDescriptionListNode(reader.PstFile.DataIndexTree, childDescriptor.LocalDescriptorListId);
                DataStructure childDataNode = reader.PstFile.DataIndexTree.GetDataStructure(childDescriptor.TableId);

                if (childDataNode != null)
                {
                    LocalDescriptorList localDescriptorList = Util.GetLocalDescriptorList(reader, childLocalDescriptorListNode);

                    Table childTable = Util.GetTable(reader, childDataNode, localDescriptorList);

                    if (childTable != null && !Util.IsFolder(childTable))
                    {
                        Item child = Util.GetItem(reader, localDescriptorList, childTable, childDescriptor.Id, childDescriptor.ParentItemDescriptorId, includeAttachments);
                        items.Add(child);
                    }
                }
            }

            return(items);
        }
Exemplo n.º 8
0
        private void Parse(PstFileReader reader, byte[] tableBuffer, LocalDescriptorList localDescriptorList, DataStructure tableDataNode)
        {
            ushort indexOffset         = BitConverter.ToUInt16(tableBuffer, 0);
            ushort tableType           = BitConverter.ToUInt16(tableBuffer, 2);
            uint   tableValueReference = BitConverter.ToUInt32(tableBuffer, 4);

            TableIndex index = new TableIndex(tableBuffer, indexOffset, reader.PstFile.Is64Bit);

            TableIndexItem tableHeaderACIndexItem = index.GetItem(tableValueReference);

            byte[] tableHeaderACBuffer = new byte[tableHeaderACIndexItem.EndOffset - tableHeaderACIndexItem.StartOffset];
            System.Array.Copy(tableBuffer, tableHeaderACIndexItem.StartOffset, tableHeaderACBuffer, 0, tableHeaderACBuffer.Length);

            TableHeaderAC tableHeaderAC = new TableHeaderAC(tableHeaderACBuffer);

            if (tableHeaderAC.Type != 0xAC)
            {
                return;
            }

            byte[] entryDefinitionsBuffer = null;

            if (tableHeaderAC.TableEntryDefinitionReference < 0x8000)
            {
                TableIndexItem tableEntryDefinitionIndexItem = index.GetItem(tableHeaderAC.TableEntryDefinitionReference);

                entryDefinitionsBuffer = new byte[tableEntryDefinitionIndexItem.EndOffset - tableEntryDefinitionIndexItem.StartOffset];
                System.Array.Copy(tableBuffer, tableEntryDefinitionIndexItem.StartOffset, entryDefinitionsBuffer, 0, entryDefinitionsBuffer.Length);
            }
            else
            {
                if (localDescriptorList != null)
                {
                    LocalDescriptorListElement element = localDescriptorList.Elements.ContainsKey(tableHeaderAC.TableEntryDefinitionReference) ? localDescriptorList.Elements[tableHeaderAC.TableEntryDefinitionReference] : null;

                    if (element != null)
                    {
                        DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(element.DataStructureId);

                        if (dataNode != null)
                        {
                            entryDefinitionsBuffer = Util.GetBuffer(reader, dataNode);
                        }
                    }
                }
            }

            if (entryDefinitionsBuffer == null)
            {
                return;
            }

            IList <TableACEntryDefinition> entryDefinitions = new List <TableACEntryDefinition>();

            for (int i = 0; i < tableHeaderAC.EntryDefinitionCount; i++)
            {
                TableACEntryDefinition entry = new TableACEntryDefinition();

                entry.EntryValueType        = BitConverter.ToUInt16(entryDefinitionsBuffer, i * 16);
                entry.EntryId               = BitConverter.ToUInt16(entryDefinitionsBuffer, i * 16 + 2);
                entry.ValueArrayEntryOffset = BitConverter.ToUInt16(entryDefinitionsBuffer, i * 16 + 4);
                entry.ValueArrayEntrySize   = BitConverter.ToUInt16(entryDefinitionsBuffer, i * 16 + 6);
                entry.ValueArrayEntryNumber = BitConverter.ToUInt16(entryDefinitionsBuffer, i * 16 + 8);
                entry.DescriptorId          = BitConverter.ToUInt32(entryDefinitionsBuffer, i * 16 + 12);

                entryDefinitions.Add(entry);
            }

            TableIndexItem tableHeaderB5IndexItem = index.GetItem(tableHeaderAC.B5HeaderReference);

            byte[] tableHeaderB5Buffer = new byte[8];
            System.Array.Copy(tableBuffer, tableHeaderB5IndexItem.StartOffset, tableHeaderB5Buffer, 0, 8);

            TableHeaderB5 tableHeaderB5 = new TableHeaderB5(tableHeaderB5Buffer);

            if (tableHeaderB5.Type != 0xB5)
            {
                return;
            }

            byte[] entryValueBuffer = null;

            if (tableHeaderAC.ValueEntriesIndexReference == 0)
            {
                return;
            }

            if (localDescriptorList != null)
            {
                LocalDescriptorListElement element = localDescriptorList.Elements.ContainsKey(tableHeaderAC.ValueEntriesIndexReference) ? localDescriptorList.Elements[tableHeaderAC.ValueEntriesIndexReference] : null;

                if (element != null)
                {
                    DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(element.DataStructureId);

                    if (dataNode != null)
                    {
                        entryValueBuffer = Util.GetBuffer(reader, dataNode);
                    }
                }
                else
                {
                    TableIndexItem entryValueIndexItem = index.GetItem(tableHeaderAC.ValueEntriesIndexReference);

                    entryValueBuffer = new byte[entryValueIndexItem.EndOffset - entryValueIndexItem.StartOffset];
                    System.Array.Copy(tableBuffer, entryValueIndexItem.StartOffset, entryValueBuffer, 0, entryValueBuffer.Length);
                }
            }

            if (entryValueBuffer == null)
            {
                return;
            }

            for (int i = 0; i < entryDefinitions.Count; i++)
            {
                TableACEntryDefinition entryDefinition = entryDefinitions[i];

                TableEntry entry = new TableEntry(reader.PstFile.Encoding);
                entry.PropertyTag = new PropertyTag(entryDefinition.EntryId, entryDefinition.EntryValueType);

                if (entry.PropertyTag.Type == PropertyType.Short || entry.PropertyTag.Type == PropertyType.Boolean)
                {
                    entry.ValueBuffer = new byte[2];
                    System.Array.Copy(entryValueBuffer, entryDefinition.ValueArrayEntryOffset, entry.ValueBuffer, 0, 2);
                }
                else if (entry.PropertyTag.Type == PropertyType.Integer || entry.PropertyTag.Type == PropertyType.Float)
                {
                    entry.ValueBuffer = new byte[4];
                    System.Array.Copy(entryValueBuffer, entryDefinition.ValueArrayEntryOffset, entry.ValueBuffer, 0, 4);
                }
                else if (entry.PropertyTag.Type == PropertyType.Long || entry.PropertyTag.Type == PropertyType.Double || entry.PropertyTag.Type == PropertyType.Currency ||
                         entry.PropertyTag.Type == PropertyType.ApplicationTime || entry.PropertyTag.Type == PropertyType.SystemTime)
                {
                    entry.ValueBuffer = new byte[8];
                    System.Array.Copy(entryValueBuffer, entryDefinition.ValueArrayEntryOffset, entry.ValueBuffer, 0, 8);
                }
                else if (entry.PropertyTag.Type == PropertyType.ShortArray || entry.PropertyTag.Type == PropertyType.IntegerArray || entry.PropertyTag.Type == PropertyType.FloatArray ||
                         entry.PropertyTag.Type == PropertyType.LongArray || entry.PropertyTag.Type == PropertyType.DoubleArray || entry.PropertyTag.Type == PropertyType.CurrencyArray ||
                         entry.PropertyTag.Type == PropertyType.String || entry.PropertyTag.Type == PropertyType.String8 || entry.PropertyTag.Type == PropertyType.StringArray || entry.PropertyTag.Type == PropertyType.String8Array ||
                         entry.PropertyTag.Type == PropertyType.Object || entry.PropertyTag.Type == PropertyType.Binary || entry.PropertyTag.Type == PropertyType.BinaryArray || entry.PropertyTag.Type == PropertyType.Guid || entry.PropertyTag.Type == PropertyType.GuidArray)
                {
                    if (entryDefinition.DescriptorId > 0)
                    {
                        if (localDescriptorList != null)
                        {
                            LocalDescriptorListElement element = localDescriptorList.Elements.ContainsKey(entryDefinition.DescriptorId) ? localDescriptorList.Elements[entryDefinition.DescriptorId] : null;

                            if (element != null)
                            {
                                DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(element.DataStructureId);

                                if (dataNode != null)
                                {
                                    byte[] valueBuffer = Util.GetBuffer(reader, dataNode);

                                    if (valueBuffer != null && valueBuffer.Length > 3)
                                    {
                                        ushort tableA5Type = BitConverter.ToUInt16(valueBuffer, 2);

                                        if (tableA5Type == 0xA5)
                                        {
                                            TableA5 tableA5 = new TableA5(reader, valueBuffer);
                                            valueBuffer = tableA5.GetValue(entryDefinition.ValueArrayEntryOffset);
                                        }
                                    }

                                    entry.ValueBuffer = valueBuffer;
                                }
                            }
                        }
                    }
                    else
                    {
                        uint valueReference = BitConverter.ToUInt32(entryValueBuffer, entryDefinition.ValueArrayEntryOffset);

                        if (valueReference == 0)
                        {
                            continue;
                        }

                        if (Util.IsInternalReference(valueReference))
                        {
                            TableIndexItem indexItem = index.GetItem(valueReference);

                            if (indexItem != null)
                            {
                                if (indexItem.EndOffset > indexItem.StartOffset)
                                {
                                    entry.ValueBuffer = new byte[indexItem.EndOffset - indexItem.StartOffset];

                                    if (tableBuffer.Length >= indexItem.StartOffset + entry.ValueBuffer.Length)
                                    {
                                        System.Array.Copy(tableBuffer, indexItem.StartOffset, entry.ValueBuffer, 0, entry.ValueBuffer.Length);
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (localDescriptorList != null)
                            {
                                LocalDescriptorListElement element = localDescriptorList.Elements.ContainsKey(valueReference) ? localDescriptorList.Elements[valueReference] : null;

                                if (element != null)
                                {
                                    DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(element.DataStructureId);

                                    if (dataNode != null)
                                    {
                                        byte[] valueBuffer = Util.GetBuffer(reader, dataNode);

                                        if (valueBuffer != null && valueBuffer.Length > 3)
                                        {
                                            ushort tableA5Type = BitConverter.ToUInt16(valueBuffer, 2);

                                            if (tableA5Type == 0xA5)
                                            {
                                                TableA5 tableA5 = new TableA5(reader, valueBuffer);
                                                valueBuffer = tableA5.GetValue(entryDefinition.ValueArrayEntryOffset);
                                            }
                                        }

                                        entry.ValueBuffer = valueBuffer;
                                    }
                                }
                            }
                        }
                    }
                }

                Entries.Add(entry);
            }
        }
Exemplo n.º 9
0
 internal TableAC(PstFileReader reader, byte[] tableBuffer, LocalDescriptorList localDescriptorList, DataStructure tableDataNode)
 {
     Parse(reader, tableBuffer, localDescriptorList, tableDataNode);
 }
Exemplo n.º 10
0
        private void Parse(PstFileReader reader, byte[] tableBuffer, LocalDescriptorList localDescriptorList, DataStructure tableDataNode)
        {
            ushort indexOffset         = BitConverter.ToUInt16(tableBuffer, 0);
            ushort tableType           = BitConverter.ToUInt16(tableBuffer, 2);
            uint   tableValueReference = BitConverter.ToUInt32(tableBuffer, 4);

            TableIndex index = new TableIndex(tableBuffer, indexOffset, reader.PstFile.Is64Bit);

            TableIndexItem tableHeaderB5IndexItem = index.GetItem(tableValueReference);

            if (tableHeaderB5IndexItem == null)
            {
                return;
            }

            byte[] tableHeaderB5Buffer = new byte[8];
            System.Array.Copy(tableBuffer, tableHeaderB5IndexItem.StartOffset, tableHeaderB5Buffer, 0, 8);

            TableHeaderB5     tableHeaderB5     = new TableHeaderB5(tableHeaderB5Buffer);
            BTreeOnHeapHeader bTreeOnHeapHeader = new BTreeOnHeapHeader(tableHeaderB5Buffer);

            if (tableHeaderB5.Type != 0xB5)
            {
                return;
            }

            if (tableHeaderB5.ValueEntriesIndexReference == 0)
            {
                return;
            }

            uint valueEntryReference = tableHeaderB5.ValueEntriesIndexReference;

            byte[] entryValueBuffer = null;

            if (bTreeOnHeapHeader.BIdxLevels == 2)
            {
                //Not implemented
                return;
            }
            else if (bTreeOnHeapHeader.BIdxLevels == 1)
            {
                TableIndexItem entryIndexItem = index.Items[(int)bTreeOnHeapHeader.HidRoot.Index];

                byte[] level1EntryValueBuffer = new byte[entryIndexItem.EndOffset - entryIndexItem.StartOffset];
                System.Array.Copy(tableBuffer, entryIndexItem.StartOffset, level1EntryValueBuffer, 0, level1EntryValueBuffer.Length);

                MemoryStream entryValueBufferMemoryStream = new MemoryStream();

                for (int i = 0; i < level1EntryValueBuffer.Length; i += 6)
                {
                    byte[] heapIdBuffer = new byte[4];
                    System.Array.Copy(level1EntryValueBuffer, i + 2, heapIdBuffer, 0, 4);

                    HeapId heapId = new HeapId(heapIdBuffer);

                    TableIndexItem tempEntryIndexItem = index.Items[(int)heapId.Index];

                    byte[] tempLevel1EntryValueBuffer = new byte[tempEntryIndexItem.EndOffset - tempEntryIndexItem.StartOffset];
                    System.Array.Copy(tableBuffer, tempEntryIndexItem.StartOffset, tempLevel1EntryValueBuffer, 0, tempLevel1EntryValueBuffer.Length);

                    entryValueBufferMemoryStream.Write(tempLevel1EntryValueBuffer, 0, tempLevel1EntryValueBuffer.Length);
                }

                entryValueBuffer = entryValueBufferMemoryStream.ToArray();
            }
            else
            {
                TableIndexItem entryIndexItem = index.GetItem(valueEntryReference);

                if (entryIndexItem != null)
                {
                    entryValueBuffer = new byte[entryIndexItem.EndOffset - entryIndexItem.StartOffset];
                    System.Array.Copy(tableBuffer, entryIndexItem.StartOffset, entryValueBuffer, 0, entryValueBuffer.Length);
                }
            }
            if (entryValueBuffer != null)
            {
                for (int i = 0; i < entryValueBuffer.Length - 2; i += 8)
                {
                    ushort tag  = BitConverter.ToUInt16(entryValueBuffer, i);
                    ushort type = BitConverter.ToUInt16(entryValueBuffer, i + 2);

                    TableEntry entry = new TableEntry(reader.PstFile.Encoding);
                    entry.PropertyTag = new PropertyTag(tag, type);

                    if (entry.PropertyTag.Type == PropertyType.Boolean)
                    {
                        int intValue = BitConverter.ToInt32(entryValueBuffer, i + 4);

                        if (intValue != 0) //true
                        {
                            entry.ValueBuffer = BitConverter.GetBytes((short)1);
                        }
                        else
                        {
                            entry.ValueBuffer = BitConverter.GetBytes((short)0);
                        }
                    }
                    else if (entry.PropertyTag.Type == PropertyType.Short)
                    {
                        entry.ValueBuffer = new byte[2];
                        System.Array.Copy(entryValueBuffer, i + 4, entry.ValueBuffer, 0, 2);
                    }
                    else if (entry.PropertyTag.Type == PropertyType.Integer || entry.PropertyTag.Type == PropertyType.Float)
                    {
                        entry.ValueBuffer = new byte[4];
                        System.Array.Copy(entryValueBuffer, i + 4, entry.ValueBuffer, 0, 4);
                    }
                    else if (entry.PropertyTag.Type == PropertyType.Object)
                    {
                        uint valueReference = BitConverter.ToUInt32(entryValueBuffer, i + 4);

                        if (valueReference == 0)
                        {
                            continue;
                        }

                        if (Util.IsInternalReference(valueReference))
                        {
                            TableIndexItem indexItem = index.GetItem(valueReference);

                            if (indexItem != null)
                            {
                                if (indexItem.EndOffset > indexItem.StartOffset)
                                {
                                    entry.ValueBuffer = new byte[indexItem.EndOffset - indexItem.StartOffset];

                                    if (tableBuffer.Length >= indexItem.StartOffset + entry.ValueBuffer.Length)
                                    {
                                        System.Array.Copy(tableBuffer, indexItem.StartOffset, entry.ValueBuffer, 0, entry.ValueBuffer.Length);
                                    }

                                    uint embeddedItemId = BitConverter.ToUInt32(entry.ValueBuffer, 0);

                                    if (localDescriptorList != null)
                                    {
                                        LocalDescriptorListElement element = localDescriptorList.Elements.ContainsKey(embeddedItemId) ? localDescriptorList.Elements[embeddedItemId] : null;

                                        if (element != null)
                                        {
                                            DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(element.DataStructureId);

                                            if (dataNode != null)
                                            {
                                                entry.ValueBuffer = Util.GetBuffer(reader, dataNode);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (localDescriptorList != null)
                            {
                                LocalDescriptorListElement element = localDescriptorList.Elements.ContainsKey(valueReference) ? localDescriptorList.Elements[valueReference] : null;

                                if (element != null)
                                {
                                    DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(element.DataStructureId);

                                    if (dataNode != null)
                                    {
                                        byte[] valueBuffer = Util.GetBuffer(reader, dataNode);
                                        entry.ValueBuffer = valueBuffer;
                                    }
                                }
                            }
                        }
                    }
                    else if (entry.PropertyTag.Type == PropertyType.Long || entry.PropertyTag.Type == PropertyType.Double || entry.PropertyTag.Type == PropertyType.Currency ||
                             entry.PropertyTag.Type == PropertyType.ShortArray || entry.PropertyTag.Type == PropertyType.IntegerArray || entry.PropertyTag.Type == PropertyType.FloatArray ||
                             entry.PropertyTag.Type == PropertyType.LongArray || entry.PropertyTag.Type == PropertyType.DoubleArray || entry.PropertyTag.Type == PropertyType.CurrencyArray ||
                             entry.PropertyTag.Type == PropertyType.String || entry.PropertyTag.Type == PropertyType.String8 || entry.PropertyTag.Type == PropertyType.StringArray || entry.PropertyTag.Type == PropertyType.String8Array ||
                             entry.PropertyTag.Type == PropertyType.Binary || entry.PropertyTag.Type == PropertyType.BinaryArray || entry.PropertyTag.Type == PropertyType.Guid ||
                             entry.PropertyTag.Type == PropertyType.GuidArray || entry.PropertyTag.Type == PropertyType.ApplicationTime || entry.PropertyTag.Type == PropertyType.SystemTime)
                    {
                        uint valueReference = BitConverter.ToUInt32(entryValueBuffer, i + 4);

                        if (valueReference == 0)
                        {
                            continue;
                        }

                        if (Util.IsInternalReference(valueReference))
                        {
                            TableIndexItem indexItem = index.GetItem(valueReference);

                            if (indexItem != null)
                            {
                                if (indexItem.EndOffset > indexItem.StartOffset)
                                {
                                    entry.ValueBuffer = new byte[indexItem.EndOffset - indexItem.StartOffset];

                                    if (tableBuffer.Length >= indexItem.StartOffset + entry.ValueBuffer.Length)
                                    {
                                        System.Array.Copy(tableBuffer, indexItem.StartOffset, entry.ValueBuffer, 0, entry.ValueBuffer.Length);
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (localDescriptorList != null)
                            {
                                LocalDescriptorListElement element = localDescriptorList.Elements.ContainsKey(valueReference) ? localDescriptorList.Elements[valueReference] : null;

                                if (element != null)
                                {
                                    DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(element.DataStructureId);

                                    if (dataNode != null)
                                    {
                                        byte[] valueBuffer = Util.GetBuffer(reader, dataNode);
                                        entry.ValueBuffer = valueBuffer;
                                    }
                                }
                            }
                        }
                    }

                    Entries.Add(entry);
                }
            }
        }
Exemplo n.º 11
0
        private void Parse(PstFileReader reader, byte[] tableBuffer, LocalDescriptorList localDescriptorList, DataStructure tableDataNode, bool isRecipientsTable)
        {
            ushort indexOffset         = BitConverter.ToUInt16(tableBuffer, 0);
            ushort tableType           = BitConverter.ToUInt16(tableBuffer, 2);
            uint   tableValueReference = BitConverter.ToUInt32(tableBuffer, 4);

            TableIndex index = new TableIndex(tableBuffer, indexOffset, reader.PstFile.Is64Bit);

            TableIndexItem tableHeader7CIndexItem = index.GetItem(tableValueReference);

            if (tableHeader7CIndexItem == null)
            {
                return;
            }

            byte[] tableHeader7CBuffer = new byte[tableHeader7CIndexItem.EndOffset - tableHeader7CIndexItem.StartOffset];

            if (tableHeader7CBuffer.Length > tableBuffer.Length - tableHeader7CIndexItem.StartOffset)
            {
                return;
            }

            System.Array.Copy(tableBuffer, tableHeader7CIndexItem.StartOffset, tableHeader7CBuffer, 0, tableHeader7CBuffer.Length);

            TableHeader7C tableHeader7C = new TableHeader7C(tableHeader7CBuffer);

            if (tableHeader7C.Type != 0x7C)
            {
                return;
            }

            TableIndexItem tableHeaderB5IndexItem = index.GetItem(tableHeader7C.B5HeaderReference);

            byte[] tableHeaderB5Buffer = new byte[8];
            System.Array.Copy(tableBuffer, tableHeaderB5IndexItem.StartOffset, tableHeaderB5Buffer, 0, 8);

            TableHeaderB5     tableHeaderB5     = new TableHeaderB5(tableHeaderB5Buffer);
            BTreeOnHeapHeader bTreeOnHeapHeader = new BTreeOnHeapHeader(tableHeaderB5Buffer);

            if (tableHeaderB5.Type != 0xB5)
            {
                return;
            }

            if (tableHeader7C.ValueEntriesIndexReference == 0)
            {
                return;
            }

            byte[] entryValueBuffer = null;
            bool   useB5Header      = false;

            if (bTreeOnHeapHeader.BIdxLevels == 2)
            {
                //Not implemented
                return;
            }
            else if (bTreeOnHeapHeader.BIdxLevels == 1)
            {
                byte[] level1EntryValueBuffer = null;

                if (bTreeOnHeapHeader.HidRoot.Index > 0 && bTreeOnHeapHeader.HidRoot.BlockIndex == 0)
                {
                    TableIndexItem entryIndexItem = index.Items.ContainsKey((int)bTreeOnHeapHeader.HidRoot.Index) ? index.Items[(int)bTreeOnHeapHeader.HidRoot.Index] : null;

                    if (entryIndexItem != null)
                    {
                        level1EntryValueBuffer = new byte[entryIndexItem.EndOffset - entryIndexItem.StartOffset];
                        System.Array.Copy(tableBuffer, entryIndexItem.StartOffset, level1EntryValueBuffer, 0, level1EntryValueBuffer.Length);
                    }
                }
                else if (bTreeOnHeapHeader.HidRoot.Index > 0 && bTreeOnHeapHeader.HidRoot.BlockIndex > 0)
                {
                    if (index.SecondItems.Length >= bTreeOnHeapHeader.HidRoot.BlockIndex)
                    {
                        IDictionary <int, TableIndexItem> secondIndexTable = index.SecondItems[bTreeOnHeapHeader.HidRoot.BlockIndex - 1];

                        if (secondIndexTable != null)
                        {
                            TableIndexItem entryIndexItem = secondIndexTable.ContainsKey((int)bTreeOnHeapHeader.HidRoot.Index) ? secondIndexTable[(int)bTreeOnHeapHeader.HidRoot.Index] : null;

                            if (entryIndexItem != null)
                            {
                                level1EntryValueBuffer = new byte[entryIndexItem.EndOffset - entryIndexItem.StartOffset];
                                System.Array.Copy(tableBuffer, entryIndexItem.StartOffset, level1EntryValueBuffer, 0, level1EntryValueBuffer.Length);
                            }
                        }
                    }
                }

                MemoryStream entryValueBufferMemoryStream = new MemoryStream();

                for (int i = 0; i < level1EntryValueBuffer.Length; i += 8)
                {
                    byte[] heapIdBuffer = new byte[4];
                    System.Array.Copy(level1EntryValueBuffer, i + 4, heapIdBuffer, 0, 4);

                    HeapId heapId = new HeapId(heapIdBuffer);

                    if (heapId.Index > 0 && heapId.BlockIndex == 0)
                    {
                        TableIndexItem tempEntryIndexItem = index.Items.ContainsKey((int)heapId.Index) ? index.Items[(int)heapId.Index] : null;

                        if (tempEntryIndexItem != null)
                        {
                            byte[] tempLevel1EntryValueBuffer = new byte[tempEntryIndexItem.EndOffset - tempEntryIndexItem.StartOffset];
                            System.Array.Copy(tableBuffer, tempEntryIndexItem.StartOffset, tempLevel1EntryValueBuffer, 0, tempLevel1EntryValueBuffer.Length);

                            entryValueBufferMemoryStream.Write(tempLevel1EntryValueBuffer, 0, tempLevel1EntryValueBuffer.Length);
                        }
                    }
                    else if (heapId.Index > 0 && heapId.BlockIndex > 0)
                    {
                        if (index.SecondItems.Length >= heapId.BlockIndex)
                        {
                            IDictionary <int, TableIndexItem> secondIndexTable = index.SecondItems[heapId.BlockIndex - 1];

                            if (secondIndexTable != null)
                            {
                                TableIndexItem tempEntryIndexItem = secondIndexTable.ContainsKey((int)heapId.Index) ? secondIndexTable[(int)heapId.Index] : null;

                                if (tempEntryIndexItem != null)
                                {
                                    byte[] tempLevel1EntryValueBuffer = new byte[tempEntryIndexItem.EndOffset - tempEntryIndexItem.StartOffset];
                                    System.Array.Copy(tableBuffer, tempEntryIndexItem.StartOffset, tempLevel1EntryValueBuffer, 0, tempLevel1EntryValueBuffer.Length);

                                    entryValueBufferMemoryStream.Write(tempLevel1EntryValueBuffer, 0, tempLevel1EntryValueBuffer.Length);
                                }
                            }
                        }
                    }
                }

                entryValueBuffer = entryValueBufferMemoryStream.ToArray();
                useB5Header      = true;
            }
            else if (localDescriptorList != null)
            {
                LocalDescriptorListElement element = localDescriptorList.Elements.ContainsKey(tableHeader7C.ValueEntriesIndexReference) ? localDescriptorList.Elements[tableHeader7C.ValueEntriesIndexReference] : null;

                if (element == null && tableHeader7C.ValueEntriesIndexReference != 63 && !Util.IsInternalReference(tableHeader7C.ValueEntriesIndexReference))
                {
                    uint elementId = isRecipientsTable ? 1682u : 1649u;

                    element = localDescriptorList.Elements.ContainsKey(elementId) ? localDescriptorList.Elements[elementId] : null;

                    if (element != null && element.SubList != null)
                    {
                        element = element.SubList.Elements.ContainsKey(tableHeader7C.ValueEntriesIndexReference) ? element.SubList.Elements[tableHeader7C.ValueEntriesIndexReference] : null;
                    }
                }

                if (element != null)
                {
                    DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(element.DataStructureId);

                    if (dataNode != null)
                    {
                        entryValueBuffer = Util.GetBuffer(reader, dataNode);
                    }
                }
                else
                {
                    if (tableHeader7C.ValueEntriesIndexReference == 63)
                    {
                        TableIndexItem entryValueIndexItem = index.GetItem(tableHeaderB5.ValueEntriesIndexReference);

                        if (entryValueIndexItem != null && tableBuffer.Length >= entryValueIndexItem.EndOffset)
                        {
                            entryValueBuffer = new byte[entryValueIndexItem.EndOffset - entryValueIndexItem.StartOffset];
                            System.Array.Copy(tableBuffer, entryValueIndexItem.StartOffset, entryValueBuffer, 0, entryValueBuffer.Length);
                        }

                        useB5Header = true;
                    }
                    else
                    {
                        TableIndexItem entryValueIndexItem = index.GetItem(tableHeader7C.ValueEntriesIndexReference);

                        if (entryValueIndexItem != null && tableBuffer.Length >= entryValueIndexItem.EndOffset)
                        {
                            entryValueBuffer = new byte[entryValueIndexItem.EndOffset - entryValueIndexItem.StartOffset];
                            System.Array.Copy(tableBuffer, entryValueIndexItem.StartOffset, entryValueBuffer, 0, entryValueBuffer.Length);
                        }
                    }
                }
            }
            else
            {
                if (tableHeader7C.ValueEntriesIndexReference == 63)
                {
                    TableIndexItem entryValueIndexItem = index.GetItem(tableHeaderB5.ValueEntriesIndexReference);

                    if (entryValueIndexItem != null && tableBuffer.Length >= entryValueIndexItem.EndOffset)
                    {
                        entryValueBuffer = new byte[entryValueIndexItem.EndOffset - entryValueIndexItem.StartOffset];
                        System.Array.Copy(tableBuffer, entryValueIndexItem.StartOffset, entryValueBuffer, 0, entryValueBuffer.Length);
                    }

                    useB5Header = true;
                }
                else
                {
                    TableIndexItem entryValueIndexItem = index.GetItem(tableHeader7C.ValueEntriesIndexReference);

                    if (entryValueIndexItem != null && tableBuffer.Length >= entryValueIndexItem.EndOffset)
                    {
                        entryValueBuffer = new byte[entryValueIndexItem.EndOffset - entryValueIndexItem.StartOffset];
                        System.Array.Copy(tableBuffer, entryValueIndexItem.StartOffset, entryValueBuffer, 0, entryValueBuffer.Length);
                    }
                }
            }

            if (entryValueBuffer == null)
            {
                return;
            }

            int entriesArraySize = entryValueBuffer.Length / tableHeader7C.ValueArraySize;

            if (useB5Header)
            {
                entriesArraySize = entryValueBuffer.Length / (tableHeaderB5.EntryIdSize + tableHeaderB5.EntryValueSize);
            }

            EntriesArray = new TableEntryList[entriesArraySize];

            for (int m = 0; m < entriesArraySize; m++)
            {
                EntriesArray[m] = new TableEntryList();

                for (int i = 0; i < tableHeader7C.EntryDefinitions.Count; i++)
                {
                    Table7CEntryDefinition entryDefinition = tableHeader7C.EntryDefinitions[i];

                    TableEntry entry = new TableEntry(reader.PstFile.Encoding);
                    entry.PropertyTag = new PropertyTag(entryDefinition.EntryId, entryDefinition.EntryValueType);

                    int offset = m * tableHeader7C.ValueArraySize + entryDefinition.ValueArrayEntryOffset;

                    if (useB5Header)
                    {
                        offset = m * (tableHeaderB5.EntryIdSize + tableHeaderB5.EntryValueSize);
                    }

                    if (entryValueBuffer.Length < offset)
                    {
                        if (isRecipientsTable)
                        {
                            Console.Error.WriteLine("\rWarning: Bad entry Recipients Property Table..skipping entry");
                        }
                        else
                        {
                            Console.Error.WriteLine("\rWarning: Bad entry in Table 7c..skipping entry");
                        }
                    }
                    else if (entry.PropertyTag.Type == PropertyType.Short || entry.PropertyTag.Type == PropertyType.Boolean)
                    {
                        entry.ValueBuffer = new byte[2];
                        System.Array.Copy(entryValueBuffer, offset, entry.ValueBuffer, 0, 2);
                    }
                    else if (entry.PropertyTag.Type == PropertyType.Integer || entry.PropertyTag.Type == PropertyType.Float)
                    {
                        entry.ValueBuffer = new byte[4];
                        System.Array.Copy(entryValueBuffer, offset, entry.ValueBuffer, 0, 4);
                    }
                    else if (!useB5Header && (entry.PropertyTag.Type == PropertyType.Long || entry.PropertyTag.Type == PropertyType.Double || entry.PropertyTag.Type == PropertyType.Currency))
                    {
                        entry.ValueBuffer = new byte[8];
                        System.Array.Copy(entryValueBuffer, offset, entry.ValueBuffer, 0, 8);
                    }
                    else if (entry.PropertyTag.Type == PropertyType.Long || entry.PropertyTag.Type == PropertyType.Double || entry.PropertyTag.Type == PropertyType.Currency ||
                             entry.PropertyTag.Type == PropertyType.ShortArray || entry.PropertyTag.Type == PropertyType.IntegerArray || entry.PropertyTag.Type == PropertyType.FloatArray ||
                             entry.PropertyTag.Type == PropertyType.LongArray || entry.PropertyTag.Type == PropertyType.DoubleArray || entry.PropertyTag.Type == PropertyType.CurrencyArray ||
                             entry.PropertyTag.Type == PropertyType.String || entry.PropertyTag.Type == PropertyType.String8 || entry.PropertyTag.Type == PropertyType.StringArray || entry.PropertyTag.Type == PropertyType.String8Array ||
                             entry.PropertyTag.Type == PropertyType.Binary || entry.PropertyTag.Type == PropertyType.BinaryArray || entry.PropertyTag.Type == PropertyType.Object ||
                             entry.PropertyTag.Type == PropertyType.Guid || entry.PropertyTag.Type == PropertyType.GuidArray || entry.PropertyTag.Type == PropertyType.ApplicationTime || entry.PropertyTag.Type == PropertyType.SystemTime)
                    {
                        uint valueReference = 0;

                        if (useB5Header && tableHeaderB5.EntryValueSize == 2)
                        {
                            valueReference = BitConverter.ToUInt16(entryValueBuffer, offset);
                        }
                        else
                        {
                            valueReference = BitConverter.ToUInt32(entryValueBuffer, offset);
                        }

                        if (valueReference == 0)
                        {
                            continue;
                        }

                        if (Util.IsInternalReference(valueReference))
                        {
                            TableIndexItem indexItem = index.GetItem(valueReference);

                            if (indexItem != null)
                            {
                                if (indexItem.EndOffset > indexItem.StartOffset)
                                {
                                    entry.ValueBuffer = new byte[indexItem.EndOffset - indexItem.StartOffset];

                                    if (tableBuffer.Length >= indexItem.StartOffset + entry.ValueBuffer.Length)
                                    {
                                        System.Array.Copy(tableBuffer, indexItem.StartOffset, entry.ValueBuffer, 0, entry.ValueBuffer.Length);
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (localDescriptorList != null)
                            {
                                LocalDescriptorListElement element = localDescriptorList.Elements.ContainsKey(valueReference) ? localDescriptorList.Elements[valueReference] : null;

                                if (element == null)
                                {
                                    LocalDescriptorListElement recipientElement = localDescriptorList.Elements.ContainsKey((uint)1682) ? localDescriptorList.Elements[(uint)1682] : null;

                                    if (recipientElement != null && recipientElement.SubList != null)
                                    {
                                        element = recipientElement.SubList.Elements.ContainsKey(valueReference) ? recipientElement.SubList.Elements[valueReference] : null;
                                    }
                                }

                                if (element != null)
                                {
                                    DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(element.DataStructureId);

                                    if (dataNode != null)
                                    {
                                        entry.ValueBuffer = Util.GetBuffer(reader, dataNode);
                                    }
                                }
                            }
                        }
                    }

                    EntriesArray[m].Add(entry);
                }
            }

            //Try to recover recipients table if email address is null in all entries
            int emptyEmailAddressCount = 0;

            for (int k = 0; k < EntriesArray.Length; k++)
            {
                if (EntriesArray[k][MapiPropertyTag.PR_EMAIL_ADDRESS] != null && EntriesArray[k][MapiPropertyTag.PR_EMAIL_ADDRESS].ValueBuffer == null)
                {
                    emptyEmailAddressCount++;
                }
                else if (EntriesArray[k][MapiPropertyTag.PR_EMAIL_ADDRESS] == null && EntriesArray[k][MapiPropertyTag.PR_RECIPIENT_TYPE] != null)
                {
                    emptyEmailAddressCount++;
                }
            }

            if (emptyEmailAddressCount > (int)(EntriesArray.Length / 2))
            {
                TableInfo tableInfo = new TableInfo(tableHeader7CBuffer);
                IDictionary <uint, byte[]> rowTable = new Dictionary <uint, byte[]>();
                int rowLength = tableInfo.EndOffsetCellExistenceBlock;

                IList <TableRowId> rowIds = new List <TableRowId>();

                for (int i = 0; i < entryValueBuffer.Length; i += entryValueBuffer.Length / entriesArraySize)
                {
                    byte[] rowIdBuffer = new byte[entryValueBuffer.Length / entriesArraySize];

                    if (entryValueBuffer.Length >= i + rowIdBuffer.Length)
                    {
                        System.Array.Copy(entryValueBuffer, i, rowIdBuffer, 0, rowIdBuffer.Length);

                        TableRowId rowId = new TableRowId(rowIdBuffer);
                        rowIds.Add(rowId);
                    }
                }

                if (localDescriptorList != null)
                {
                    LocalDescriptorListElement element = localDescriptorList.Elements.ContainsKey((uint)0x692) ? localDescriptorList.Elements[(uint)0x692] : null;

                    if (element != null)
                    {
                        if (element.SubList == null || !element.SubList.Elements.ContainsKey((uint)63) || element.SubList.Elements[(uint)63] == null)
                        {
                            return;
                        }

                        LocalDescriptorListElement subElement = element.SubList.Elements[(uint)63];
                        DataStructure dataNode = reader.PstFile.DataIndexTree.GetDataStructure(subElement.DataStructureId);

                        if (dataNode != null)
                        {
                            byte[] rowMatrix = Util.GetBuffer(reader, dataNode);

                            int tableSize  = reader.PstFile.Is64Bit ? 8176 : 8180;
                            int tableCount = 1;

                            for (int r = 0; r <= rowMatrix.Length - rowLength; r += rowLength)
                            {
                                if (((tableSize * tableCount) - r) < rowLength)
                                {
                                    r = tableSize * tableCount++;
                                }

                                byte[] rowBuffer = new byte[rowLength];

                                System.Array.Copy(rowMatrix, r, rowBuffer, 0, rowBuffer.Length);

                                uint dwRowId = BitConverter.ToUInt32(rowBuffer, 0);

                                if (!rowTable.ContainsKey(dwRowId))
                                {
                                    rowTable.Add(dwRowId, rowBuffer);
                                }
                                else
                                {
                                    //Console.WriteLine("Warning: existing row key:" + dwRowId);
                                }
                            }

                            int cellExistenceBlockLength = tableInfo.EndOffsetCellExistenceBlock - tableInfo.EndOffset1ByteDataValue;
                            EntriesArray = new TableEntryList[rowIds.Count];

                            for (int i = 0; i < rowIds.Count; i++)
                            {
                                EntriesArray[i] = new TableEntryList();

                                byte[] rowBuffer = rowTable.ContainsKey(rowIds[i].Id) ? rowTable[rowIds[i].Id] : null;

                                if (rowBuffer != null)
                                {
                                    for (int c = 0; c < tableInfo.Columns.Count; c++)
                                    {
                                        TableColumnDescription columnDescription = tableInfo.Columns[c];

                                        byte[] cellExistenceBlock = new byte[cellExistenceBlockLength];

                                        System.Array.Copy(rowBuffer, rowBuffer.Length - cellExistenceBlockLength, cellExistenceBlock, 0, cellExistenceBlock.Length);

                                        int cellExistenceBlockValue = cellExistenceBlock[columnDescription.IBit / 8] & (1 << (7 - (columnDescription.IBit % 8)));

                                        if (cellExistenceBlockValue != 0) //true
                                        {
                                            PropertyTag propertyTag = new PropertyTag(columnDescription.Tag);
                                            TableEntry  entry       = new TableEntry(reader.PstFile.Encoding);

                                            byte[] valueBuffer = new byte[columnDescription.CountBytes];
                                            System.Array.Copy(rowBuffer, columnDescription.Offset, valueBuffer, 0, valueBuffer.Length);

                                            if (propertyTag.Type == PropertyType.Boolean)
                                            {
                                                if (valueBuffer[0] != 0) //true
                                                {
                                                    valueBuffer = BitConverter.GetBytes((short)1);
                                                }
                                                else
                                                {
                                                    valueBuffer = BitConverter.GetBytes((short)0);
                                                }
                                            }
                                            else if (propertyTag.Type == PropertyType.Long || propertyTag.Type == PropertyType.Double || propertyTag.Type == PropertyType.Currency ||
                                                     propertyTag.Type == PropertyType.ApplicationTime || propertyTag.Type == PropertyType.SystemTime || propertyTag.Type == PropertyType.Guid)
                                            {
                                                HeapId heapId = new HeapId(valueBuffer);

                                                TableIndexItem indexItem = index.Items.ContainsKey((int)heapId.Index) ? index.Items[(int)heapId.Index] : null;

                                                if (indexItem != null)
                                                {
                                                    valueBuffer = new byte[indexItem.EndOffset - indexItem.StartOffset];
                                                    System.Array.Copy(tableBuffer, indexItem.StartOffset, valueBuffer, 0, valueBuffer.Length);
                                                }
                                            }
                                            else if (propertyTag.Type == PropertyType.String || propertyTag.Type == PropertyType.String8 || propertyTag.Type == PropertyType.Binary || propertyTag.Type == PropertyType.Object ||
                                                     propertyTag.Type == PropertyType.ShortArray || propertyTag.Type == PropertyType.IntegerArray || propertyTag.Type == PropertyType.FloatArray ||
                                                     propertyTag.Type == PropertyType.LongArray || propertyTag.Type == PropertyType.DoubleArray || propertyTag.Type == PropertyType.CurrencyArray ||
                                                     propertyTag.Type == PropertyType.StringArray || propertyTag.Type == PropertyType.String8Array || propertyTag.Type == PropertyType.BinaryArray || propertyTag.Type == PropertyType.GuidArray)
                                            {
                                                HeapId heapId = new HeapId(valueBuffer);

                                                if (heapId.Index > 0 && heapId.BlockIndex == 0)
                                                {
                                                    TableIndexItem indexItem = index.Items.ContainsKey((int)heapId.Index) ? index.Items[(int)heapId.Index] : null;

                                                    if (indexItem != null)
                                                    {
                                                        valueBuffer = new byte[indexItem.EndOffset - indexItem.StartOffset];
                                                        System.Array.Copy(tableBuffer, indexItem.StartOffset, valueBuffer, 0, valueBuffer.Length);
                                                    }
                                                }
                                                else if (heapId.Index > 0 && heapId.BlockIndex > 0)
                                                {
                                                    if (index.SecondItems.Length >= heapId.BlockIndex)
                                                    {
                                                        IDictionary <int, TableIndexItem> secondIndexTable = index.SecondItems[heapId.BlockIndex - 1];

                                                        if (secondIndexTable != null)
                                                        {
                                                            TableIndexItem indexItem = secondIndexTable.ContainsKey((int)heapId.Index) ? secondIndexTable[(int)heapId.Index] : null;

                                                            if (indexItem != null)
                                                            {
                                                                valueBuffer = new byte[indexItem.EndOffset - indexItem.StartOffset];
                                                                System.Array.Copy(tableBuffer, indexItem.StartOffset, valueBuffer, 0, valueBuffer.Length);
                                                            }
                                                        }
                                                    }
                                                }
                                            }

                                            entry.PropertyTag = propertyTag;
                                            entry.ValueBuffer = valueBuffer;

                                            EntriesArray[i].Add(entry);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 12
0
 internal Table7C(PstFileReader reader, byte[] tableBuffer, LocalDescriptorList localDescriptorList, DataStructure tableDataNode, bool isRecipientsTable)
 {
     Parse(reader, tableBuffer, localDescriptorList, tableDataNode, isRecipientsTable);
 }
Exemplo n.º 13
0
        private void Parse(Stream stream, System.Text.Encoding encoding)
        {
            this.encoding = encoding;
            this.stream   = stream;
            this.reader   = new PstFileReader(this, stream);

            uint signature = reader.ReadUInt32();//offset 0

            if (signature != 0x4e444221)
            {
                Close();

                throw new FileFormatException("Invalid file format!");
            }

            uint   crc32            = reader.ReadUInt32(); //offset 4
            ushort contentType      = reader.ReadUInt16(); //offset 8
            ushort dataVersion      = reader.ReadUInt16(); //offset 10
            ushort contentVersion   = reader.ReadUInt16(); //offset 12
            byte   creationPlatform = reader.ReadByte();   //offset 14
            byte   accessPlatform   = reader.ReadByte();   //offset 15
            uint   unknown1         = reader.ReadUInt32(); //offset 16
            uint   unknown2         = reader.ReadUInt32(); //offset 20

            if (dataVersion == 0x0015 || dataVersion == 0x0017)
            {
                is64Bit = true;
            }

            if (!is64Bit)
            {
                //32-bit file
                uint unknown3 = reader.ReadUInt32();         //offset 24
                uint unknown4 = reader.ReadUInt32();         //offset 28
                uint unknown5 = reader.ReadUInt32();         //offset 32

                byte[] unknownArray1 = reader.ReadBytes(32); //offset 36
                byte[] unknownArray2 = reader.ReadBytes(32);
                byte[] unknownArray3 = reader.ReadBytes(32);
                byte[] unknownArray4 = reader.ReadBytes(32);

                uint unknown6 = reader.ReadUInt32();                      //offset 164

                size = reader.ReadInt32();                                //offset 168

                uint lastDataAllocationTableOffset = reader.ReadUInt32(); //offset 172
                uint unknown7 = reader.ReadUInt32();                      //offset 176
                uint unknown8 = reader.ReadUInt32();                      //offset 180

                descriptorIndexBackPointer = reader.ReadUInt32();
                descriptorIndex            = reader.ReadUInt32();
                dataIndexBackPointer       = reader.ReadUInt32();
                dataIndex = reader.ReadUInt32();

                uint   unknown9 = reader.ReadUInt32();                            //offset 200
                byte[] dataAllocationTableMap      = reader.ReadBytes(128);       //offset 204
                byte[] indexNodeAllocationTableMap = reader.ReadBytes(128);       //offset 332
                byte   senitinal = reader.ReadByte();                             //offset 460

                encryptionType = EnumUtil.ParseEncryptionType(reader.ReadByte()); //offset 461

                //AllocationTable dataAllocationTable = new AllocationTable(reader, 17408); //offset 0x4400
                //AllocationTable indexNodeAllocationTable = new AllocationTable(reader, 17920); //offset 0x4600
            }
            else
            {
                //64-bit file
                ulong unknown3 = reader.ReadUInt64();        //offset 24
                ulong unknown4 = reader.ReadUInt64();        //offset 32
                uint  unknown5 = reader.ReadUInt32();        //offset 40

                byte[] unknownArray1 = reader.ReadBytes(32); //offset 36
                byte[] unknownArray2 = reader.ReadBytes(32);
                byte[] unknownArray3 = reader.ReadBytes(32);
                byte[] unknownArray4 = reader.ReadBytes(32);

                uint unknown61 = reader.ReadUInt32();                             //offset 172
                uint unknown62 = reader.ReadUInt32();                             //offset 176
                uint unknown63 = reader.ReadUInt32();                             //offset 180

                size = reader.ReadInt64();                                        //offset 184

                ulong lastDataAllocationTableOffset = reader.ReadUInt64();        //offset 192
                ulong unknown7 = reader.ReadUInt64();                             //offset 200
                ulong unknown8 = reader.ReadUInt64();                             //offset 208

                descriptorIndexBackPointer = reader.ReadUInt64();                 //offset 216
                descriptorIndex            = reader.ReadUInt64();                 //offset 224
                dataIndexBackPointer       = reader.ReadUInt64();                 //offset 232
                dataIndex = reader.ReadUInt64();                                  //offset 240

                uint unknown9  = reader.ReadUInt32();                             //offset 248
                uint unknown10 = reader.ReadUInt32();                             //offset 252

                byte[] dataAllocationTableMap      = reader.ReadBytes(128);       //offset 256
                byte[] indexNodeAllocationTableMap = reader.ReadBytes(128);       //offset 384

                byte senitinal = reader.ReadByte();                               //offset 512

                encryptionType = EnumUtil.ParseEncryptionType(reader.ReadByte()); //offset 513
            }

            descriptorIndexTree = new IndexTree(reader, descriptorIndex);
            descriptorIndexTree.SetParent(); //set parent folder

            dataIndexTree = new IndexTree(reader, dataIndex);

            ulong nameToIdMapId  = 97;
            ulong messageStoreId = 33;
            ulong rootId         = 290;
            ulong mailboxRootId  = 32802; //32802 or 32834

            Table nameToIdMapTable  = null;
            Table messageStoreTable = null;
            Table rootTable         = null;
            Table mailboxRootTable  = null;

            ItemDescriptor nameToIdMapItemDescriptor  = descriptorIndexTree.Nodes.ContainsKey(nameToIdMapId) ? (ItemDescriptor)descriptorIndexTree.Nodes[nameToIdMapId] : null;
            ItemDescriptor messageStoreItemDescriptor = descriptorIndexTree.Nodes.ContainsKey(messageStoreId) ? (ItemDescriptor)descriptorIndexTree.Nodes[messageStoreId] : null;
            ItemDescriptor rootItemDescriptor         = descriptorIndexTree.Nodes.ContainsKey(rootId) ? (ItemDescriptor)descriptorIndexTree.Nodes[rootId] : null;
            ItemDescriptor mailboxRootItemDescriptor  = descriptorIndexTree.Nodes.ContainsKey(mailboxRootId) ? (ItemDescriptor)descriptorIndexTree.Nodes[mailboxRootId] : null;

            if (mailboxRootItemDescriptor == null)
            {
                mailboxRootItemDescriptor = descriptorIndexTree.Nodes.ContainsKey((ulong)32834) ? (ItemDescriptor)descriptorIndexTree.Nodes[(ulong)32834] : null;
            }

            if (nameToIdMapItemDescriptor == null)
            {
                throw new DataStructureException("Unresolvable Data Structure issue with: nameToIdMapItemDescriptor");
            }

            DataStructure nameToIdMapLocalDescriptorListNode = Util.GetLocalDescriptionListNode(reader.PstFile.DataIndexTree, nameToIdMapItemDescriptor.LocalDescriptorListId);
            DataStructure nameToIdMapDataNode = reader.PstFile.DataIndexTree.GetDataStructure(nameToIdMapItemDescriptor.TableId);

            if (nameToIdMapDataNode != null)
            {
                LocalDescriptorList nameToIdMapLocalDescriptorList = Util.GetLocalDescriptorList(reader, nameToIdMapLocalDescriptorListNode);
                nameToIdMapTable = Util.GetTable(reader, nameToIdMapDataNode, nameToIdMapLocalDescriptorList);
            }

            if (messageStoreItemDescriptor == null)
            {
                throw new DataStructureException("Unresolvable Data Structure issue with: messageStoreItemDescriptor");
            }

            DataStructure messageStoreLocalDescriptorListNode = Util.GetLocalDescriptionListNode(reader.PstFile.DataIndexTree, messageStoreItemDescriptor.LocalDescriptorListId);
            DataStructure messageStoreDataNode = reader.PstFile.DataIndexTree.GetDataStructure(messageStoreItemDescriptor.TableId);

            if (messageStoreDataNode != null)
            {
                LocalDescriptorList messageStoreLocalDescriptorList = Util.GetLocalDescriptorList(reader, messageStoreLocalDescriptorListNode);
                messageStoreTable = Util.GetTable(reader, messageStoreDataNode, messageStoreLocalDescriptorList);
            }

            if (rootItemDescriptor == null)
            {
                throw new DataStructureException("Unresolvable Data Structure issue with: rootItemDescriptor");
            }

            DataStructure rootLocalDescriptorListNode = Util.GetLocalDescriptionListNode(reader.PstFile.DataIndexTree, rootItemDescriptor.LocalDescriptorListId);
            DataStructure rootDataNode = reader.PstFile.DataIndexTree.GetDataStructure(rootItemDescriptor.TableId);

            if (rootDataNode != null)
            {
                LocalDescriptorList rootLocalDescriptorList = Util.GetLocalDescriptorList(reader, rootLocalDescriptorListNode);
                rootTable = Util.GetTable(reader, rootDataNode, rootLocalDescriptorList);
            }

            if (mailboxRootItemDescriptor != null)
            {
                DataStructure mailboxRootLocalDescriptorListNode = Util.GetLocalDescriptionListNode(reader.PstFile.DataIndexTree, mailboxRootItemDescriptor.LocalDescriptorListId);
                DataStructure mailboxRootDataNode = reader.PstFile.DataIndexTree.GetDataStructure(mailboxRootItemDescriptor.TableId);

                if (mailboxRootDataNode != null)
                {
                    LocalDescriptorList mailboxRootLocalDescriptorList = Util.GetLocalDescriptorList(reader, mailboxRootLocalDescriptorListNode);
                    mailboxRootTable = Util.GetTable(reader, mailboxRootDataNode, mailboxRootLocalDescriptorList);
                }
            }

            if (nameToIdMapTable != null)
            {
                nameToIdMap = new NameToIdMap(nameToIdMapTable);

                FillNamedIdToTag();
            }

            if (messageStoreTable != null)
            {
                messageStore = new MessageStore(messageStoreTable);
            }

            if (rootTable != null)
            {
                root = new Folder(reader, rootItemDescriptor, rootTable);
            }

            if (mailboxRootItemDescriptor != null && mailboxRootTable != null)
            {
                mailboxRoot = new Folder(reader, mailboxRootItemDescriptor, mailboxRootTable);
            }
        }