private Guid GetPropertySetGuid(int indexHint) { if (indexHint == 0) { return(Guid.Empty); } else if (indexHint == 1) { return(PropertySetGuid.PS_MAPI); } else if (indexHint == 2) { return(PropertySetGuid.PS_PUBLIC_STRINGS); } else { int propertySetGuidIndex = indexHint - 3; if (PropertySetGuidStreamCache == null) { PSTNode node = m_file.GetNode((uint)InternalNodeName.NID_NAME_TO_ID_MAP); PropertySetGuidStreamCache = node.PC.GetBytesProperty(PropertyID.PidTagNameidStreamGuid); } int offset = propertySetGuidIndex * 16; Guid guid = LittleEndianConverter.ToGuid(PropertySetGuidStreamCache, offset); return(guid); } }
public static PSTFolder GetFolder(PSTNode node) { if (node.NodeID.nidType == NodeTypeName.NID_TYPE_NORMAL_FOLDER) { PropertyContext pc = node.PC; if (pc != null) { string containerClass = pc.GetStringProperty(PropertyID.PidTagContainerClass); FolderItemTypeName itemType = GetItemType(containerClass); switch (itemType) { case FolderItemTypeName.Appointment: return(new CalendarFolder(node)); case FolderItemTypeName.Note: return(new MailFolder(node)); default: return(new PSTFolder(node)); } } else { throw new Exception("PC is null"); } } else { throw new Exception("Node ID does not belong to a folder"); } }
/// <returns>short PropertyID used to store the property</returns> public PropertyID AddToMap(PropertyLongID propertyLongID, Guid propertySetGuid) { PSTNode node = m_file.GetNode((uint)InternalNodeName.NID_NAME_TO_ID_MAP); int wGuid = GetPropertySetGuidIndexHint(propertySetGuid); if (wGuid == -1) { wGuid = 3 + AddPropertySetGuid(node, propertySetGuid); } byte[] oldBuffer = node.PC.GetBytesProperty(PropertyID.PidTagNameidStreamEntry); int propertyIndex = oldBuffer.Length / 8; NameID nameID = new NameID(propertyLongID, (ushort)wGuid, (ushort)propertyIndex); byte[] newBuffer = new byte[oldBuffer.Length + 8]; Array.Copy(oldBuffer, newBuffer, oldBuffer.Length); nameID.WriteBytes(newBuffer, oldBuffer.Length); node.PC.SetBytesProperty(PropertyID.PidTagNameidStreamEntry, newBuffer); AddPropertyToHashBucket(node, nameID); node.SaveChanges(); PropertyID propertyID = (PropertyID)(nameID.PropertyShortID); m_map.Add(new PropertyName(propertyLongID, propertySetGuid), (ushort)propertyID); return(propertyID); }
public static MessageObject CreateNewMessage(PSTFile file, FolderItemTypeName folderItemType, NodeID parentNodeID, Guid searchKey) { // [MS-PST] The following properties must be present in any valid Message object PC: PropertyContext pc = PropertyContext.CreateNewPropertyContext(file); pc.SetStringProperty(PropertyID.PidTagMessageClass, GetMessageClass(folderItemType)); pc.SetInt32Property(PropertyID.PidTagMessageFlags, 0); pc.SetInt32Property(PropertyID.PidTagMessageStatus, 0); pc.SetDateTimeProperty(PropertyID.PidTagCreationTime, DateTime.UtcNow); pc.SetDateTimeProperty(PropertyID.PidTagLastModificationTime, DateTime.UtcNow); pc.SetDateTimeProperty(PropertyID.PidTagClientSubmitTime, DateTime.UtcNow); pc.SetDateTimeProperty(PropertyID.PidTagMessageDeliveryTime, DateTime.UtcNow); byte[] conversationIndex = ConversationIndexHeader.GenerateNewConversationIndex().GetBytes(); pc.SetBytesProperty(PropertyID.PidTagConversationIndex, conversationIndex); // PidTagSearchKey is apparently a GUID pc.SetBytesProperty(PropertyID.PidTagSearchKey, LittleEndianConverter.GetBytes(searchKey)); pc.SaveChanges(); NodeID pcNodeID = file.Header.AllocateNextNodeID(NodeTypeName.NID_TYPE_NORMAL_MESSAGE); file.NodeBTree.InsertNodeEntry(pcNodeID, pc.DataTree, pc.SubnodeBTree, parentNodeID); // NOTE: According to [MS-PST], A Recipient Table MUST exist for any Message object, // However, in practice even outlook itself does not always create it. PSTNode pcNode = new PSTNode(file, pcNodeID, pc.DataTree, pc.SubnodeBTree); MessageObject message = new MessageObject(pcNode); return(message); }
public bool ContainsNode(NodeID nodeID) { if (m_data == null) { PSTNode node = m_file.GetNode((uint)InternalNodeName.NID_SEARCH_DOMAIN_OBJECT); if (node.DataTree == null) { m_data = new byte[0]; } else { m_data = node.DataTree.GetData(); } } int nodeCount = m_data.Length / 4; for (int index = 0; index < nodeCount; index++) { uint currentNodeID = LittleEndianConverter.ToUInt32(m_data, index * 4); if (currentNodeID == nodeID.Value) { return(true); } } return(false); }
public NamedTableContext GetContentsTable() { if (m_contentsTable == null) { PSTNode node = GetContentsTableNode(); m_contentsTable = node.NamedTableContext; } return(m_contentsTable); }
public RecurringAppointment(PSTNode node) : base(node) { this.Recurring = true; byte[] bytes = PC.GetBytesProperty(PropertyNames.PidLidAppointmentRecur); if (bytes != null) { ReadRecurrencePattern(bytes); } }
public void CreateAttachmentTableIfNotExist() { CreateSubnodeBTreeIfNotExist(); Subnode subnode = SubnodeBTree.GetSubnode((uint)InternalNodeName.NID_ATTACHMENT_TABLE); if (subnode == null) { PSTNode template = this.File.GetNode(InternalNodeName.NID_ATTACHMENT_TABLE); NodeID nodeID = new NodeID((uint)InternalNodeName.NID_ATTACHMENT_TABLE); SubnodeBTree.InsertSubnodeEntry(nodeID, template.DataTree, null); File.BlockBTree.IncrementBlockEntryReferenceCount(template.DataTree.RootBlock.BlockID); } }
public static Note GetNote(PSTFile file, NodeID nodeID) { PSTNode node = file.GetNode(nodeID); NamedPropertyContext pc = node.PC; if (pc != null) { return(new Note(node)); } else { return(null); } }
// http://social.msdn.microsoft.com/Forums/en-US/os_binaryfile/thread/a5f9c653-40f5-4638-85d3-00c54607d984/ // For the following types, search the SDO for the NIDs of the old and new parent folders. // If either of the NIDs is contained in the SDO, enqueue the SUD private void QueueSearchUpdateDescriptor(SearchUpdateDescriptor sud) { if (m_node == null) { m_node = m_file.GetNode((uint)InternalNodeName.NID_SEARCH_MANAGEMENT_QUEUE); } if (m_node.DataTree == null) { m_node.DataTree = new DataTree(m_file); } m_node.DataTree.AppendData(sud.GetBytes()); }
public void CreateRecipientsTableIfNotExist() { CreateSubnodeBTreeIfNotExist(); Subnode subnode = SubnodeBTree.GetSubnode((uint)InternalNodeName.NID_RECIPIENT_TABLE); if (subnode == null) { PSTNode template = this.File.GetNode(InternalNodeName.NID_RECIPIENT_TABLE); NodeID nodeID = new NodeID((uint)InternalNodeName.NID_RECIPIENT_TABLE); SubnodeBTree.InsertSubnodeEntry(nodeID, template.DataTree, null); File.BlockBTree.IncrementBlockEntryReferenceCount(template.DataTree.RootBlock.BlockID); this.RecipientsTable.AddPropertyColumnIfNotExist(PropertyID.PidTagRecipientDisplayName, PropertyTypeName.PtypString); this.RecipientsTable.AddPropertyColumnIfNotExist(PropertyID.PidTagRecipientEntryId, PropertyTypeName.PtypBinary); this.RecipientsTable.AddPropertyColumnIfNotExist(PropertyID.PidTagRecipientFlags, PropertyTypeName.PtypInteger32); this.RecipientsTable.AddPropertyColumnIfNotExist(PropertyID.PidTagRecipientTrackStatus, PropertyTypeName.PtypInteger32); } }
public static PSTFolder GetFolder(PSTFile file, NodeID nodeID) { if (nodeID.nidType == NodeTypeName.NID_TYPE_NORMAL_FOLDER) { PSTNode node = file.GetNode(nodeID); if (node != null) { return(GetFolder(node)); } else { return(null); } } else { throw new Exception("Node ID does not belong to a folder"); } }
/// <summary> /// Caller must update its hierarchy table to include the new child /// </summary> public static PSTFolder CreateNewFolder(PSTFile file, string folderName, FolderItemTypeName folderItemType, NodeID parentNodeID) { // create the normal folder node PropertyContext pc = PropertyContext.CreateNewPropertyContext(file); pc.SetStringProperty(PropertyID.PidTagDisplayName, folderName); pc.SetInt32Property(PropertyID.PidTagContentCount, 0); pc.SetInt32Property(PropertyID.PidTagContentUnreadCount, 0); pc.SetBooleanProperty(PropertyID.PidTagSubfolders, false); pc.SetStringProperty(PropertyID.PidTagContainerClass, GetContainerClass(folderItemType)); pc.SaveChanges(); NodeID pcNodeID = file.Header.AllocateNextFolderNodeID(); file.NodeBTree.InsertNodeEntry(pcNodeID, pc.DataTree, pc.SubnodeBTree, parentNodeID); PSTNode pcNode = new PSTNode(file, pcNodeID, pc.DataTree, pc.SubnodeBTree); // There is no need to create a new empty TC, we can simply point to the appropriate template // and only update the reference to another data tree during modification PSTNode hierarchyTableTemplateNode = file.GetNode(InternalNodeName.NID_HIERARCHY_TABLE_TEMPLATE); NodeID hierarchyTableNodeID = new NodeID(NodeTypeName.NID_TYPE_HIERARCHY_TABLE, pcNodeID.nidIndex); file.NodeBTree.InsertNodeEntry(hierarchyTableNodeID, hierarchyTableTemplateNode.DataTree, null, new NodeID(0)); file.BlockBTree.IncrementBlockEntryReferenceCount(hierarchyTableTemplateNode.DataTree.RootBlock.BlockID); PSTNode contentsTableTemplateNode = file.GetNode(InternalNodeName.NID_CONTENTS_TABLE_TEMPLATE); NodeID contentsTableNodeID = new NodeID(NodeTypeName.NID_TYPE_CONTENTS_TABLE, pcNodeID.nidIndex); file.NodeBTree.InsertNodeEntry(contentsTableNodeID, contentsTableTemplateNode.DataTree, null, new NodeID(0)); file.BlockBTree.IncrementBlockEntryReferenceCount(contentsTableTemplateNode.DataTree.RootBlock.BlockID); PSTNode associatedContentsTableTemplateNode = file.GetNode(InternalNodeName.NID_ASSOC_CONTENTS_TABLE_TEMPLATE); NodeID associatedContentsTableNodeID = new NodeID(NodeTypeName.NID_TYPE_ASSOC_CONTENTS_TABLE, pcNodeID.nidIndex); file.NodeBTree.InsertNodeEntry(associatedContentsTableNodeID, associatedContentsTableTemplateNode.DataTree, null, new NodeID(0)); file.BlockBTree.IncrementBlockEntryReferenceCount(associatedContentsTableTemplateNode.DataTree.RootBlock.BlockID); PSTFolder folder = PSTFolder.GetFolder(pcNode); return(folder); }
private int GetPropertySetGuidIndex(Guid propertySetGuid) { PSTNode node = m_file.GetNode((uint)InternalNodeName.NID_NAME_TO_ID_MAP); byte[] buffer = node.PC.GetBytesProperty(PropertyID.PidTagNameidStreamGuid); if (buffer.Length % 16 > 0) { throw new InvalidPropertyException("Invalid NameidStreamGuid"); } for (int index = 0; index < buffer.Length; index += 16) { Guid guid = LittleEndianConverter.ToGuid(buffer, index); if (guid == propertySetGuid) { return(index / 16); } } return(-1); }
public static Appointment GetAppointment(PSTFile file, NodeID nodeID) { PSTNode node = file.GetNode(nodeID); NamedPropertyContext pc = node.PC; if (pc != null) { bool recurring = pc.GetBooleanProperty(PropertyNames.PidLidRecurring, false); if (recurring) { return(new RecurringAppointment(node)); } else { return(new SingleAppointment(node)); } } else { return(null); } }
public void FillMap() { m_map = new Dictionary <PropertyName, ushort>(); PSTNode node = m_file.GetNode((uint)InternalNodeName.NID_NAME_TO_ID_MAP); byte[] buffer = node.PC.GetBytesProperty(PropertyID.PidTagNameidStreamEntry); if (buffer.Length % 8 > 0) { throw new InvalidPropertyException("Invalid NameidStreamEntry"); } for (int index = 0; index < buffer.Length; index += 8) { NameID nameID = new NameID(buffer, index); if (!nameID.IsStringIdentifier) { ushort propertyShortID = nameID.PropertyShortID; PropertyLongID propertyLongID = (PropertyLongID)nameID.dwPropertyID; Guid propertySetGuid = GetPropertySetGuid(nameID.wGuid); m_map.Add(new PropertyName(propertyLongID, propertySetGuid), propertyShortID); } } }
public PSTNode(PSTNode node) : base(node.File, node.DataTree, node.SubnodeBTree) { m_nodeID = node.NodeID; }
public static TableContext GetAssociatedContentsTableTemplate(PSTFile file) { PSTNode node = file.GetNode(InternalNodeName.NID_ASSOC_CONTENTS_TABLE_TEMPLATE); return(node.TableContext); }
public SingleAppointment(PSTNode node) : base(node) { this.Recurring = false; //this.IsRecurring = false; }
public PSTNode GetNode(NodeID nodeID) { PSTNode node = PSTNode.GetPSTNode(this, nodeID); return(node); }
public static TableContext GetHierarchyTableTemplate(PSTFile file) { PSTNode node = file.GetNode(InternalNodeName.NID_HIERARCHY_TABLE_TEMPLATE); return(node.TableContext); }
public MailFolder(PSTNode node) : base(node) { }
protected Note(PSTNode node) : base(node) { }
protected Appointment(PSTNode node) : base(node) { }
public TableContext GetAssociatedContentsTable() { PSTNode node = GetAssociatedContentsTableNode(); return(node.TableContext); }
private NamedTableContext m_contentsTable; // We use it for buffering purposes public PSTFolder(PSTNode node) : base(node) { }
public static MessageObject GetMessage(PSTFile file, NodeID nodeID) { PSTNode node = file.GetNode(nodeID); return(new MessageObject(node)); }
public TableContext GetHierarchyTable() { PSTNode node = GetHierarchyTableNode(); return(node.TableContext); }
private RecipientsTable m_recipientsTable; // for buffering purposes public MessageObject(PSTNode node) : base(node) { }
public CalendarFolder(PSTNode node) : base(node) { }