private void UnloadHeaderFile(string path, byte[] key) { try { if (!File.Exists(path)) { return; } using (TaggedStream filex = new TaggedStream(path, Network.Protocol)) using (IVCryptoStream crypto = IVCryptoStream.Load(filex, key)) { PacketStream stream = new PacketStream(crypto, Protocol, FileAccess.Read); G2Header header = null; while (stream.ReadPacket(ref header)) { if (header.Name == StoragePacket.File) { StorageFile packet = StorageFile.Decode(header); if (packet == null) { continue; } OpFile commonFile = null; if (!FileMap.SafeTryGetValue(packet.HashID, out commonFile)) { continue; } commonFile.DeRef(); } } } } catch (Exception ex) { Core.Network.UpdateLog("Storage", "Error loading files " + ex.Message); } }
void HashFile(HashPack pack) { // three steps, hash file, encrypt file, hash encrypted file try { OpFile file = null; StorageFile info = pack.File.Info.Clone(); // remove old references from local file OpFile commonFile = null; if (FileMap.SafeTryGetValue(pack.File.Info.HashID, out commonFile)) { commonFile.DeRef(); //crit test } if (!File.Exists(pack.Path)) { return; } // do public hash Utilities.ShaHashFile(pack.Path, ref info.InternalHash, ref info.InternalSize); info.InternalHashID = BitConverter.ToUInt64(info.InternalHash, 0); // if file exists in public map, use key for that file OpFile internalFile = null; InternalFileMap.SafeTryGetValue(info.InternalHashID, out internalFile); if (internalFile != null) { file = internalFile; file.References++; // if file already encrypted in our system, continue if (File.Exists(GetFilePath(info.HashID))) { info.Size = file.Size; info.FileKey = file.Key; info.Hash = file.Hash; info.HashID = file.HashID; if (!Utilities.MemCompare(file.Hash, pack.File.Info.Hash)) { ReviseFile(pack, info); } return; } } // file key is opID and public hash xor'd so that files won't be duplicated on the network // apply special compartment key here as well, xor again RijndaelManaged crypt = Utilities.CommonFileKey(Core.User.Settings.OpKey, info.InternalHash); info.FileKey = crypt.Key; // encrypt file to temp dir string tempPath = Core.GetTempPath(); Utilities.EncryptTagFile(pack.Path, tempPath, crypt, Core.Network.Protocol, ref info.Hash, ref info.Size); info.HashID = BitConverter.ToUInt64(info.Hash, 0); // move to official path string path = GetFilePath(info.HashID); if (!File.Exists(path)) { File.Move(tempPath, path); } // if we dont have record of file make one if (file == null) { file = new OpFile(info); file.References++; FileMap.SafeAdd(info.HashID, file); InternalFileMap.SafeAdd(info.InternalHashID, file); } // else, record already made, just needed to put the actual file in the system else { Debug.Assert(info.HashID == file.HashID); } // if hash is different than previous mark as modified if (!Utilities.MemCompare(file.Hash, pack.File.Info.Hash)) { ReviseFile(pack, info); } } catch (Exception ex) { /*rotate file to back of queue * lock (HashQueue) * if (HashQueue.Count > 1) * HashQueue.Enqueue(HashQueue.Dequeue());*/ Core.Network.UpdateLog("Storage", "Hash thread: " + ex.Message); } }