Example #1
0
        /// <summary>
        /// Reads the metadata from a message file.
        /// </summary>
        /// <param name="msgID">The message ID.</param>
        /// <param name="path">Fully qualified path to the message file.</param>
        /// <returns>The <see cref="QueuedMsgInfo" />.</returns>
        internal QueuedMsgInfo ReadMessageMetadata(Guid msgID, string path)
        {
            QueuedMsgInfo msgInfo;
            int           cbBody;

            byte[] md5Hash;
            long   savePos;

            using (var fsMsg = new EnhancedFileStream(path, FileMode.Open, FileAccess.ReadWrite))
            {
                try
                {
                    // Read the message file header

                    if (fsMsg.ReadInt32() != MsgMagic)      // Magic Number
                    {
                        throw new Exception();
                    }

                    if (fsMsg.ReadInt32() != 0)             // Format Version
                    {
                        throw new Exception();
                    }

                    fsMsg.ReadInt32();                      // Reserved

                    // Verify that the MD5 hash saved in then file matches the
                    // hash computed for the remainder of the file as it exists
                    // right now.

                    md5Hash = fsMsg.ReadBytes(MD5Hasher.DigestSize);
                    savePos = fsMsg.Position;

                    if (!Helper.ArrayEquals(md5Hash, MD5Hasher.Compute(fsMsg, fsMsg.Length - fsMsg.Position)))
                    {
                        throw new FormatException(string.Format("Message file [{0}] is corrupt. MD5 digests do not match.", path));
                    }

                    fsMsg.Position = savePos;

                    // Skip over the message body data

                    cbBody         = fsMsg.ReadInt32();
                    fsMsg.Position = fsMsg.Position + cbBody;

                    // Read the metadata and add the provider specific information

                    msgInfo              = new QueuedMsgInfo(fsMsg.ReadString16());
                    msgInfo.PersistID    = msgInfo.ID;
                    msgInfo.ProviderData = path;

                    return(msgInfo);
                }
                catch
                {
                    throw new FormatException(string.Format("Bad message file [{0}].", path));
                }
            }
        }
Example #2
0
        private OperationLogMode mode;                          // The current mode

        /// <summary>
        /// Opens or creates a file operation log file.
        /// </summary>
        /// <param name="path">The path to the log file.</param>
        /// <param name="transactionID">The log's transaction <see cref="Guid" />.</param>
        /// <remarks>
        /// New logs will be created in <see cref="OperationLogMode.Undo" /> mode.
        /// </remarks>
        public FileOperationLog(string path, Guid transactionID)
        {
            this.path = Path.GetFullPath(path);
            this.file = new EnhancedFileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite);

            if (file.Length == 0)
            {
                // Initialize a new file

                file.WriteInt32(Magic);
                file.WriteInt32(0);
                file.WriteInt32(0);
                file.WriteInt32((int)OperationLogMode.Undo);
                file.WriteBytesNoLen(transactionID.ToByteArray());
                file.Flush();
            }
            else
            {
                // Open an existing file.

                try
                {
                    if (file.ReadInt32() != Magic || // Magic number
                        file.ReadInt32() != 0)
                    {                                // Format Versopn
                        throw new Exception();
                    }

                    file.ReadInt32();                   // Reserved

                    switch (file.ReadInt32())           // Mode
                    {
                    case (int)OperationLogMode.Undo:

                        mode = OperationLogMode.Undo;
                        break;

                    case (int)OperationLogMode.Redo:

                        mode = OperationLogMode.Redo;
                        break;

                    default:

                        throw new Exception();
                    }

                    this.transactionID = new Guid(file.ReadBytes(16));
                    if (transactionID != this.transactionID)
                    {
                        throw new Exception();
                    }
                }
                catch
                {
                    throw new TransactionException(CorruptMsg);
                }
            }
        }
Example #3
0
        //---------------------------------------------------------------------
        // Static members

        /// <summary>
        /// Verifies that a log file is not corrupt.
        /// </summary>
        /// <param name="path">The path to the log file.</param>
        /// <param name="transactionID">Returns as the file's transaction <see cref="Guid" />.</param>
        /// <returns><c>true</c> if the log file is valid, <c>false</c> if it is corrupt.</returns>
        public static bool Validate(string path, out Guid transactionID)
        {
            int cb;

            try
            {
                using (var file = new EnhancedFileStream(path, FileMode.Open, FileAccess.ReadWrite))
                {
                    if (file.ReadInt32() != Magic || // Magic number
                        file.ReadInt32() != 0)
                    {                                // Format Versopn
                        throw new Exception();
                    }

                    switch (file.ReadInt32())           // Mode
                    {
                    case (int)OperationLogMode.Undo:
                    case (int)OperationLogMode.Redo:

                        break;

                    default:

                        throw new Exception();
                    }

                    file.ReadInt32();                   // Reserved
                    transactionID = new Guid(file.ReadBytes(16));

                    while (!file.Eof)
                    {
                        if (file.ReadInt32() != Magic)
                        {
                            throw new Exception();
                        }

                        cb = file.ReadInt32();
                        if (cb < 0 || cb + file.Position > file.Length)
                        {
                            throw new Exception();
                        }

                        file.Position += cb;
                    }

                    return(true);
                }
            }
            catch
            {
                transactionID = Guid.Empty;
                return(false);
            }
        }