/// <summary> /// Writes a message file. /// </summary> /// <param name="path">The file path.</param> /// <param name="msg">The message.</param> /// <param name="msgInfo">The message metadata.</param> internal void WriteMessage(string path, QueuedMsg msg, QueuedMsgInfo msgInfo) { byte[] md5Hash; using (var fsMsg = new EnhancedFileStream(path, FileMode.Create, FileAccess.ReadWrite)) { // Write the file header fsMsg.WriteInt32(MsgMagic); // Magic Number fsMsg.WriteInt32(0); // Format Version fsMsg.WriteInt32(0); // Reserved fsMsg.WriteBytesNoLen(md5Zeros); // MD5 hash placeholder // Write the message body. fsMsg.WriteBytes32(msg.BodyRaw); // Write the metadata. fsMsg.WriteString16(msgInfo.ToString()); // Compute and save the MD5 hash fsMsg.Position = MsgHeaderSize; md5Hash = MD5Hasher.Compute(fsMsg, fsMsg.Length - fsMsg.Position); fsMsg.Position = MsgMD5Offset; fsMsg.WriteBytesNoLen(md5Hash); } }
/// <summary> /// Updates a message file's metadata. /// </summary> /// <param name="path">The file path.</param> /// <param name="msgInfo">The message metadata.</param> internal void WriteMessageMetadata(string path, QueuedMsgInfo msgInfo) { using (var fsMsg = new EnhancedFileStream(path, FileMode.Open, FileAccess.ReadWrite)) { // Seek past the message's header and body. int cbBody; byte[] md5Hash; fsMsg.Position = MsgHeaderSize; cbBody = fsMsg.ReadInt32(); fsMsg.Position = fsMsg.Position + cbBody; // Write the metadata and truncate the file. fsMsg.WriteString16(msgInfo.ToString()); fsMsg.SetLength(fsMsg.Position); // Regenerate the MD5 Hash fsMsg.Position = MsgMD5Offset + MD5Hasher.DigestSize; md5Hash = MD5Hasher.Compute(fsMsg, fsMsg.Length - fsMsg.Position); fsMsg.Position = MsgMD5Offset; fsMsg.WriteBytesNoLen(md5Hash); } }
private void WriteFile(string path, byte[] data) { var es = new EnhancedFileStream(path, FileMode.Create); es.WriteBytesNoLen(data); es.Close(); }
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); } } }