/*
* CPZipStripper 2.0
* Written by Decebal Mihailescu [http://www.codeproject.com/script/articles/list_articles.asp?userid=634640]
*/
using System;
using System.Collections.Generic;
using System.Text;
using java.util.zip;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
namespace CPZipStripper
{
static class ZipUtility
{
static private string m_zipFolder;
static private ZipOutputStream _zos = null;
static private int m_trimIndex = 0;
static private sbyte[] _buffer = new sbyte[2048];
// Call this function to remove the key from memory after use for security
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
internal static extern bool ZeroMemory(IntPtr Destination, int Length);
#region cryptograhy
//// Function to Generate a 64 bits Key.
//static string GenerateKey()
//{
// //DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
// // Create an instance of Symetric Algorithm. Key and IV is generated automatically.
// DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
// // Use the Automatically generated key for Encryption.
// return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
//}
//static void EncryptFile(string sInputFilename,
// string sOutputFilename,
// string sKey)
//{
// FileStream fsInput = new FileStream(sInputFilename,
// FileMode.Open,
// FileAccess.Read);
// FileStream fsEncrypted = new FileStream(sOutputFilename,
// FileMode.Create,
// FileAccess.Write);
// DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
// DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
// DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
// ICryptoTransform desencrypt = DES.CreateEncryptor();
// CryptoStream cryptostream = new CryptoStream(fsEncrypted,
// desencrypt,
// CryptoStreamMode.Write);
// byte[] bytearrayinput = new byte[fsInput.Length];
// fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
// cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
// cryptostream.Close();
// fsInput.Close();
// fsEncrypted.Close();
//}
//static void DecryptFile(string sInputFilename,
// string sOutputFilename,
// string sKey)
//{
// DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
// //A 64 bit key and IV is required for this provider.
// //Set secret key For DES algorithm.
// DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
// //Set initialization vector.
// DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
// //Create a file stream to read the encrypted file back.
// FileStream fsread = new FileStream(sInputFilename,
// FileMode.Open,
// FileAccess.Read);
// //Create a DES decryptor from the DES instance.
// ICryptoTransform desdecrypt = DES.CreateDecryptor();
// //Create crypto stream set to read and do a
// //DES decryption transform on incoming bytes.
// CryptoStream cryptostreamDecr = new CryptoStream(fsread,
// desdecrypt,
// CryptoStreamMode.Read);
// //Print the contents of the decrypted file.
// StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
// fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
// fsDecrypted.Flush();
// fsDecrypted.Close();
//}
//static void TestEncryptDecrypt()
//{
// string s = "Foo bar";
// string s1 = Convert.ToBase64String(Encoding.Unicode.GetBytes(s));
// // And back...
// string s2 = Encoding.Unicode.GetString(Convert.FromBase64String(s1));
// // Must be 64 bits, 8 bytes.
// // Distribute this key to the user who will decrypt this file.
// string sSecretKey;
// // Get the Key for the file to Encrypt.
// sSecretKey = GenerateKey();
// // For additional security Pin the key.
// GCHandle gch = GCHandle.Alloc(sSecretKey, GCHandleType.Pinned);
// // Encrypt the file.
// EncryptFile(@"C:\MyData.txt",
// @"C:\Encrypted.txt",
// sSecretKey);
// // Decrypt the file.
// DecryptFile(@"C:\Encrypted.txt",
// @"C:\Decrypted.txt",
// sSecretKey);
// // Remove the Key from memory.
// ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
// gch.Free();
//}
#endregion
public static List<string> GetZipFileNames(string zipFile)
{
ZipFile zf = null;
List<string> list = new List<string>();
try
{
zf = new ZipFile(zipFile);
java.util.Enumeration enu = zf.entries();
while (enu.hasMoreElements())
{
ZipEntry zen = enu.nextElement() as ZipEntry;
if (zen.isDirectory())
continue;//ignore directories
list.Add(zen.getName());
System.Windows.Forms.Application.DoEvents();
}
}
catch(Exception ex)
{
throw new ApplicationException("Please drag/drop only valid zip files\nthat are not password protected.",ex);
}
finally
{
if (zf != null)
zf.close();
}
return list;
}
public static void CreateZipFromFolder(string Folder, IsFileStrippableDelegate IsStrip)
{
try
{
string ParentDir = Directory.GetParent(Folder).FullName;
m_trimIndex = ParentDir.Length;
string root = Path.GetPathRoot(Folder);
if (ParentDir != root)
m_trimIndex++;
m_zipFolder = Folder;
string strNewFile = m_zipFolder + ".zip";
string fileName = Path.GetFileName(strNewFile);
strNewFile = Path.GetDirectoryName(strNewFile) + @"\" + fileName;
//make room for the new zip
System.IO.File.Delete(strNewFile + ".old");
if (File.Exists(strNewFile))
System.IO.File.Move(strNewFile, strNewFile + ".old");
_zos = new ZipOutputStream(new java.io.FileOutputStream(strNewFile));
_CreateZipFromFolder(Folder, IsStrip);
}//try ends
catch (Exception ex)
{
throw new ApplicationException("unable to zip " + Folder + "folder", ex);
}
finally
{
if (_zos != null)
_zos.close();
_zos = null;
m_trimIndex = 0;
}
}
private static void _CreateZipFromFolder(string Folder, IsFileStrippableDelegate IsStrip)
{
System.IO.DirectoryInfo dirInfo =
new System.IO.DirectoryInfo(Folder);
System.IO.FileInfo[] files = dirInfo.GetFiles("*");//all files
foreach (FileInfo file in files)
{
if (IsStrip != null && IsStrip(file.FullName))
continue;//skip, don't zip it
java.io.FileInputStream instream = new java.io.FileInputStream(file.FullName);
int bytes = 0;
string strEntry = file.FullName.Substring(m_trimIndex);
_zos.putNextEntry(new ZipEntry(strEntry));
while ((bytes = instream.read(_buffer, 0, _buffer.Length)) > 0)
{
_zos.write(_buffer, 0, bytes);
}
_zos.closeEntry();
instream.close();
System.Windows.Forms.Application.DoEvents();
}
System.IO.DirectoryInfo[] folders = null;
folders = dirInfo.GetDirectories("*");
if (folders != null)
{
foreach (System.IO.DirectoryInfo folder in folders)
{
_CreateZipFromFolder(folder.FullName, IsStrip);
}
}
}
public static void StripZip(string zipFile, List<string> trashFiles)
{
if (zipFile == null ||zipFile.Length == 0 || !File.Exists(zipFile))
return;
ZipOutputStream zos = null;
ZipInputStream zis = null;
//remove 'zip' extension
bool bsuccess = true;
string strNewFile = zipFile.Remove(zipFile.Length - 3, 3) + "tmp";
try
{
zos = new ZipOutputStream(new java.io.FileOutputStream(strNewFile));
zis = new ZipInputStream(new java.io.FileInputStream(zipFile));
ZipEntry ze = null;
while ((ze = zis.getNextEntry()) != null)
{
if (ze.isDirectory())
continue;//ignore directories
string fname = ze.getName();
bool bstrip = trashFiles.Contains(fname);
if (!bstrip)
{
//copy the entry from zis to zos
int bytes = 0;
try
{
//deal with password protected files
zos.putNextEntry(new ZipEntry(fname));
while ((bytes = zis.read(_buffer, 0, _buffer.Length)) > 0)
{
zos.write(_buffer, 0, bytes);
System.Windows.Forms.Application.DoEvents();
}
}
catch (Exception)
{
bsuccess = false;
throw;
}
finally
{
zis.closeEntry();
zos.closeEntry();
}
}
}
}
catch (Exception ex)
{
bsuccess = false;
throw new ApplicationException("unable to zip/unzip: " + zipFile, ex);
}
finally
{
if (zis != null)
zis.close();
if (zos != null)
zos.close();
if (bsuccess)
{
System.IO.File.Delete(zipFile + ".old");
System.IO.File.Move(zipFile, zipFile + ".old");
System.IO.File.Move(strNewFile, zipFile);
}
else
{
System.IO.File.Delete(strNewFile);
}
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
public static void UnZip(string file, string Folder, IsFileStrippableDelegate IsStrip)
{
if (file == null || file.Length == 0 || !File.Exists(file))
return;
ZipInputStream zis = null;
try
{
zis = new ZipInputStream(new java.io.FileInputStream(file));
ZipEntry ze = null;
while ((ze = zis.getNextEntry()) != null)
{
if (ze.isDirectory())
continue;//ignore directories
string fname = ze.getName();
bool bstrip = IsStrip != null && IsStrip(fname);
if (!bstrip)
{
//unzip entry
int bytes = 0;
FileStream filestream = null;
BinaryWriter w = null;
try
{
string filePath = Folder + @"\" + fname;
if(!Directory.Exists(Path.GetDirectoryName(filePath)))
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
filestream = new FileStream(filePath, FileMode.Create);
w = new BinaryWriter(filestream);
while ((bytes = zis.read(_buffer, 0, _buffer.Length)) > 0)
{
System.Windows.Forms.Application.DoEvents();
for (int i = 0; i < bytes; i++)
{
unchecked
{
w.Write((byte)_buffer[i]);
}
}
}
}
catch (Exception)
{
throw;
}
finally
{
zis.closeEntry();
w.Close();
filestream.Close();
}
}
}
}
catch (Exception ex)
{
throw new ApplicationException("unable to unzip: " + file +"\nIt might be password protected.", ex);
}
finally
{
if (zis != null)
zis.close();
}
}
}
}