private FileBaseCluster CreateCluster(int logicalClusterNumber) { // Make sure the requested cluster exists if (logicalClusterNumber < 0 || logicalClusterNumber >= _clusterAddresses.Count) { throw new ArgumentOutOfRangeException(); } int clusterAddress = _clusterAddresses[logicalClusterNumber]; FileBaseCluster fileCluster; if (logicalClusterNumber == 0) { FileHeaderCluster fileHeaderCluster = new FileHeaderCluster(clusterAddress); fileHeaderCluster.Initialize(); fileHeaderCluster.ParentID = _file.ParentID; fileHeaderCluster.Name = _file.Name; fileCluster = fileHeaderCluster; } else { fileCluster = new FileDataCluster(clusterAddress); fileCluster.Initialize(); } fileCluster.FileID = _file.ID; fileCluster.NextClusterAddress = _fileSystem.GetNextClusterAddress(clusterAddress); fileCluster.BytesUsed = _fileSystem.GetBytesUsed(clusterAddress); _logicalClusterNumber = logicalClusterNumber; return(fileCluster); }
public void FileDataSaveLoadTest() { ConfigurationTest.Initialize(); using (var io = ConfigurationTest.CreateMemoryIO()) { SimpleClusterIO cio = new SimpleClusterIO(io); Random r = new Random(Seed); FileDataCluster csc = new FileDataCluster(Address); csc.Initialize(); int fileID = r.Next(); int nextClusterAddress = r.Next(); int bytesUsed = r.Next(); DateTime writeTime = new DateTime(2005, 1, 1); // File System Cluster fields csc.FileID = fileID; csc.NextClusterAddress = nextClusterAddress; csc.BytesUsed = bytesUsed; csc.WriteTime = writeTime; byte[] data = new byte[FileDataCluster.DataSize]; for (int i = 0; i < data.Length; i++) { data[i] = (byte)(r.Next() & byte.MaxValue); } csc.Data.Set(0, data); cio.Save(csc); int offset = 0; DataBlock b = new DataBlock( io.Bytes, Address * Configuration.Geometry.BytesPerCluster, Configuration.Geometry.BytesPerCluster); byte[] marker = b.ToByteArray(offset, Constants.SrfsMarker.Length); Assert.IsTrue(marker.SequenceEqual(Constants.SrfsMarker)); offset += marker.Length; byte[] version = b.ToByteArray(offset, Constants.CurrentVersion.Length); Assert.IsTrue(version.SequenceEqual(Constants.CurrentVersion)); offset += version.Length; Guid guid = new Guid(b.ToByteArray(offset, Constants.GuidLength)); Assert.AreEqual(guid, Configuration.FileSystemID); offset += Constants.GuidLength; byte[] signatureBytes = b.ToByteArray(offset, Signature.Length); offset += Signature.Length; byte[] thumbprintBytes = b.ToByteArray(offset, KeyThumbprint.Length); Assert.IsTrue(thumbprintBytes.SequenceEqual(Configuration.CryptoSettings.SigningKeyThumbprint.Bytes)); offset += KeyThumbprint.Length; byte[] hashBytes = b.ToByteArray(offset, 32); offset += 32; ClusterType clusterType = (ClusterType)b.ToByte(offset); Assert.AreEqual(clusterType, ClusterType.FileData); offset += sizeof(ClusterType); Assert.AreEqual(fileID, b.ToInt32(offset)); offset += sizeof(int); Assert.AreEqual(nextClusterAddress, b.ToInt32(offset)); offset += sizeof(int); Assert.AreEqual(bytesUsed, b.ToInt32(offset)); offset += sizeof(int); Assert.AreEqual(writeTime, new DateTime(b.ToInt64(offset))); offset += sizeof(long); byte[] encryptionThumbprintBytes = b.ToByteArray(offset, KeyThumbprint.Length); Assert.IsTrue(encryptionThumbprintBytes.SequenceEqual(Configuration.CryptoSettings.EncryptionKeyThumbprint.Bytes)); offset += KeyThumbprint.Length; byte[] publicKeyBytes = b.ToByteArray(offset, PublicKey.Length); offset += PublicKey.Length; int dataLength = Configuration.Geometry.BytesPerCluster - offset; int padding = dataLength % 16; dataLength -= padding; Assert.AreEqual(data.Length, dataLength); offset += padding; using (ECDiffieHellmanCng dest = new ECDiffieHellmanCng(Configuration.CryptoSettings.DecryptionKey)) using (AesCng aes = new AesCng()) { aes.KeySize = 256; aes.BlockSize = 128; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.None; aes.Key = dest.DeriveKeyMaterial(new PublicKey(publicKeyBytes).GetCngKey()); aes.IV = new byte[16]; using (var decryptor = aes.CreateDecryptor()) { byte[] decryptedData = b.TransformFinalBlock(decryptor, offset, dataLength); for (int i = 0; i < dataLength; i++) { Assert.AreEqual(data[i], decryptedData[i]); } } } FileDataCluster csc2 = new FileDataCluster(Address); cio.Load(csc2); Assert.IsTrue(csc2.Marker.SequenceEqual(Constants.SrfsMarker)); Assert.IsTrue(csc2.Version.SequenceEqual(Constants.CurrentVersion)); Assert.AreEqual(csc2.VolumeID, Configuration.FileSystemID); Assert.AreEqual(csc2.Type, ClusterType.FileData); Assert.AreEqual(csc2.FileID, fileID); Assert.AreEqual(csc2.NextClusterAddress, nextClusterAddress); Assert.AreEqual(csc2.BytesUsed, bytesUsed); Assert.AreEqual(csc2.WriteTime, writeTime); for (int i = 0; i < dataLength; i++) { Assert.AreEqual(data[i], csc2.Data.ToByte(i)); } } }