public static void EncryptData(Stream fs, byte[] comprBlock) { crcgen = new CRC32(); InitCipher(tpfkey); Random randomiser = new Random(); int val1 = randomiser.Next(); int val2 = randomiser.Next(); int val3 = randomiser.Next(); byte[] header; using (MemoryStream ms = new MemoryStream()) { ms.Write(BitConverter.GetBytes(val1), 0, 4); ms.Write(BitConverter.GetBytes(val2), 0, 4); ms.Write(BitConverter.GetBytes(val3), 0, 4); header = ms.ToArray(); } //DecryptBlock(header, 0, 12); EncryptBlock(header, 0, 12); fs.Write(header, 0, 12); //DecryptBlock(comprBlock, 0, comprBlock.Length); EncryptBlock(comprBlock, 0, comprBlock.Length); fs.Write(comprBlock, 0, comprBlock.Length); }
private void DecryptBlock(byte[] block, int offset, int count, UInt32[] Keys, CRC32 crcgen) { for (int i = offset; i < offset + count; i++) { block[i] = (byte)(block[i] ^ MagicByte(Keys)); Keys = UpdateKeys(block[i], Keys, crcgen); } }
private UInt32[] UpdateKeys(byte byteval, UInt32[] Keys, CRC32 crcgen) { Keys[0] = (UInt32)crcgen.ComputeCrc32(Keys[0], byteval); Keys[1] = Keys[1] + (byte)Keys[0]; Keys[1] = Keys[1] * 0x08088405 + 1; Keys[2] = (UInt32)crcgen.ComputeCrc32(Keys[2], (byte)(Keys[1] >> 24)); return Keys; }
private UInt32[] InitCipher(byte[] password, CRC32 crcgen) { UInt32[] Keys = { 305419896, 591751049, 878082192 }; for (int i = 0; i < password.Length; i++) { Keys = UpdateKeys(password[i], Keys, crcgen); } return Keys; }
public static void DecryptData(ZipReader.ZipEntry entry, byte[] block, int start, int count) { if (block == null || block.Length < count || count < 12) throw new ArgumentException("Invalid arguments for decryption"); crcgen = new CRC32(); InitCipher(tpfkey); DecryptBlock(block, start, 12); if (block[11] != (byte)((entry.CRC >> 24) & 0xff) && (entry.BitFlag & 0x8) != 0x8) throw new FormatException("Incorrect password"); DecryptBlock(block, start + 12, count - 12); }
public byte[] Extract(bool Preview, String outname = null) { byte[] databuff; int dataoff = 30; if (Filename != null) dataoff += Filename.Length; if (Extra != null) dataoff += Extra.Length; using (FileStream tpf = new FileStream(_par._filename, FileMode.Open, FileAccess.Read)) { tpf.Seek(FileOffset, SeekOrigin.Begin); databuff = ZipReader.BuffXOR(tpf, dataoff + (int)ComprSize + 16); // XOR the whole data block as well as the footer } // Check for correct header data and such ZipEntry fileentry = new ZipEntry(databuff); if (!fileentry.Compare(this)) throw new InvalidDataException("File header not as expected"); if (BitConverter.ToUInt32(databuff, (int)ComprSize + dataoff) != datadescriptormagic) throw new InvalidDataException("Footer not as expected"); //ZipCrypto.DecryptData(this, databuff, dataoff, (int)ComprSize); KFreonZipCrypto crypto = new KFreonZipCrypto(this, databuff, dataoff, (int)ComprSize); databuff = crypto.GetBlocks(); databuff = Deflate(databuff, 12 + dataoff, (int)ComprSize - 12); if (databuff.Length != UncomprSize) throw new InvalidDataException("Deflation resulted in incorrect file size"); CRC32 crcgen = new CRC32(); if (crcgen.BlockChecksum(databuff, 0, (int)UncomprSize) != CRC) throw new InvalidDataException("Checksums don't match"); if (!Preview) { outname = outname ?? Filename; using (FileStream fs = new FileStream(outname, FileMode.Create, FileAccess.Write)) { fs.Write(databuff, 0, (int)UncomprSize); } return null; } else return databuff; }
/// <summary> /// Constructor for tree texture object. /// </summary> /// <param name="temppcc">PCC to get info from.</param> /// <param name="ExpID">ExpID of texture.</param> /// <param name="WhichGame">Game target.</param> /// <param name="pathBIOGame">BIOGame path to game targeted.</param> /// <param name="ExecPath">Path to ME3Explorer \exec\ folder.</param> /// <param name="allfiles">List of all PCC's containing texture.</param> /// <param name="Success">OUT: True if sucessfully created.</param> public TreeTexInfo(IPCCObject temppcc, int ExpID, int WhichGame, string pathBIOGame, string ExecPath, out bool Success) { Success = false; CRC32 crcgen = new CRC32(); string ArcPath = pathBIOGame; ITexture2D temptex2D = null; if (temppcc.Exports[ExpID].ValidTextureClass()) { try { temptex2D = temppcc.CreateTexture2D(ExpID, pathBIOGame); } catch (Exception e) { Console.WriteLine(e); return; } // KFreon: If no images, ignore if (temptex2D.imgList.Count == 0) return; string texname = temptex2D.texName; IImageInfo tempImg = temptex2D.GenerateImageInfo(); uint hash = 0; // KFreon: Get texture hash if (tempImg.CompareStorage("pccSto")) { if (temptex2D.texFormat != ImageEngineFormat.DDS_ATI2_3Dc) hash = ~crcgen.BlockChecksum(temptex2D.DumpImg(tempImg.imgSize, ArcPath)); else hash = ~crcgen.BlockChecksum(temptex2D.DumpImg(tempImg.imgSize, pathBIOGame), 0, tempImg.uncSize / 2); } else { byte[] buffer = temptex2D.DumpImg(tempImg.imgSize, ArcPath); if (buffer == null) hash = 0; else { if (temptex2D.texFormat != ImageEngineFormat.DDS_ATI2_3Dc) hash = ~crcgen.BlockChecksum(buffer); else hash = ~crcgen.BlockChecksum(buffer, 0, tempImg.uncSize / 2); } } // KFreon: Get image thumbnail string thumbnailPath = ExecPath + "placeholder.ico"; string tempthumbpath = ExecPath + "ThumbnailCaches\\" + "ME" + WhichGame + "ThumbnailCache\\" + texname + "_" + hash + ".jpg"; bool exists = File.Exists(tempthumbpath); if (!exists) try { using (MemoryStream ms = new MemoryStream(temptex2D.GetImageData())) { var tex = temptex2D.imgList.Where(t => t.offset != -1).First(); int max = (int)(tex.imgSize.height > tex.imgSize.width ? tex.imgSize.height : tex.imgSize.width); double divisor = max > 128 ? max / 128.0 : 1; int newWidth = (int)(tex.imgSize.width / divisor); int newHeight = (int)(tex.imgSize.height / divisor); string temp = KFreonLib.Textures.Creation.GenerateThumbnail(ms, tempthumbpath, newWidth, newHeight); if (temp != null) thumbnailPath = temp; } } catch { } // KFreon: Don't really care about failures // KFreon: Initialise things ValidFirstPCC = WhichGame == 2 && (!String.IsNullOrEmpty(temptex2D.arcName) && temptex2D.arcName != "None"); InfoInitialise(temptex2D, ExpID, hash, WhichGame, temppcc, tempImg.offset, thumbnailPath, pathBIOGame); Success = true; } }
/// <summary> /// Constructor for tree texture object. /// </summary> /// <param name="temppcc">PCC to get info from.</param> /// <param name="ExpID">ExpID of texture.</param> /// <param name="WhichGame">Game target.</param> /// <param name="pathBIOGame">BIOGame path to game targeted.</param> /// <param name="ExecPath">Path to ME3Explorer \exec\ folder.</param> /// <param name="allfiles">List of all PCC's containing texture.</param> /// <param name="Success">OUT: True if sucessfully created.</param> public TreeTexInfo(IPCCObject temppcc, int ExpID, int WhichGame, string pathBIOGame, string ExecPath, out bool Success) { Success = false; CRC32 crcgen = new CRC32(); string ArcPath = pathBIOGame; ITexture2D temptex2D = null; if (temppcc.Exports[ExpID].ValidTextureClass()) { try { temptex2D = temppcc.CreateTexture2D(ExpID, pathBIOGame); } catch (Exception e) { Console.WriteLine(e); return; } // KFreon: If no images, ignore if (temptex2D.imgList.Count == 0) return; string texname = temptex2D.texName; IImageInfo tempImg = temptex2D.GenerateImageInfo(); uint hash = 0; /*if (WhichGame != 1 && temptex2D.arcName != "None") ValidFirstPCC = true;*/ // KFreon: Add pcc name to list in tex2D if necessary /*if (temptex2D.allFiles == null || temptex2D.allFiles.Count == 0) { temptex2D.allFiles = new List<string>(); temptex2D.allFiles.Add(temppcc.pccFileName); } else if (!temptex2D.allFiles.Contains(temppcc.pccFileName)) temptex2D.allFiles.Add(temppcc.pccFileName);*/ // KFreon: Get texture hash if (tempImg.CompareStorage("pccSto")) { if (temptex2D.texFormat != "PF_NormalMap_HQ") hash = ~crcgen.BlockChecksum(temptex2D.DumpImg(tempImg.imgSize, ArcPath)); else hash = ~crcgen.BlockChecksum(temptex2D.DumpImg(tempImg.imgSize, pathBIOGame), 0, tempImg.uncSize / 2); } else { byte[] buffer = temptex2D.DumpImg(tempImg.imgSize, ArcPath); if (buffer == null) hash = 0; else { if (temptex2D.texFormat != "PF_NormalMap_HQ") hash = ~crcgen.BlockChecksum(buffer); else hash = ~crcgen.BlockChecksum(buffer, 0, tempImg.uncSize / 2); } } // KFreon: Get image thumbnail string thumbnailPath = ExecPath + "placeholder.ico"; string tempthumbpath = ExecPath + "ThumbnailCaches\\" + "ME" + WhichGame + "ThumbnailCache\\" + texname + "_" + hash + ".jpg"; bool exists = File.Exists(tempthumbpath); if (!exists) try { using (MemoryStream ms = new MemoryStream(temptex2D.GetImageData())) if (ImageEngine.GenerateThumbnailToFile(ms, tempthumbpath, 128)) thumbnailPath = tempthumbpath; } catch { } // KFreon: Don't really care about failures // KFreon: Initialise things ValidFirstPCC = WhichGame == 2 && (!String.IsNullOrEmpty(temptex2D.arcName) && temptex2D.arcName != "None"); InfoInitialise(temptex2D, ExpID, hash, WhichGame, temppcc, tempImg.offset, thumbnailPath, pathBIOGame); Success = true; } }
public static void Repack(String filename, List <String> files) { List <ZipEntry> Entries = new List <ZipEntry>(); foreach (String file in files) { if (!File.Exists(file)) { throw new FileNotFoundException(Path.GetFileName(file) + " was not found"); } } using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite)) { CRC32 crcgen = new CRC32(); foreach (String file in files) { ZipEntry entry = new ZipEntry(); entry.MainOffset = fs.Position; entry.Filename = Path.GetFileName(file); //Header fs.Write(BitConverter.GetBytes(ZipReader.filemagic), 0, 4); fs.Write(BitConverter.GetBytes(MinVers), 0, 2); fs.Write(BitConverter.GetBytes(BitFlag), 0, 2); fs.Write(BitConverter.GetBytes(ComprMethod), 0, 2); //Date/time FileInfo finfo = new FileInfo(file); ushort secs = (ushort)finfo.LastWriteTime.Second; ushort mins = (ushort)finfo.LastWriteTime.Minute; ushort hours = (ushort)finfo.LastWriteTime.Hour; ushort datetime = (ushort)(secs / 2); datetime |= (ushort)(mins >> 5); datetime |= (ushort)(hours >> 11); fs.Write(BitConverter.GetBytes(datetime), 0, 2); entry.Time = datetime; ushort day = (ushort)finfo.LastWriteTime.Day; ushort month = (ushort)finfo.LastWriteTime.Month; ushort year = (ushort)finfo.LastWriteTime.Year; datetime = day; datetime &= (ushort)(month >> 5); datetime &= (ushort)(year >> 9); fs.Write(BitConverter.GetBytes(datetime), 0, 2); entry.Date = datetime; byte[] comprData; long temppos; using (FileStream fs2 = new FileStream(file, FileMode.Open, FileAccess.Read)) { byte[] buff = new byte[fs2.Length]; fs2.Read(buff, 0, buff.Length); entry.CRC32 = crcgen.BlockChecksum(buff); entry.UncLen = (UInt32)fs2.Length; fs.Write(BitConverter.GetBytes(entry.CRC32), 0, 4); fs.Seek(4, SeekOrigin.Current); // Skip compressed size fs.Write(BitConverter.GetBytes(entry.UncLen), 0, 4); fs.Write(BitConverter.GetBytes((ushort)entry.Filename.Length), 0, 2); fs.Write(BitConverter.GetBytes((ushort)0), 0, 2); foreach (char c in entry.Filename) { fs.WriteByte((byte)c); } temppos = fs.Position; fs2.Seek(0, SeekOrigin.Begin); // Rewind using (MemoryStream ms = new MemoryStream()) { using (DeflateStream deflator = new DeflateStream(ms, CompressionMode.Compress)) { fs2.CopyTo(deflator); } comprData = ms.ToArray(); } entry.ComprLen = (uint)comprData.Length + 12; } fs.Seek(entry.MainOffset + 18, SeekOrigin.Begin); fs.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4); fs.Seek(temppos, SeekOrigin.Begin); ZipCrypto.EncryptData(fs, comprData); // Encrypt and write data fs.Write(BitConverter.GetBytes(ZipReader.datadescriptormagic), 0, 4); fs.Write(BitConverter.GetBytes(entry.CRC32), 0, 4); fs.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4); fs.Write(BitConverter.GetBytes(entry.UncLen), 0, 4); Entries.Add(entry); } uint cdlen = 0; uint cdpos = (uint)fs.Position; for (int i = 0; i < Entries.Count; i++) { long start = fs.Position; fs.Write(BitConverter.GetBytes(ZipReader.dirfileheadermagic), 0, 4); fs.Write(BitConverter.GetBytes(ZipWriter.MinVers), 0, 2); fs.Write(BitConverter.GetBytes(ZipWriter.MinVers), 0, 2); fs.Write(BitConverter.GetBytes(ZipWriter.BitFlag), 0, 2); fs.Write(BitConverter.GetBytes(ZipWriter.ComprMethod), 0, 2); ZipWriter.ZipEntry entry = Entries[i]; fs.Write(BitConverter.GetBytes(entry.Time), 0, 2); fs.Write(BitConverter.GetBytes(entry.Date), 0, 2); fs.Write(BitConverter.GetBytes(entry.CRC32), 0, 4); fs.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4); fs.Write(BitConverter.GetBytes(entry.UncLen), 0, 4); fs.Write(BitConverter.GetBytes((ushort)entry.Filename.Length), 0, 2); fs.Write(BitConverter.GetBytes(0), 0, 4); // 0 for extra field, 0 for comment fs.Write(BitConverter.GetBytes(0), 0, 4); // 0 for disk no, 0 for internal attributes fs.Write(BitConverter.GetBytes(0x81B40020), 0, 4); fs.Write(BitConverter.GetBytes((int)entry.MainOffset), 0, 4); foreach (char c in entry.Filename) { fs.WriteByte((byte)c); } long end = fs.Position; cdlen += (uint)(end - start); } fs.Write(BitConverter.GetBytes(ZipReader.endofdirmagic), 0, 4); fs.Write(BitConverter.GetBytes(0), 0, 4); fs.Write(BitConverter.GetBytes((ushort)Entries.Count), 0, 2); fs.Write(BitConverter.GetBytes((ushort)Entries.Count), 0, 2); fs.Write(BitConverter.GetBytes(cdlen), 0, 4); fs.Write(BitConverter.GetBytes(cdpos), 0, 4); fs.Write(BitConverter.GetBytes(0), 0, 2); long streamlen = fs.Length; fs.Seek(0, SeekOrigin.Begin); // XOR the file while (fs.Position < fs.Length) { int count = (fs.Position + 10000 <= fs.Length) ? 10000 : (int)(fs.Length - fs.Position); byte[] buff2 = BuffXOR(fs, count); fs.Seek(-count, SeekOrigin.Current); fs.Write(buff2, 0, count); } } }
public static void Repack(String filename, List<String> files) { List<ZipEntry> Entries = new List<ZipEntry>(); foreach (String file in files) { if (!File.Exists(file)) throw new FileNotFoundException(Path.GetFileName(file) + " was not found"); } using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite)) { CRC32 crcgen = new CRC32(); foreach (String file in files) { ZipEntry entry = new ZipEntry(); entry.MainOffset = fs.Position; entry.Filename = Path.GetFileName(file); //Header fs.Write(BitConverter.GetBytes(ZipReader.filemagic), 0, 4); fs.Write(BitConverter.GetBytes(MinVers), 0, 2); // TEST build version? //fs.Write(BitConverter.GetBytes(20), 0, 2); fs.Write(BitConverter.GetBytes(BitFlag), 0, 2); fs.Write(BitConverter.GetBytes(ComprMethod), 0, 2); //Date/time FileInfo finfo = new FileInfo(file); ushort secs = (ushort)finfo.LastWriteTime.Second; ushort mins = (ushort)finfo.LastWriteTime.Minute; ushort hours = (ushort)finfo.LastWriteTime.Hour; ushort datetime = (ushort)(secs / 2); datetime |= (ushort)(mins >> 5); datetime |= (ushort)(hours >> 11); fs.Write(BitConverter.GetBytes(datetime), 0, 2); entry.Time = datetime; ushort day = (ushort)finfo.LastWriteTime.Day; ushort month = (ushort)finfo.LastWriteTime.Month; ushort year = (ushort)finfo.LastWriteTime.Year; datetime = day; datetime &= (ushort)(month >> 5); datetime &= (ushort)(year >> 9); fs.Write(BitConverter.GetBytes(datetime), 0, 2); entry.Date = datetime; byte[] comprData; long temppos; using (FileStream fs2 = new FileStream(file, FileMode.Open, FileAccess.Read)) { byte[] buff = new byte[fs2.Length]; fs2.Read(buff, 0, buff.Length); entry.CRC32 = crcgen.BlockChecksum(buff); entry.UncLen = (UInt32)fs2.Length; fs.Write(BitConverter.GetBytes(entry.CRC32), 0, 4); fs.Seek(4, SeekOrigin.Current); // Skip compressed size fs.Write(BitConverter.GetBytes(entry.UncLen), 0, 4); if (entry.Filename.ToLower().Contains("meresults")) entry.Filename = "texmod.log"; fs.Write(BitConverter.GetBytes((ushort)entry.Filename.Length), 0, 2); fs.Write(BitConverter.GetBytes((ushort)0), 0, 2); foreach (char c in entry.Filename) fs.WriteByte((byte)c); temppos = fs.Position; fs2.Seek(0, SeekOrigin.Begin); // Rewind using (MemoryStream ms = new MemoryStream()) { using (DeflateStream deflator = new DeflateStream(ms, CompressionMode.Compress)) fs2.CopyTo(deflator); comprData = ms.ToArray(); } entry.ComprLen = (uint)comprData.Length + 12; } fs.Seek(entry.MainOffset + 18, SeekOrigin.Begin); fs.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4); fs.Seek(temppos, SeekOrigin.Begin); ZipCrypto.EncryptData(fs, comprData); // Encrypt and write data fs.Write(BitConverter.GetBytes(ZipReader.datadescriptormagic), 0, 4); fs.Write(BitConverter.GetBytes(entry.CRC32), 0, 4); fs.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4); fs.Write(BitConverter.GetBytes(entry.UncLen), 0, 4); Entries.Add(entry); } uint cdlen = 0; uint cdpos = (uint)fs.Position; for (int i = 0; i < Entries.Count; i++) { long start = fs.Position; fs.Write(BitConverter.GetBytes(ZipReader.dirfileheadermagic), 0, 4); fs.Write(BitConverter.GetBytes(ZipWriter.MinVers), 0, 2); fs.Write(BitConverter.GetBytes(ZipWriter.MinVers), 0, 2); fs.Write(BitConverter.GetBytes(ZipWriter.BitFlag), 0, 2); fs.Write(BitConverter.GetBytes(ZipWriter.ComprMethod), 0, 2); ZipWriter.ZipEntry entry = Entries[i]; fs.Write(BitConverter.GetBytes(entry.Time), 0, 2); fs.Write(BitConverter.GetBytes(entry.Date), 0, 2); fs.Write(BitConverter.GetBytes(entry.CRC32), 0, 4); fs.Write(BitConverter.GetBytes(entry.ComprLen), 0, 4); fs.Write(BitConverter.GetBytes(entry.UncLen), 0, 4); fs.Write(BitConverter.GetBytes((ushort)entry.Filename.Length), 0, 2); fs.Write(BitConverter.GetBytes(0), 0, 4); // 0 for extra field fs.Write(BitConverter.GetBytes(0), 0, 4); // 0 for disk no, 0 for internal attributes fs.Write(BitConverter.GetBytes(0x81B40020), 0, 4); fs.Write(BitConverter.GetBytes((int)entry.MainOffset), 0, 4); foreach (char c in entry.Filename) fs.WriteByte((byte)c); long end = fs.Position; cdlen += (uint)(end - start); } fs.Write(BitConverter.GetBytes(ZipReader.endofdirmagic), 0, 4); fs.Write(BitConverter.GetBytes(0), 0, 4); fs.Write(BitConverter.GetBytes((ushort)Entries.Count), 0, 2); fs.Write(BitConverter.GetBytes((ushort)Entries.Count), 0, 2); fs.Write(BitConverter.GetBytes(cdlen), 0, 4); fs.Write(BitConverter.GetBytes(cdpos), 0, 4); string createdBy = " "; string comment = " "; string fullString = createdBy + "\n" + comment; fs.Write(BitConverter.GetBytes(fullString.Length), 0, 2); byte[] bytes = Encoding.Default.GetBytes(fullString); fs.Write(bytes, 0, bytes.Length); long streamlen = fs.Length; fs.Seek(0, SeekOrigin.Begin); // XOR the file while (fs.Position < fs.Length) { int count = (fs.Position + 10000 <= fs.Length) ? 10000 : (int)(fs.Length - fs.Position); byte[] buff2 = BuffXOR(fs, count); fs.Seek(-count, SeekOrigin.Current); fs.Write(buff2, 0, count); } } }
public byte[] Extract(bool Preview, String outname = null) { byte[] databuff; int dataoff = 30; // For ZipEntry header - not the above one if (Filename != null) { dataoff += Filename.Length; } if (Extra != null) { dataoff += Extra.Length; } // KFreon: Use stored MemoryStream if possible. Stream tpf = null; if (_par.FileData == null) { tpf = new FileStream(_par._filename, FileMode.Open, FileAccess.Read); } else { tpf = new MemoryStream(_par.FileData); } tpf.Seek(FileOffset, SeekOrigin.Begin); databuff = ZipReader.BuffXOR(tpf, dataoff + (int)ComprSize + 16); // XOR the whole data block as well as the footer // KFreon: Dispose of stream IF it was a FileStream if (_par.FileData == null) { tpf.Dispose(); } // Check for correct header data and such ZipEntry fileentry = new ZipEntry(databuff); if (!fileentry.Compare(this)) { throw new InvalidDataException("File header not as expected"); } // KFreon: Apparently not necessary. Some TPF's fail to load with this, but when commented out, they load fine, so... /*if (BitConverter.ToUInt32(databuff, (int)ComprSize + dataoff) != datadescriptormagic) * Console.WriteLine("Footer not as expected");*/ ZipDecrypto crypto = new ZipDecrypto(this, databuff, dataoff, (int)ComprSize); databuff = crypto.GetBlocks(); databuff = Deflate(databuff, 12 + dataoff, (int)ComprSize - 12); if (databuff.Length != UncomprSize) { throw new InvalidDataException("Deflation resulted in incorrect file size"); } CRC32 crcgen = new CRC32(); if (crcgen.BlockChecksum(databuff, 0, (int)UncomprSize) != CRC) { throw new InvalidDataException("Checksums don't match"); } if (!Preview) { outname = outname ?? Filename; using (FileStream fs = new FileStream(outname, FileMode.Create, FileAccess.Write)) { fs.Write(databuff, 0, (int)UncomprSize); } return(null); } else { return(databuff); } }