using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CDPShared { public class YellowFile { private string _filePath; public string FileId { get; set; } // this is actually the FMAP Id internally public string CloudId { get; set; } // this isn't being used yet. Gene 2021.11.17 public string CircleId { get; set; } public string TopicId { get; set; } public string DecryptionId { get; set; } public string OwnerId { get; set; } // this is a device Id public Int32 RevisionNo { get; set; } public Int32 EncryptionMethod { get; set; } public UInt64 EncryptedBlockSize { get; set; } public DateTime FileAccessTime { get; set; } // I'm not sure when this gets 'set' or what it should be. but make it UTC public DateTime FileModificationTime { get; set; } // this should be when the file header was built in UTC public DateTime FileStatusTime { get; set; } // not sure on this one either. public string Comment; public YellowFile(string filePath) { _filePath = filePath; using (FileStream fsIn = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { ReadHeader(fsIn); } } protected void ReadHeader(FileStream fs) { BinaryReader br = new BinaryReader(fs); var versionBytes = br.ReadBytes(8); // should be 'Circle1' UInt64 encyptedDataPos = br.ReadUInt64(); FileId = new Guid(br.ReadBytes(16)).ToString(); CloudId = new Guid(br.ReadBytes(16)).ToString(); CircleId = new Guid(br.ReadBytes(16)).ToString(); TopicId = new Guid(br.ReadBytes(16)).ToString(); DecryptionId = new Guid(br.ReadBytes(16)).ToString(); OwnerId = new Guid(br.ReadBytes(16)).ToString(); // the file format has IV being 32 byte, but we only need 16 br.ReadBytes(16); // skip over IV br.ReadBytes(16); // skip over the extra 16 bytes RevisionNo = br.ReadInt32(); EncryptionMethod = br.ReadInt32(); EncryptedBlockSize = br.ReadUInt64(); FileAccessTime = DateTime.FromBinary(br.ReadInt64()); FileModificationTime = DateTime.FromBinary(br.ReadInt64()); FileStatusTime = DateTime.FromBinary(br.ReadInt64()); Comment = Encoding.Unicode.GetString(br.ReadBytes(256)).Trim('\0'); br.ReadBytes(40); // reserved byte[] hash = br.ReadBytes(32); Debug.Assert(fs.Position == 512); } public void UpdateOwner(string ownerId) { Guid owner = Guid.Parse(ownerId); using (FileStream fs = new FileStream(_filePath, FileMode.Open)) { fs.Position = 96; byte[] guidBytes = owner.ToByteArray(); fs.Write(guidBytes, 0, guidBytes.Length); } } } }