// TAHファイルをstreamに書き込む.成功ならtrue,失敗ならfalseを返す. public bool Write(Stream tostream) { try { int index = 0; // ファイル先頭に移動する. tostream.Seek(0, SeekOrigin.Begin); using (BufferedStream stream = new BufferedStream(tostream)) using (BinaryWriter binarywriter = new BinaryWriter(stream)) { // ヘッダー情報を構築する. BuildHeader(); // ヘッダーを書き込む. header.Write(binarywriter); long entryposition = stream.Position; // offset値は0のままでエントリを一度書き込む. foreach (TAHContent content in contents) { content.Entry.Write(binarywriter); } // ディレクトリを構築する BuildDirectory(); // ディレクトリを書き込む. directory.Write(binarywriter); // データを書き込む foreach (TAHContent content in contents) { // 実際にデータを読み込む. Byte[] data = Data(delegateFileList[index++]); // ヘッダーを更新する. content.Data = data; content.Entry.Length = data.Length; content.Entry.DataOffset = (uint)stream.Position; UInt32 length = (UInt32)content.Entry.Length; binarywriter.Write(length); Byte[] cryptdata = TAHUtil.Encrypt(content.Data); binarywriter.Write(cryptdata); // 参照を解除する. content.Data = null; data = null; } // エントリを書き直す. stream.Seek(entryposition, SeekOrigin.Begin); foreach (TAHContent content in contents) { content.Entry.Write(binarywriter); } // バッファをフラッシュして完了. binarywriter.Flush(); binarywriter.Close(); //stream.Flush(); } } catch (Exception ex) { Debug.WriteLine(ex.Message); return(false); } return(true); }
public static void ReadExternalFileList() { external_files = new ext_file_list(); if (System.IO.File.Exists("names.txt")) { System.IO.StreamReader reader = new System.IO.StreamReader(System.IO.File.OpenRead("names.txt")); List <string> known_files = new List <string>(); string line; while ((line = reader.ReadLine()) != null) { known_files.Add(line); } //map a list of hash keys to the file... external_files.files = known_files.ToArray(); if (external_files.files != null) { external_files.hashkeys = new UInt32[external_files.files.Length]; for (int i = 0; i < external_files.files.Length; i++) { external_files.hashkeys[i] = TAHUtil.CalcHash(external_files.files[i]); //Console.WriteLine(external_files.hashkeys[i].ToString("X8") + "\t" + external_files.files[i]); } } //sorting for faster look up... Array.Sort(external_files.hashkeys, external_files.files); } }
public static byte[] ReadEntryData(BinaryReader br, TAHEntry e) { br.BaseStream.Seek(e.DataOffset, SeekOrigin.Begin); byte[] output = new byte[br.ReadInt32()]; byte[] input = br.ReadBytes(e.Length - 4); TAHUtil.Decrypt(input, output); return(output); }
public static byte[] Decrypt(byte[] input, byte[] output) { //debug = true; try { #if DECRYPT_DEBUG byte[] output2 = new byte[output.Length]; if (debug) { TAHUtil.DecryptOld(input.Clone() as byte[], output2); } #endif DoDecrypt(input, output); #if DECRYPT_DEBUG if (debug) { for (int i = 0; i < output.Length; ++i) { System.Diagnostics.Debug.Assert(output2[i] == output[i]); } } #endif #if ENCRYPT_DEBUG byte[] encrypted = DoEncrypt(output); byte[] encrypted2 = new byte[output.Length]; uint length = (uint)encrypted2.Length; //TAHdecrypt.Decrypter.encrypt(ref output, (uint)output.Length, ref encrypted2, ref length); byte[] decrypted = new byte[output.Length]; DoDecrypt(encrypted, decrypted); if (debug) { for (int i = 0; i < output.Length; ++i) { System.Diagnostics.Debug.Assert(decrypted[i] == output[i]); } } #endif return(output); } catch (Exception e) { DbgPrint(e.ToString()); throw; } }
// TAHにファイルを加える. public void Add(string filename) { // オリジナルのファイル名を保存しておく. delegateFileList.Add(filename); // TAHに格納可能なファイル名に変換する. string regularfile = filename.Replace('\\', '/'); TAHEntry tahentry = new TAHEntry(); tahentry.DataOffset = 0; tahentry.FileName = regularfile; tahentry.Length = 0; if (Path.GetDirectoryName(regularfile) == "") { // dddddddd_xxxxxxxx.eee形式をハッシュ値に戻す if (regularfile.Length >= 17) { string hashcode = regularfile.Substring(9, 8); try { // 16進数からハッシュ値に. tahentry.Hash = UInt32.Parse(hashcode, System.Globalization.NumberStyles.HexNumber); // 暫定ファイル名は削除. tahentry.FileName = null; } catch (Exception) { // 判んない時は適当につける. tahentry.Hash = TAHUtil.CalcHash(regularfile); } } else { // 判んない時は適当につける. tahentry.Hash = TAHUtil.CalcHash(regularfile); } } else { tahentry.Hash = TAHUtil.CalcHash(regularfile); } TAHContent content = new TAHContent(tahentry, null); contents.Add(content); }
public void Write(BinaryWriter bw) { MemoryStream ms = new MemoryStream(); BinaryWriter bw2 = new BinaryWriter(ms); foreach (string i in Files) { if (i.EndsWith("/")) { TAHUtil.WriteString(bw2, i); } else { TAHUtil.WriteString(bw2, Path.GetFileName(i)); } } bw2.Flush(); byte[] encrypted = TAHUtil.Encrypt(ms.ToArray()); bw.Write((uint)ms.Length); bw.Write(encrypted); }
public GenericTAHStream(GenericTahInfo info, ArcsTahFilesEntry tsoInfo) { // zipファイルの中か? if (info.zipid != -1) { ArcsZipArcEntry zip = TDCGExplorer.ArcsDB.GetZip(info.zipid); string zippath = Path.Combine(TDCGExplorer.SystemDB.zips_path, zip.path); switch (Path.GetExtension(zip.path).ToLower()) { case ".zip": archive = new ZipArchive(); break; case ".lzh": archive = new LzhArchive(); break; case ".rar": archive = new RarArchive(); break; default: archive = new DirectAccessArchive(); break; } TDCGExplorer.LastAccessFile = zippath; archive.Open(zippath); if (archive == null) { throw new Exception(TextResource.ArchiveIsNull); } // foreach (IArchiveEntry entry in archive) { // ディレクトリのみの場合はスキップする. if (entry.IsDirectory == true) { continue; } // マッチするファイルを見つけた. if (entry.FileName == info.path) { ms = new MemoryStream((int)entry.Size); archive.Extract(entry, ms); ms.Seek(0, SeekOrigin.Begin); tah = new TAHFile(ms); tah.LoadEntries(); if (tsoInfo == null) { return; } int tahentry = 0; foreach (TAHEntry ent in tah.EntrySet.Entries) { // 該当ファイルを見つけた. if (tahentry == tsoInfo.tahentry) { byte[] data = TAHUtil.ReadEntryData(tah.Reader, ent); // Cursor.Current = Cursors.WaitCursor; ims = new MemoryStream(data); return; } tahentry++; } } } } else { string source = Path.Combine(TDCGExplorer.SystemDB.arcs_path, info.path); tah = new TAHFile(source); tah.LoadEntries(); if (tsoInfo == null) { return; } int tahentry = 0; foreach (TAHEntry ent in tah.EntrySet.Entries) { // 該当ファイルを見つけた. if (tahentry == tsoInfo.tahentry) { byte[] data = TAHUtil.ReadEntryData(tah.Reader, ent); // ims = new MemoryStream(data); return; } tahentry++; } } throw new Exception("TAH内のファイルが見つかりません"); }
public TAHContent LoadContent(BinaryReader br, TAHEntry e) { return(new TAHContent(e, TAHUtil.ReadEntryData(br, e))); }
public void Read(BinaryReader br, TAHFile file) { // ディレクトリデータの読み込み Files = new List <string>(file.Header.NumEntries); int output_length = br.ReadInt32(); int input_length = (int)(file.EntrySet[0].DataOffset - br.BaseStream.Position); //- 16 - 8 * file.Header.NumEntries; byte[] input = br.ReadBytes(input_length); byte[] output = new byte[output_length]; if (output.Length == 0) { return; } // add konoa:tahdecryptorのバグ回避. if (input.Length == 0) { return; } TAHUtil.Decrypt(input, output); //TAHdecrypt.Decrypter.decrypt(ref input, (uint)input.Length, ref output, (uint)output.Length); MemoryStream ms = new MemoryStream(output); BinaryReader br2 = new BinaryReader(ms); try { string dir = ""; while (ms.Position < ms.Length) { string name = TAHUtil.ReadString(br2); if (name.Length == 0) { } else if (name.EndsWith("/")) { dir = name; //DbgPrint("Directory: " + dir); } else { name = dir + name; uint hash = TAHUtil.CalcHash(name); TAHEntry ent; //DbgPrint(hash.ToString("X").PadLeft(8, '0')); if (file.EntrySet.TryGetValue(hash, out ent)) { ent.FileName = name; //DbgPrint(": Found: " + file); } else { //DbgPrint(": Not Found: " + file); System.Diagnostics.Debug.Assert(false); } //EntryMap[hash].FileName = FileName; } Files.Add(name); } } catch (EndOfStreamException) { } }