public static string GetMessageClass(FolderItemTypeName folderItemType)
        {
            switch (folderItemType)
            {
            case FolderItemTypeName.Appointment:
                return("IPM.Appointment");

            case FolderItemTypeName.Contact:
                return("IPM.Contact");

            case FolderItemTypeName.Journal:
                return("IPM.Journal");

            case FolderItemTypeName.Note:
                return("IPM.Note");

            case FolderItemTypeName.StickyNote:
                return("IPM.StickyNote");

            case FolderItemTypeName.Task:
                return("IPM.Task");

            default:
                return(null);
            }
        }
        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);
        }
示例#3
0
        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");
            }
        }
示例#4
0
        /// <summary>
        /// Changes will be saved immediately
        /// </summary>
        public PSTFolder CreateChildFolder(string folderName, FolderItemTypeName folderItemType)
        {
            PSTFolder       childFolder = CreateNewFolder(this.File, folderName, folderItemType, this.NodeID);
            PropertyContext pc          = this.PC;

            if (!pc.GetBooleanProperty(PropertyID.PidTagSubfolders).Value)
            {
                pc.SetBooleanProperty(PropertyID.PidTagSubfolders, true);
                pc.SaveChanges(NodeID);
            }
            // update hierarchy table of parent (set PidTagSubfolders of current folder to true):
            TableContext parentHierarchyTable = ParentFolder.GetHierarchyTable();
            int          rowIndexOfFolder     = parentHierarchyTable.GetRowIndex(NodeID.Value);

            if (!parentHierarchyTable.GetBooleanProperty(rowIndexOfFolder, PropertyID.PidTagSubfolders).Value)
            {
                parentHierarchyTable.SetBooleanProperty(rowIndexOfFolder, PropertyID.PidTagSubfolders, true);
                parentHierarchyTable.SaveChanges(ParentFolder.GetHierarchyTableNodeID());
            }

            // update hierarchy table:
            TableContext hierarchyTable = GetHierarchyTable();

            hierarchyTable.AddRow(childFolder.NodeID.Value);
            int rowIndex = hierarchyTable.RowCount - 1;

            // Template properties (assured to be present)
            hierarchyTable.SetInt32Property(rowIndex, PropertyID.PidTagContentCount, 0);
            hierarchyTable.SetInt32Property(rowIndex, PropertyID.PidTagContentUnreadCount, 0);
            hierarchyTable.SetBooleanProperty(rowIndex, PropertyID.PidTagSubfolders, false);
            hierarchyTable.SetStringProperty(rowIndex, PropertyID.PidTagDisplayName, folderName);
            hierarchyTable.SetStringProperty(rowIndex, PropertyID.PidTagContainerClass, GetContainerClass(folderItemType));
            hierarchyTable.SetInt32Property(rowIndex, PropertyID.PidTagLtpRowId, (int)childFolder.NodeID.Value);
            // PidTagLtpRowVer uses dwUnique
            int rowVersion = (int)File.Header.AllocateNextUniqueID();

            hierarchyTable.SetInt32Property(rowIndex, PropertyID.PidTagLtpRowVer, rowVersion);

            hierarchyTable.SaveChanges(GetHierarchyTableNodeID());

            this.File.SearchManagementQueue.AddFolder(childFolder.NodeID, this.NodeID);

            return(childFolder);
        }
示例#5
0
        /// <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);
        }
 public static MessageObject CreateNewMessage(PSTFile file, FolderItemTypeName folderItemType, NodeID parentNodeID)
 {
     return(CreateNewMessage(file, folderItemType, parentNodeID, Guid.NewGuid()));
 }