648 lines
18 KiB
C#

/*********************************************************************************************
* Copyright 2004 - Volian Enterprises, Inc. All rights reserved.
* Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
* ------------------------------------------------------------------------------
* $Workfile: ZipFuncs.cs $ $Revision: 2 $
* $Author: Kathy $ $Date: 8/10/04 9:12a $
*
* $History: ZipFuncs.cs $
*
* ***************** Version 2 *****************
* User: Kathy Date: 8/10/04 Time: 9:12a
* Updated in $/LibSource/Utils
* force copy for backup of zip file on checks (was crashing)
*
* ***************** Version 1 *****************
* User: Kathy Date: 7/27/04 Time: 8:35a
* Created in $/LibSource/Utils
*********************************************************************************************/
using System;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Collections.Specialized;
namespace Utils
{
/// <summary>
/// Zip and UnZip functions.
/// </summary>
public class ZipFuncs
{
[DllImport("Kernel32.DLL")] public static extern uint GetDriveType(char[] lpRootPathName);
private CDZipNET dzip;
private CDUnZipNET duzip;
private string _strZipPathAndFile; // full path and zip file name
private bool _CancelZip;
private bool _zipOnRemovable; // i.e. floppy disk
private int _ArchiveType; // Full or Partial
private string _strZipFileExcludeList; // what not to zip
private string _strComment; // user's zip comment
private string _strFilesToArchive; // what to zip up
private string _strArcTitle; // user's archive title
private string _strDestPath; // place to unzip to
//#define DRIVE_UNKNOWN 0
//#define DRIVE_NO_ROOT_DIR 1
//#define DRIVE_REMOVABLE 2
//#define DRIVE_FIXED 3
//#define DRIVE_REMOTE 4
//#define DRIVE_CDROM 5
//#define DRIVE_RAMDISK 6
private enum DriveType
{
DRIVE_UNKNOWN=0,
DRIVE_NO_ROOT_DIR,
DRIVE_REMOVABLE,
DRIVE_FIXED,
DRIVE_REMOTE,
DRIVE_CDROM,
DRIVE_RAMDISK
}
private enum ZipTypes
{
Full=0,
Partial=1
}
// Contstructor for an existing Zip file
public ZipFuncs(string iZipFile)
{
_strZipPathAndFile = iZipFile;
SetupDestinationPath();
_CancelZip = false;
// populate local variables with Zip file's
// Title, Archive type, and Comment
GetZipCommentInformation();
}
// Constructor for a new Zip file
public ZipFuncs()
{
_strZipPathAndFile = "";
_CancelZip = false;
}
//public properties
public string strArcTitle
{
get { return _strArcTitle; }
set {_strArcTitle = value.ToString(); }
}
public string strZipPathAndFile
{
get { return _strZipPathAndFile;}
set
{
_strZipPathAndFile = value.ToString();
SetupDestinationPath();
// populate local variables with Zip file's
// Title, Archive type, and Comment
GetZipCommentInformation();
}
}
public string strUnZipDestPath
{
get { return _strDestPath; }
set
{
_strDestPath = value.ToString();
}
}
public bool CancelZip
{
get { return _CancelZip;}
set { _CancelZip = value; }
}
public bool zipOnRemovable
{
get { return _zipOnRemovable;}
set { _zipOnRemovable = value;}
}
public int ArchiveType
{
get { return _ArchiveType;}
set { _ArchiveType = value; }
}
public string strFilesToArchive
{
get { return _strFilesToArchive; }
set { _strFilesToArchive = value.ToString(); }
}
public string strZipFileExcludeList
{
get { return _strZipFileExcludeList; }
set { _strZipFileExcludeList = value.ToString(); }
}
public string strComment
{
get {return _strComment;}
set
{
// if (value == null)
// _strComment = "";
// else
_strComment = (value == null)?"":value.ToString();
}
}
public bool CreateNewZipFile()
{
return _GenerateZipFile(true);
}
public bool UpdateZipFile()
{
return _GenerateZipFile(false);
}
private bool _GenerateZipFile(bool NewFileFile)
{
StringBuilder cmntTxt = new StringBuilder();
bool rtnval;
ZipFuncsDlg zpDlg = new ZipFuncsDlg();
dzip = new CDZipNET();
_CancelZip = false;
_zipOnRemovable = IsARemovableDisk();
// Setup DynaZip
// build comment field text
cmntTxt.Append(_strArcTitle);
cmntTxt.Append("\n");
if (_ArchiveType == (int)ZipFuncs.ZipTypes.Partial)
{
// Do not recurse the sub directories when doing a partial archive
cmntTxt.Append("PARTIAL\n");
dzip.RecurseFlag = false;
}
else
{
cmntTxt.Append("FULL\n");
dzip.RecurseFlag = true;
}
cmntTxt.Append(_strComment);
dzip.AddCommentFlag = true;
dzip.Comment = cmntTxt.ToString(); // zip file comment string
// CompressionFactors 10 - 19 are not compatable with older zip programs
// (i.e WinZip 7.0)
dzip.CompressionFactor = 9; // maxium compression
dzip.ExcludeFollowingFlag = true;
dzip.ExcludeFollowing = _strZipFileExcludeList;
dzip.ItemList = _strFilesToArchive;
dzip.LargeZIPFilesFlag = true;
dzip.ZIPFile = _strZipPathAndFile; // zip file name with full path
// Is the target zip path on a removable dirve?
if (_zipOnRemovable)
{
dzip.MultiVolumeControl = CDZipNET.MULTIVOLCONTROL.MV_USEMULTI;
}
else
{
dzip.MultiVolumeControl = CDZipNET.MULTIVOLCONTROL.MV_NONE;
}
// setup status bars
dzip.MajorStatusFlag = true;
dzip.MinorStatusFlag = true;
dzip.ZipMajorStatus += new CDZipNET.OnZipMajorStatus(zpDlg.ZipMajorStatus_event);
dzip.ZipMinorStatus += new CDZipNET.OnZipMinorStatus(zpDlg.ZipMinorStatus_event);
_CancelZip = false;
zpDlg.Show();
// Do the Zip function
if (!NewFileFile)
dzip.ActionDZ = CDZipNET.DZACTION.ZIP_UPDATE; //update existing zip file
else
dzip.ActionDZ = CDZipNET.DZACTION.ZIP_ADD; // create new zip file
rtnval = (zpDlg.DialogResult == System.Windows.Forms.DialogResult.OK);
zpDlg.Dispose();
// check for errors during the zip function.
if (rtnval)
rtnval = CheckZipErrorCode();
// if we are zipping to a different location than the current procedure
// set directory, we always want to return false so that this newly
// created zip file is not placed in the VE-PROMS tree.
if (_zipOnRemovable || ZipFileNotInCurrentDirectory())
rtnval = false;
return rtnval;
}
// If there is a problem with the Zip file header, try to fix it.
private bool FixZipFile()
{
bool rtnval;
string ZipFileName = _strZipPathAndFile;
string backupName = ZipFileName.Substring(0,ZipFileName.LastIndexOf(".")) + ".bku";
_CancelZip = false;
// save a copy of the zip file
File.Copy(ZipFileName,backupName,true);
dzip.FixFlag = true;
dzip.ActionDZ = CDZipNET.DZACTION.ZIP_UPDATE;
if (dzip.ErrorCode == CDZipNET.ZIPRESPONSE.ZE_FORM )
{
dzip.FixFlag = false;
dzip.FixHarderFlag = true;
dzip.ActionDZ = CDZipNET.DZACTION.ZIP_UPDATE;
dzip.FixHarderFlag = false;
}
rtnval = (dzip.ErrorCode == 0); // 0 = success
if (!rtnval)
{
// not successful, so restore from the backup file
File.Copy(backupName,ZipFileName,true);
}
File.Delete(backupName); // delete the backup file
return rtnval;
}
private bool CheckZipErrorCode()
{
bool rtnval;
switch (dzip.ErrorCode)
{
case CDZipNET.ZIPRESPONSE.ZE_OK: // ZE_OK
rtnval = true;
break;
case CDZipNET.ZIPRESPONSE.ZE_FORM: // ZE_FORM
case CDZipNET.ZIPRESPONSE.ZE_TEST: // ZE_TEST
// Internal organization of ZIP file is dammaged.
// Try using the Fix function
// note that you cannot do the fix on removable media
if (!zipOnRemovable)
rtnval = FixZipFile();
else
rtnval = false;
break;
case CDZipNET.ZIPRESPONSE.ZE_ABORT: // ZE_ABORT
rtnval = false;
break;
default:
rtnval = false;
break;
}
return rtnval;
}
// If there is a problem with the Zip file header, try to fix it.
private bool FixUnZipFile()
{
bool rtnval;
string ZipFileName = _strZipPathAndFile;
string backupName = ZipFileName.Substring(0,ZipFileName.LastIndexOf(".")) + ".bku";
_CancelZip = false;
dzip = new CDZipNET();
dzip.ZIPFile = duzip.ZIPFile;
// save a copy of the zip file
File.Copy(ZipFileName,backupName,true);
dzip.FixFlag = true;
dzip.ActionDZ = CDZipNET.DZACTION.ZIP_UPDATE;
if (dzip.ErrorCode == CDZipNET.ZIPRESPONSE.ZE_FORM)
{
dzip.FixFlag = false;
dzip.FixHarderFlag = true;
dzip.ActionDZ = CDZipNET.DZACTION.ZIP_UPDATE;
dzip.FixHarderFlag = false;
}
rtnval = (dzip.ErrorCode == CDZipNET.ZIPRESPONSE.ZE_OK); // 0 = success
dzip.Dispose();
if (!rtnval)
{
// not successful, so restore from the backup file
File.Copy(backupName,ZipFileName,true);
}
File.Delete(backupName); // delete the backup file
return rtnval;
}
private bool CheckUnZipErrorCode()
{
bool rtnval;
switch (duzip.ErrorCode)
{
case CDUnZipNET.UNZIPRESPONSE.UE_OK: // UE_OK
rtnval = true;
break;
case CDUnZipNET.UNZIPRESPONSE.UE_STRUCT: // UE_STRUCT
// Internal organization of ZIP file is dammaged.
// Try using the Fix function
rtnval = FixUnZipFile();
break;
case CDUnZipNET.UNZIPRESPONSE.UE_ABORT: // UE_ABORT
case CDUnZipNET.UNZIPRESPONSE.UE_CANCEL: // UE_CANCEL
rtnval = false;
break;
default:
rtnval = false;
break;
}
return rtnval;
}
public bool AddZipCommentInformation()
{
StringBuilder cmntTxt = new StringBuilder();
dzip = new CDZipNET();
_CancelZip = false;
// Save the current attributes of the zip file, update zip file
// and then restore attributes
// - the zip file might be readonly
System.IO.FileAttributes saveAttribs = File.GetAttributes(_strZipPathAndFile);
File.SetAttributes(_strZipPathAndFile,FileAttributes.Normal);
// add comment
cmntTxt.Append(_strArcTitle);
cmntTxt.Append("\n");
if (_ArchiveType == (int)ZipTypes.Partial)
cmntTxt.Append("PARTIAL\n");
else
cmntTxt.Append("FULL\n");
cmntTxt.Append(_strComment);
dzip.AddCommentFlag = true;
dzip.Comment = cmntTxt.ToString();
dzip.ZIPFile = _strZipPathAndFile; // zip file name with full path
dzip.ActionDZ = CDZipNET.DZACTION.ZIP_ADD;
File.SetAttributes(_strZipPathAndFile,saveAttribs);
return CheckZipErrorCode();
}
public bool GetZipCommentInformation()
{
int x;
string ZipComment;
string strArcType;
_CancelZip = false;
if (!(File.Exists(_strZipPathAndFile)))
return false; // !!! no zip file
duzip = new CDUnZipNET();
duzip.ZIPFile = _strZipPathAndFile; // zip file name with full path
duzip.ActionDZ = CDUnZipNET.DUZACTION.UNZIP_GETCOMMENTSIZE;
if (!CheckUnZipErrorCode())
return false; // error
if (duzip.ReturnCount <= 0)
return false; // no comment informat
duzip.ActionDZ = CDUnZipNET.DUZACTION.UNZIP_GETCOMMENT;
ZipComment = duzip.ReturnString;
x = ZipComment.IndexOf("\n");
if (x < 0) return false; // nothing in comment
_strArcTitle = ZipComment.Substring(0,x);
ZipComment = ZipComment.Substring(x+1);
x = ZipComment.IndexOf("\n");
if (x > 0)
{
strArcType = ZipComment.Substring(0,x);
if (strArcType.Equals("FULL"))
_ArchiveType = (int)ZipTypes.Full;
else
_ArchiveType = (int)ZipTypes.Partial;
_strComment = ZipComment.Substring(x+1);
}
else
{
// at this point, default to a full archive
_ArchiveType = (int)ZipTypes.Full;
// default to path and filename for the comment
_strComment = _strZipPathAndFile;
}
return true;
}
private bool IsARemovableDisk()
{
uint DrvType;
string tmp = _strZipPathAndFile.Substring(0,2);
DrvType = GetDriveType(tmp.ToCharArray());
return (DrvType.Equals((uint)DriveType.DRIVE_REMOVABLE));
}
private bool ZipFileNotInCurrentDirectory()
{
string curdir = Directory.GetCurrentDirectory();
string tmpstr = _strZipPathAndFile.ToUpper();
if (tmpstr.EndsWith(".ZIP"))
tmpstr = tmpstr.Substring(0,tmpstr.LastIndexOf("."));
return tmpstr.Equals(curdir);
}
public bool UnzipFromZipFile()
{
return _UnzipFromZipFile(true); // unzip from the archive
}
public bool TestTheZipFile()
{
return _UnzipFromZipFile(false); // test the archive
}
private bool _UnzipFromZipFile(bool ExtractFiles)
{
StringBuilder cmntTxt = new StringBuilder();
bool rtnval;
ZipFuncsDlg zpDlg = new ZipFuncsDlg();
// StringBuilder cmntTxt = new StringBuilder();
// VEO_Archive arc = (VEO_Archive) _CurObj;
duzip = new CDUnZipNET();
_zipOnRemovable = IsARemovableDisk();
// Setup DynaZip
// zip file name with full path
duzip.ZIPFile = _strZipPathAndFile;
//root of drive letter
// duzip.Destination = Path.GetPathRoot(_strZipPathAndFile);
duzip.Destination = _strDestPath;
// what files to get from the zip file
duzip.Filespec = "*.*"; // get all files
//Replace - this combination of flags results in unzipping all files whether
// they were changed or not.
duzip.FreshenFlag = false;
duzip.UpdateFlag = false;
// Make a reference to a single byte to avoid null access
duzip.MemoryBlock = new Byte[1];
// true = Overwrite non-read only files without asking
duzip.OverwriteFlag = true;
// true = proceed to unzip by traversing into folders
duzip.RecurseFlag = true;
duzip.UnzipSubOptions = CDUnZipNET.UNZIPSUBOPTION.USO_NONE;
// set this option to allow the overwriting of ReadOnly Files.
// this option only has meaning when the OverwriteFlag property
// is set to true
duzip.UnzipSubOptions |= CDUnZipNET.UNZIPSUBOPTION.USO_OVERWRITE_RO;
// allow the MinorCancel event to respond to cancel requests
duzip.UnzipSubOptions |= CDUnZipNET.UNZIPSUBOPTION.USO_MINORCANCEL;
// debug
// duzip.DiagnosticFlag = true;
// duzip.UnzipSubOptions |= CDUnZipNET.UNZIPSUBOPTION.USO_LOGZIPRESULTS;
// setup status bars
duzip.MajorStatusFlag = true;
duzip.MinorStatusFlag = true;
duzip.MessageCallbackFlag = true;
duzip.UnZipMajorStatus += new CDUnZipNET.OnUnZipMajorStatus(zpDlg.ZipMajorStatus_event);
duzip.UnZipMinorStatus += new CDUnZipNET.OnUnZipMinorStatus(zpDlg.ZipMinorStatus_event);
_CancelZip = false;
zpDlg.Show(); // display the status dialog
if (!ExtractFiles)
duzip.TestFlag = true; // don't extract, only test each item in zip file
// Do the UnZip function
duzip.ActionDZ = CDUnZipNET.DUZACTION.UNZIP_EXTRACT;
rtnval = (zpDlg.DialogResult == System.Windows.Forms.DialogResult.OK);
zpDlg.Dispose();
// check for errors during the unzip function.
if (!CheckUnZipErrorCode())
return false; // error
if (duzip.ReturnCount <= 0)
return false; // nothing unzipped
return rtnval;
}
public StringCollection ZipFileContents()
{
StringCollection ZipFileList = new StringCollection();
StringBuilder cmntTxt = new StringBuilder();
duzip = new CDUnZipNET();
_zipOnRemovable = false;
// Setup DynaZip
// zip file name with full path
duzip.ZIPFile = _strZipPathAndFile;
// what files to get from the zip file
duzip.Filespec = "*.*"; // get all files
//Replace - this combination of flags results in unzipping all files whether
// they were changed or not.
duzip.FreshenFlag = false;
duzip.UpdateFlag = false;
// Make a reference to a single byte to avoid null access
duzip.MemoryBlock = new Byte[1];
_CancelZip = false;
// Do the UnZip function
duzip.ActionDZ = CDUnZipNET.DUZACTION.UNZIP_COUNTALLZIPMEMBERS;
int numItems = duzip.ReturnCount;
string str_tmpDate;
string str_tmpFileName;
for (int i=0;i<numItems;i++)
{
duzip.ActionDZ = CDUnZipNET.DUZACTION.UNZIP_GETNEXTZIPINFO;
str_tmpDate = duzip.zi_DateTime;
str_tmpFileName = duzip.zi_FileName;
ZipFileList.Add(str_tmpDate + "!" + str_tmpFileName);
}
return ZipFileList;
}
private void SetupDestinationPath()
{
string strDestPath = "";
duzip = new CDUnZipNET();
_zipOnRemovable = false;
// Setup DynaZip
// zip file name with full path
duzip.ZIPFile = _strZipPathAndFile;
strDestPath = Path.GetDirectoryName(_strZipPathAndFile);
strDestPath = strDestPath.ToUpper();
// what files to get from the zip file
duzip.Filespec = "proc.ini"; // get proc.ini file
//Replace - this combination of flags results in unzipping all files whether
// they were changed or not.
duzip.FreshenFlag = false;
duzip.UpdateFlag = false;
duzip.RecurseFlag = true; // so that it can get with or without path
// Make a reference to a single byte to avoid null access
duzip.MemoryBlock = new Byte[1];
_CancelZip = false;
// Do the UnZip function
int numItems = 0;
if (File.Exists(_strZipPathAndFile))
{
duzip.ActionDZ = CDUnZipNET.DUZACTION.UNZIP_COUNTNAMEDZIPMEMBERS;
// See if we found the file
numItems = duzip.ReturnCount;
}
string str_tmpFileName = "";
// string curdir = Directory.GetCurrentDirectory();
// DestPath = curdir.ToUpper();
if (numItems > 0)
{
// Adjust the destination path based on the full or partial
// path in the zip file
char [] trmchar = {'\\'};
duzip.ActionDZ = CDUnZipNET.DUZACTION.UNZIP_GETNEXTNAMEDZIPINFO;
str_tmpFileName = duzip.zi_FileName;
// trim off the file name
str_tmpFileName = str_tmpFileName.ToUpper();
str_tmpFileName = str_tmpFileName.Substring(0,str_tmpFileName.LastIndexOf("PROC.INI"));
// trim off any backslash
str_tmpFileName = str_tmpFileName.TrimEnd(trmchar);
str_tmpFileName = str_tmpFileName.ToUpper();
if (str_tmpFileName.Length > 0)
{
if (strDestPath.LastIndexOf(str_tmpFileName) > 0)
strDestPath = strDestPath.Substring(0,strDestPath.Length - str_tmpFileName.Length);
}
}
_strDestPath = strDestPath;
return;
}
}
}