"Fossies" - the Fresh Open Source Software Archive

Member "csharp/Unzip.cs" (18 Jan 2009, 28562 Bytes) of package /windows/misc/unz600dn.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C# source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Unzip.cs" see the Fossies "Dox" file reference documentation.

    1 #region README
    2 
    3   //_____________________________________________________________________________
    4   //
    5   //Sample C# code, .NET Framework 1.1, contributed to the Info-Zip project by
    6   //Adrian Maull, April 2005.
    7   //
    8   //If you have questions or comments, contact me at adrian.maull@sprintpcs.com.  Though
    9   //I will try to respond to coments/questions, I do not guarantee such response.
   10   //
   11   //THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
   12   //KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
   13   //IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
   14   //PARTICULAR PURPOSE.
   15   //
   16   //_____________________________________________________________________________
   17 
   18 
   19 #endregion
   20 
   21 #region KNOWN ISSUES
   22 
   23   //_____________________________________________________________________________
   24   //
   25   //KNOWN ISSUES:
   26   //From my testing I have encountered some issues
   27   //
   28   //1.  I receive an error code from the Unzip32.dll when I try to retrieve the comment from the
   29   //    zip file.  To display a comment you set the nzflag of the DCLIST structure = 1.  In this
   30   //    implementation, just set the m_Unzip.ExtractList = ExtractListEnum.ListContents and
   31   //    m_Unzip.DisplayComment = DisplayCommentEnum.True
   32   //    I provided a work around to this in the GetZipFileComment() method.
   33   //
   34   //    [CS, 2009-01-10:]
   35   //    The DisplayComment option works now. However, the work-around code to
   36   //    retrieve the zipfile comment using direct I/O has not yet been replaced
   37   //    by code using the UnZip DLL.
   38   //
   39   //2.  I have not tested any password/encryption logic in this sample
   40   //_____________________________________________________________________________
   41 
   42 
   43 #endregion
   44 
   45 using System;
   46 using System.Security.Permissions;
   47 using System.Runtime.InteropServices;
   48 using System.Text;
   49 using System.Windows.Forms;
   50 using System.IO;
   51 
   52 namespace CSharpInfoZip_UnZipSample
   53 {
   54   /// <summary>
   55   /// Summary description for Unzip.
   56   /// </summary>
   57 
   58   #region Public Enums
   59 
   60   public enum ExtractOnlyNewerEnum {False, True};
   61   public enum SpaceToUnderScoreEnum {False, True};
   62   public enum PromptToOverWriteEnum {NotRequired, Required};
   63   public enum QuietEnum {AllMessages, LessMessages, NoMessages};
   64   public enum WriteStdOutEnum {False, True};
   65   public enum TestZipEnum {False, True};
   66   public enum ExtractOrListEnum {Extract, ListContents};
   67   public enum FreshenExistingEnum {False, True};
   68   public enum DisplayCommentEnum {False, True};
   69   public enum HonorDirectoriesEnum {False, True};
   70   public enum OverWriteFilesEnum {False, True};
   71   public enum ConvertCR_CRLFEnum {False, True};
   72   public enum VerboseZIEnum {False, True};
   73   public enum UnixFileBackupEnum { False, True }
   74   public enum CaseSensitivityEnum { True, False };
   75   public enum RestoreTimeStampsEnum { All, FilesOnly, None };
   76   public enum UTF8NameTranslationEnum { Automatic, EscapeNonASCII, Disabled };
   77   public enum PrivilegeEnum {Default, ACL, Privilege};
   78   public enum ReplaceFileOptionsEnum {ReplaceNo=100, ReplaceYes=102, ReplaceAll=103,
   79                                       ReplaceNone=104, ReplaceRename=105};
   80 
   81 
   82   #endregion
   83 
   84   #region Event Delegates
   85 
   86   public delegate void UnZipDLLPrintMessageEventHandler(object sender, UnZipDLLPrintMessageEventArgs  e);
   87   public delegate int UnZipDLLServiceMessageEventHandler(object sender, UnZipDLLServiceMessageEventArgs  e);
   88 
   89   #endregion
   90 
   91   public class Unzip
   92   {
   93     public Unzip()
   94     {
   95     }
   96 
   97     #region Constants
   98     // Current version of the DCLIST interface structure, must be matched
   99     // with the UZ_DCL_STRUCTVER constant as defined in the struct.h header
  100     // from the UnZip WinDLL code.
  101     private const uint uz_dcl_StructVer = 0x600;
  102     #endregion
  103 
  104     #region Private Vars
  105 
  106     private ulong m_ZipFileSize;
  107     private ulong m_ZipFileCount;
  108     private int m_Stop;
  109     private string m_ZipFileName;
  110     private string m_ExtractionDirectory;
  111     private string m_Password;
  112     private string m_Comment;
  113     private string [] m_FilesToUnzip = new string[0]; //Default
  114     private string [] m_FilesToExclude = new string[0]; //Default
  115     private ZipFileEntries m_ZipFileEntries = new ZipFileEntries();
  116     private Encoding m_EncodingANSI = Encoding.Default;
  117 
  118     private ExtractOnlyNewerEnum m_ExtractOnlyNewer;
  119     private SpaceToUnderScoreEnum m_SpaceToUnderScore;
  120     private PromptToOverWriteEnum m_PromptToOverWrite;
  121     private QuietEnum m_Quiet;
  122     private WriteStdOutEnum m_WriteStdOut;
  123     private TestZipEnum m_TestZip;
  124     private ExtractOrListEnum m_ExtractOrList;
  125     private FreshenExistingEnum m_FreshenExisting;
  126     private DisplayCommentEnum m_DisplayComment;
  127     private HonorDirectoriesEnum m_HonorDirectories;
  128     private OverWriteFilesEnum m_OverWriteFiles;
  129     private ConvertCR_CRLFEnum m_ConvertCR_CRLF;
  130     private VerboseZIEnum m_VerboseZI;
  131     private UnixFileBackupEnum m_UnixFileBackup;
  132     private CaseSensitivityEnum m_CaseSensitivity;
  133     private RestoreTimeStampsEnum m_RestoreTimeStamps;
  134     private UTF8NameTranslationEnum m_UTF8NameTranslation;
  135     private PrivilegeEnum m_Privilege;
  136 
  137 
  138     #endregion
  139 
  140     #region Structures
  141 
  142     // Callback Large String
  143     protected struct UNZIPCBChar
  144     {
  145       [MarshalAs( UnmanagedType.ByValArray, SizeConst= 32000, ArraySubType = UnmanagedType.U1)]
  146       public byte [] ch;
  147     }
  148 
  149     // Callback Small String (size of a filename buffer)
  150     protected struct UNZIPCBCh
  151     {
  152       [MarshalAs( UnmanagedType.ByValArray, SizeConst= 260, ArraySubType = UnmanagedType.U1)]
  153       public byte [] ch;
  154     }
  155 
  156     //UNZIP32.DLL DCLIST Structure
  157     [ StructLayout( LayoutKind.Sequential )]
  158     protected struct DCLIST
  159     {
  160       public uint StructVersID;       // struct version id (= UZ_DCL_STRUCTVER)
  161       public int ExtractOnlyNewer;    //1 = Extract Only Newer/New, Else 0
  162       public int SpaceToUnderscore;   //1 = Convert Space To Underscore, Else 0
  163       public int PromptToOverwrite;   //1 = Prompt To Overwrite Required, Else 0
  164       public int fQuiet;              //2 = No Messages, 1 = Less, 0 = All
  165       public int ncflag;              //1 = Write To Stdout, Else 0
  166       public int ntflag;              //1 = Test Zip File, Else 0
  167       public int nvflag;              //0 = Extract, 1 = List Zip Contents
  168       public int nfflag;              //1 = Extract Only Newer Over Existing, Else 0
  169       public int nzflag;              //1 = Display Zip File Comment, Else 0
  170       public int ndflag;              //1 = Honor Directories, Else 0
  171       public int noflag;              //1 = Overwrite Files, Else 0
  172       public int naflag;              //1 = Convert CR To CRLF, Else 0
  173       public int nZIflag;             //1 = Zip Info Verbose, Else 0
  174       public int B_flag;              //1 = backup existing files
  175       public int C_flag;              //1 = Case Insensitivity, 0 = Case Sensitivity
  176       public int D_flag;              //controls restoration of timestamps
  177                                       //0 = restore all timestamps (default)
  178                                       //1 = skip restoration of timestamps for folders
  179                                       //    created on behalf of directory entries in the
  180                                       //    Zip archive
  181                                       //2 = no restoration of timestamps; extracted files
  182                                       //    and dirs get stamped with current time */
  183       public int U_flag;              // controls UTF-8 filename coding support
  184                                       //0 = automatic UTF-8 translation enabled (default)
  185                                       //1 = recognize UTF-8 coded names, but all non-ASCII
  186                                       //    characters are "escaped" into "#Uxxxx"
  187                                       //2 = UTF-8 support is disabled, filename handling
  188                                       //    works exactly as in previous UnZip versions */
  189       public int fPrivilege;          //1 = ACL, 2 = Privileges
  190       public string Zip;              //The Zip Filename To Extract Files
  191       public string ExtractDir;       //The Extraction Directory, NULL If Extracting To Current Dir
  192     }
  193 
  194     //UNZIP32.DLL Userfunctions Structure
  195     [ StructLayout( LayoutKind.Sequential )]
  196     protected struct USERFUNCTION
  197     {
  198       public UZDLLPrintCallback UZDLLPrnt;              //Print function callback
  199       public int UZDLLSND;                              //Not supported
  200       public UZDLLReplaceCallback UZDLLREPLACE;         //Replace function callback
  201       public UZDLLPasswordCallback UZDLLPASSWORD;       //Password function callback
  202       // 64-bit versions
  203       public UZReceiveDLLMessageCallback UZDLLMESSAGE;  //Receive message callback
  204       public UZDLLServiceCallback UZDLLSERVICE;         //Service callback
  205       // 32-bit versions (not used/needed here)
  206       public UZReceiveDLLMsgCBck_32 UZDLLMESSAGE_I32;   //Receive message callback
  207       public UZDLLServiceCBck_32 UZDLLSERVICE_I32;      //Service callback
  208       public ulong TotalSizeComp;                       //Total Size Of Zip Archive
  209       public ulong TotalSize;                           //Total Size Of All Files In Archive
  210       public ulong NumMembers;                          //Total Number Of All Files In The Archive
  211       public uint CompFactor;                           //Compression Factor
  212       public short cchComment;                          //Flag If Archive Has A Comment!
  213     }
  214 
  215     #endregion
  216 
  217     #region DLL Function Declares
  218 
  219     //NOTE:
  220     //This Assumes UNZIP32.DLL Is In Your \Windows\System Directory!
  221     [DllImport("unzip32.dll", SetLastError=true)]
  222     private static extern int Wiz_SingleEntryUnzip (int ifnc, string [] ifnv, int xfnc, string [] xfnv,
  223       ref DCLIST dcl, ref USERFUNCTION Userf);
  224 
  225 
  226     #endregion
  227 
  228     #region Properties
  229 
  230     public string Password
  231     {
  232       get {return m_Password;}
  233       set {m_Password = value;}
  234     }
  235 
  236     public string Comment
  237     {
  238       get {return m_Comment;}
  239       set {m_Comment = value;}
  240     }
  241 
  242     public ExtractOnlyNewerEnum ExtractOnlyNewer
  243     {
  244       get {return m_ExtractOnlyNewer;}
  245       set {m_ExtractOnlyNewer = value;}
  246     }
  247 
  248     public SpaceToUnderScoreEnum SpaceToUnderScore
  249     {
  250       get {return m_SpaceToUnderScore;}
  251       set {m_SpaceToUnderScore = value;}
  252     }
  253 
  254     public PromptToOverWriteEnum PromptToOverWrite
  255     {
  256       get {return m_PromptToOverWrite;}
  257       set {m_PromptToOverWrite = value;}
  258     }
  259 
  260     public QuietEnum Quiet
  261     {
  262       get {return m_Quiet;}
  263       set {m_Quiet = value;}
  264     }
  265 
  266     public WriteStdOutEnum WriteStdOut
  267     {
  268       get {return m_WriteStdOut;}
  269       set {m_WriteStdOut = value;}
  270     }
  271 
  272     public TestZipEnum TestZip
  273     {
  274       get {return m_TestZip;}
  275       set {m_TestZip = value;}
  276     }
  277 
  278     public ExtractOrListEnum ExtractOrList
  279     {
  280       get {return m_ExtractOrList;}
  281       set {m_ExtractOrList = value;}
  282     }
  283 
  284     public FreshenExistingEnum FreshenExisting
  285     {
  286       get {return m_FreshenExisting;}
  287       set {m_FreshenExisting = value;}
  288     }
  289 
  290     public DisplayCommentEnum DisplayComment
  291     {
  292       get {return m_DisplayComment;}
  293       set {m_DisplayComment = value;}
  294     }
  295 
  296     public HonorDirectoriesEnum HonorDirectories
  297     {
  298       get {return m_HonorDirectories;}
  299       set {m_HonorDirectories = value;}
  300     }
  301 
  302     public OverWriteFilesEnum OverWriteFiles
  303     {
  304       get {return m_OverWriteFiles;}
  305       set {m_OverWriteFiles = value;}
  306     }
  307 
  308     public ConvertCR_CRLFEnum ConvertCR_CRLF
  309     {
  310       get {return m_ConvertCR_CRLF;}
  311       set {m_ConvertCR_CRLF = value;}
  312     }
  313 
  314     public VerboseZIEnum VerboseZI
  315     {
  316       get {return m_VerboseZI;}
  317       set {m_VerboseZI = value;}
  318     }
  319 
  320     public UnixFileBackupEnum UnixFileBackup
  321     {
  322       get { return m_UnixFileBackup; }
  323       set { m_UnixFileBackup = value; }
  324     }
  325 
  326     public CaseSensitivityEnum CaseSensitivity
  327     {
  328       get {return m_CaseSensitivity;}
  329       set {m_CaseSensitivity = value;}
  330     }
  331 
  332     public RestoreTimeStampsEnum RestoreTimeStamps
  333     {
  334       get { return m_RestoreTimeStamps; }
  335       set { m_RestoreTimeStamps = value; }
  336     }
  337 
  338     public UTF8NameTranslationEnum UTF8NameTranslation
  339     {
  340       get { return m_UTF8NameTranslation; }
  341       set { m_UTF8NameTranslation = value; }
  342     }
  343 
  344     public PrivilegeEnum Privilege
  345     {
  346       get {return m_Privilege;}
  347       set {m_Privilege = value;}
  348     }
  349 
  350     public string ZipFileName
  351     {
  352       get {return m_ZipFileName;}
  353       set {m_ZipFileName = value;}
  354     }
  355 
  356     public string ExtractDirectory
  357     {
  358       get {return m_ExtractionDirectory;}
  359       set {m_ExtractionDirectory = value;}
  360     }
  361 
  362     public string [] FilesToUnzip
  363     {
  364       get {return m_FilesToUnzip;}
  365       set {m_FilesToUnzip = value;}
  366     }
  367 
  368     public string [] FilesToExclude
  369     {
  370       get {return m_FilesToExclude;}
  371       set {m_FilesToExclude = value;}
  372     }
  373 
  374     #endregion
  375 
  376     #region UnZip DLL Delegates
  377 
  378     //Callback For UNZIP32.DLL - Receive Message Function
  379     protected delegate void UZReceiveDLLMessageCallback (ulong ucsize, ulong csiz,
  380                                 ushort cfactor, ushort mo,
  381                                 ushort dy, ushort yr, ushort hh, ushort mm, byte c,
  382                                 [MarshalAs(UnmanagedType.LPStr)]String fname,
  383                                 [MarshalAs(UnmanagedType.LPStr)]String meth,
  384                                 uint crc, sbyte fCrypt);
  385 
  386     //Callback For UNZIP32.DLL - Receive Message Function (no-Int64 variant, not used here)
  387     protected delegate void UZReceiveDLLMsgCBck_32(uint ucsize_lo, uint ucsize_hi, uint csiz_lo, uint csiz_hi,
  388                                 ushort cfactor, ushort mo,
  389                                 ushort dy, ushort yr, ushort hh, ushort mm, byte c,
  390                                 [MarshalAs(UnmanagedType.LPStr)]String fname,
  391                                 [MarshalAs(UnmanagedType.LPStr)]String meth,
  392                                 uint crc, sbyte fCrypt);
  393 
  394     //Callback For UNZIP32.DLL - Print Message Function
  395     protected delegate int UZDLLPrintCallback ([MarshalAs(UnmanagedType.LPStr)]String fname, uint x);
  396 
  397     //Callback For UNZIP32.DLL - DLL Service Function
  398     protected delegate int UZDLLServiceCallback([MarshalAs(UnmanagedType.LPStr)]String fname,
  399                                                 ulong ucsize);
  400 
  401     //Callback For UNZIP32.DLL - DLL Service Function (no-Int64 variant, not used here)
  402     protected delegate int UZDLLServiceCBck_32([MarshalAs(UnmanagedType.LPStr)]String fname,
  403                                                uint ucsize_lo, uint ucsize_hi);
  404 
  405     //Callback For UNZIP32.DLL - Password Function
  406     protected delegate int UZDLLPasswordCallback(ref UNZIPCBCh pwd, int bufsize,
  407                                                  [MarshalAs(UnmanagedType.LPStr)]String msg,
  408                                                  [MarshalAs(UnmanagedType.LPStr)]String entryname);
  409 
  410     //Callback For UNZIP32.DLL - Replace Function To Overwrite Files
  411     protected delegate int UZDLLReplaceCallback(ref UNZIPCBCh fname, uint fnbufsiz);
  412 
  413     #endregion
  414 
  415     #region Events
  416 
  417     public event UnZipDLLPrintMessageEventHandler ReceivePrintMessage;
  418     public event UnZipDLLServiceMessageEventHandler ReceiveServiceMessage;
  419 
  420     #endregion
  421 
  422     #region Protected Functions
  423 
  424     protected virtual void OnReceivePrintMessage (UnZipDLLPrintMessageEventArgs e)
  425     {
  426       if (ReceivePrintMessage != null)
  427       {
  428         ReceivePrintMessage(this, e);
  429       }
  430     }
  431 
  432     protected virtual void OnReceiveServiceMessage (UnZipDLLServiceMessageEventArgs e)
  433     {
  434       if (ReceiveServiceMessage != null)
  435       {
  436         ReceiveServiceMessage(this, e);
  437       }
  438     }
  439 
  440     #endregion
  441 
  442     #region CallBack Functions
  443 
  444     //This function is called when the DCLIST structure's nvflag is ExtractListEnum.ListContents.
  445     //It is used to list the zip file contents
  446     protected void UZReceiveDLLMessage (ulong ucsize, ulong csiz, ushort cfactor, ushort mo,
  447                               ushort dy, ushort yr, ushort hh, ushort mm, byte c,
  448                               [MarshalAs(UnmanagedType.LPStr)]String fname,
  449                               [MarshalAs(UnmanagedType.LPStr)]String meth,
  450                               uint crc, sbyte fCrypt)
  451     {
  452       //Add up the size of each file in the zip file
  453       m_ZipFileSize += ucsize;
  454       m_ZipFileCount ++;
  455 
  456       //NOTE:
  457       //Build out the ZipFileEntry collection
  458       //You can do additional formatting for the month, day, and year properties
  459       ZipFileEntry zfe = new ZipFileEntry();
  460       zfe.FileName = Path.GetFileName(fname);
  461       zfe.FilePath = Path.GetDirectoryName(fname);
  462       zfe.IsFolder = (zfe.FileName.Length == 0 ? true : false);
  463       zfe.FileSize = unchecked(ucsize);
  464       zfe.FileMonth = mo;
  465       zfe.FileDay = dy;
  466       zfe.FileYear = yr;
  467       zfe.FileHour = hh;
  468       zfe.FileMinute = mm;
  469       zfe.CompressedSize = unchecked(csiz);
  470       zfe.CompressionFactor = cfactor;
  471       zfe.CompressionMethShort = meth;
  472 
  473       m_ZipFileEntries.Add(zfe);
  474 
  475     }
  476 
  477     protected int UZDLLPrint([MarshalAs(UnmanagedType.LPStr)]String msg, uint x)
  478     {
  479       UnZipDLLPrintMessageEventArgs e =
  480           new UnZipDLLPrintMessageEventArgs(msg.Substring(0, Math.Min(unchecked((int)x),
  481                                                                       msg.Length)));
  482       OnReceivePrintMessage(e);
  483 
  484       return 0;
  485     }
  486 
  487     /*
  488     DLLSERVICE *ServCallBk  = Callback function designed to be used for
  489                 allowing the application to process Windows messages,
  490                 or canceling the operation, as well as giving the
  491                 option of a progress indicator. If this function
  492                 returns a non-zero value, then it will terminate
  493                 what it is doing. It provides the application with
  494                 the name of the name of the archive member it has
  495                 just processed, as well as it's original size.
  496 
  497     fname.ch = the name of the file being zipped
  498     ucsize = the size of the file being zipped
  499 
  500      * */
  501     protected int UZDLLService([MarshalAs(UnmanagedType.LPStr)]String fname,
  502                                ulong ucsize)
  503     {
  504       //Raise this event
  505       UnZipDLLServiceMessageEventArgs e =
  506           new UnZipDLLServiceMessageEventArgs(m_ZipFileSize, fname, unchecked(ucsize));
  507       OnReceiveServiceMessage (e);
  508 
  509       return m_Stop;
  510     }
  511 
  512     protected int UZDLLPassword(ref UNZIPCBCh pwd, int bufsize,
  513                         [MarshalAs(UnmanagedType.LPStr)]String msg,
  514                         [MarshalAs(UnmanagedType.LPStr)]String entryname)
  515     {
  516       if (m_Password == null | m_Password == string.Empty) return -1;
  517 
  518       if (m_Password.Length >= bufsize)
  519       {
  520         MessageBox.Show("Length of supplied password exceeds available pw buffer size "
  521                     + bufsize.ToString() + "!", "Password Error",
  522                     MessageBoxButtons.OK, MessageBoxIcon.Error);
  523         return 5;  // IZ_PW_ERROR
  524       }
  525 
  526       //clear the byte array
  527       for (int i = 0; i < bufsize; i ++)
  528         pwd.ch[i] = 0;
  529 
  530       m_EncodingANSI.GetBytes(m_Password, 0, m_Password.Length, pwd.ch, 0);
  531 
  532       return 0;
  533     }
  534 
  535     protected int UZDLLReplace(ref UNZIPCBCh fname, uint fnbufsiz)
  536     {
  537       ReplaceFileOptionsEnum ReplaceFileOption = ReplaceFileOptionsEnum.ReplaceNo; //Default
  538       string s = string.Empty;
  539       int i = 0;
  540 
  541       if (fnbufsiz > fname.ch.Length) fnbufsiz = (uint)fname.ch.Length;
  542       for (i = 0; i < fnbufsiz; i++)
  543         if (fname.ch[i] == 0) break;
  544       s = m_EncodingANSI.GetString(fname.ch, 0, i);
  545 
  546       DialogResult rslt = MessageBox.Show("Overwrite [" + s + "]?  Click Cancel to skip all.",
  547                                   "Overwrite Confirmation", MessageBoxButtons.YesNoCancel,
  548                                   MessageBoxIcon.Question);
  549       switch (rslt)
  550       {
  551         case DialogResult.No:
  552           ReplaceFileOption = ReplaceFileOptionsEnum.ReplaceNo;
  553           break;
  554         case DialogResult.Yes:
  555           ReplaceFileOption = ReplaceFileOptionsEnum.ReplaceYes;
  556           break;
  557         case DialogResult.Cancel:
  558           ReplaceFileOption = ReplaceFileOptionsEnum.ReplaceNone;
  559           break;
  560       }
  561       return ConvertEnumToInt(ReplaceFileOption);
  562     }
  563 
  564     #endregion
  565 
  566     #region Public Functions
  567 
  568     public int UnZipFiles ()
  569     {
  570       int ret = -1;
  571 
  572       //check to see if there is enough information to proceed.
  573       //Exceptions can be thrown if required data is not passed in
  574       if (m_ZipFileName == string.Empty) return -1;
  575       if (m_ExtractionDirectory == string.Empty) return -1;
  576 
  577       //The zip file size, in bytes, is stored in the m_ZipFileSize variable.
  578       //m_ZipFileCount is the number of files in the zip.  This information
  579       //is useful for some sort of progress information during unzipping.
  580       if (!GetZipFileSizeAndCount()) return ret;
  581 
  582       DCLIST dclist = new DCLIST();
  583       dclist.StructVersID = uz_dcl_StructVer;   // Current version of this structure
  584       dclist.ExtractOnlyNewer = ConvertEnumToInt(m_ExtractOnlyNewer);
  585       dclist.SpaceToUnderscore = ConvertEnumToInt(m_SpaceToUnderScore);
  586       dclist.PromptToOverwrite = ConvertEnumToInt(m_PromptToOverWrite);
  587       dclist.fQuiet = ConvertEnumToInt(m_Quiet);
  588       dclist.ncflag = ConvertEnumToInt(m_WriteStdOut);
  589       dclist.ntflag = ConvertEnumToInt (m_TestZip);
  590       dclist.nvflag = ConvertEnumToInt(m_ExtractOrList);
  591       dclist.nfflag = ConvertEnumToInt(m_FreshenExisting);
  592       dclist.nzflag = ConvertEnumToInt(m_DisplayComment);
  593       dclist.ndflag = ConvertEnumToInt(m_HonorDirectories);
  594       dclist.noflag = ConvertEnumToInt(m_OverWriteFiles);
  595       dclist.naflag = ConvertEnumToInt(m_ConvertCR_CRLF);
  596       dclist.nZIflag = ConvertEnumToInt(m_VerboseZI);
  597       dclist.B_flag = ConvertEnumToInt(m_UnixFileBackup);
  598       dclist.C_flag = ConvertEnumToInt(m_CaseSensitivity);
  599       dclist.D_flag = ConvertEnumToInt(m_RestoreTimeStamps);
  600       dclist.U_flag = ConvertEnumToInt(m_UTF8NameTranslation);
  601       dclist.fPrivilege = ConvertEnumToInt(m_Privilege);
  602       dclist.Zip = m_ZipFileName;
  603       dclist.ExtractDir = m_ExtractionDirectory;
  604 
  605       USERFUNCTION uf = PrepareUserFunctionCallbackStructure();
  606 
  607       try
  608       {
  609         ret = Wiz_SingleEntryUnzip(m_FilesToUnzip.Length, m_FilesToUnzip, m_FilesToExclude.Length,
  610           m_FilesToExclude, ref dclist, ref uf);
  611       }
  612       catch (Exception e)
  613       {
  614         MessageBox.Show (e.ToString() + Environment.NewLine +
  615                          "Last Win32ErrorCode: " + Marshal.GetLastWin32Error());
  616         //You can check the meaning of return codes here:
  617         //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes__0-499_.asp
  618       }
  619 
  620       return ret;
  621     }
  622 
  623     public bool GetZipFileSizeAndCount(ref ulong size, ref ulong fileCount)
  624     {
  625       if (!GetZipFileSizeAndCount()) return false;
  626       size = m_ZipFileSize;
  627       fileCount = m_ZipFileCount;
  628       return true;
  629     }
  630 
  631     public ZipFileEntries GetZipFileContents ()
  632     {
  633       int ret = 0;
  634 
  635       DCLIST dclist = new DCLIST();
  636       dclist.StructVersID = uz_dcl_StructVer;
  637       dclist.nvflag = ConvertEnumToInt(ExtractOrListEnum.ListContents);
  638       dclist.Zip = m_ZipFileName;
  639 
  640       USERFUNCTION uf = PrepareUserFunctionCallbackStructure();
  641 
  642       m_ZipFileSize = 0;
  643       m_ZipFileCount = 0;
  644       m_ZipFileEntries.Clear();
  645 
  646       //This call will fill the m_ZipFileEntries collection because when the nvflag = ExtractListEnum.ListContents
  647       //the UZReceiveDLLMessage callback function is called
  648       try
  649       {
  650         ret = Wiz_SingleEntryUnzip(m_FilesToUnzip.Length, m_FilesToUnzip, m_FilesToExclude.Length,
  651           m_FilesToExclude, ref dclist, ref uf);
  652       }
  653       catch(Exception e)
  654       {
  655         MessageBox.Show (e.ToString() + Environment.NewLine +
  656                          "Last Win32ErrorCode: " + Marshal.GetLastWin32Error());
  657         //You can check the meaning of return codes here:
  658         //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes__0-499_.asp
  659       }
  660 
  661       return m_ZipFileEntries;
  662     }
  663 
  664     public string GetZipFileComment()
  665     {
  666       //WORK AROUND:
  667       //This method provides a work around to setting the nzflag of the DCLIST structure = 1, which instructs
  668       //the dll to extract the zip file comment.  See the KNOWN ISSUES region at the beginning of this code
  669       //sample.
  670 
  671       //NOTE:
  672       //Explanation of Big Endian and Little Endian Architecture
  673       //http://support.microsoft.com/default.aspx?scid=kb;en-us;102025
  674       //Bytes in the stream are in Big Endian format.  We have to read the bytes and
  675       //convert to Little Endian format.  That's what the GetLittleEndianByteOrder function
  676       //does.
  677 
  678       const int CENTRALRECORDENDSIGNATURE = 0x06054b50;
  679       const int CENTRALRECORDENDSIZE = 22;
  680 
  681       string comment = string.Empty;
  682       Encoding ae = Encoding.Default;
  683 
  684       if (m_ZipFileName == null | m_ZipFileName == string.Empty) return string.Empty;
  685 
  686       try
  687       {
  688         FileStream fs = File.OpenRead(m_ZipFileName);
  689         long pos = fs.Length - CENTRALRECORDENDSIZE;
  690 
  691         while (GetLittleEndianByteOrder(fs,4) != CENTRALRECORDENDSIGNATURE)
  692           fs.Seek(pos--, SeekOrigin.Begin);
  693 
  694 
  695         int diskNumber = GetLittleEndianByteOrder(fs,2);              /* number of this disk */
  696         int startingDiskNum = GetLittleEndianByteOrder(fs,2);         /* number of the starting disk */
  697         int entriesOnrThisDisk = GetLittleEndianByteOrder(fs,2);      /* entries on this disk */
  698         int totalEntries = GetLittleEndianByteOrder(fs,2);            /* total number of entries */
  699         int centralDirectoryTotalSize = GetLittleEndianByteOrder(fs,4); /* size of entire central directory */
  700         int offsetOfCentralDirectory = GetLittleEndianByteOrder(fs,4);  /* offset of central on starting disk */
  701         //This is what we really want here
  702         int commentSize = GetLittleEndianByteOrder(fs,2);             /* length of zip file comment */
  703 
  704 
  705         byte[] zipFileComment = new byte[commentSize];
  706         fs.Read(zipFileComment, 0, zipFileComment.Length);
  707 
  708         comment =  ae.GetString(zipFileComment, 0, zipFileComment.Length);
  709         fs.Close();
  710       }
  711       catch (Exception e)
  712       {
  713         throw new Exception(e.Message);
  714       }
  715       return comment;
  716     }
  717 
  718     public void Stop ()
  719     {
  720       //m_Stop gets returned from the UZDLLService callback.
  721       //A value of 1 means abort processing.
  722       m_Stop = 1;
  723     }
  724 
  725     #endregion
  726 
  727     #region Private Functions
  728 
  729     private int ConvertEnumToInt (System.Enum obj)
  730     {
  731       return Convert.ToInt32(obj);
  732     }
  733 
  734     private bool GetZipFileSizeAndCount()
  735     {
  736       int ret = 0;
  737 
  738       DCLIST dclist = new DCLIST();
  739       dclist.StructVersID = uz_dcl_StructVer;   // Current version of this structure
  740       dclist.nvflag = ConvertEnumToInt(ExtractOrListEnum.ListContents);
  741       dclist.Zip = m_ZipFileName;
  742       dclist.ExtractDir = m_ExtractionDirectory;
  743 
  744       USERFUNCTION uf = PrepareUserFunctionCallbackStructure();
  745 
  746       //Reset these variables
  747       m_ZipFileSize = 0;
  748       m_ZipFileCount = 0;
  749 
  750       ret = Wiz_SingleEntryUnzip(m_FilesToUnzip.Length, m_FilesToUnzip, m_FilesToExclude.Length,
  751                                  m_FilesToExclude, ref dclist, ref uf);
  752 
  753       return (ret == 0);
  754     }
  755 
  756 
  757     private USERFUNCTION PrepareUserFunctionCallbackStructure()
  758     {
  759       USERFUNCTION uf = new USERFUNCTION();
  760       uf.UZDLLPrnt = new UZDLLPrintCallback(UZDLLPrint);
  761       uf.UZDLLSND = 0; //Not supported
  762       uf.UZDLLREPLACE = new UZDLLReplaceCallback(UZDLLReplace);
  763       uf.UZDLLPASSWORD = new UZDLLPasswordCallback(UZDLLPassword);
  764       uf.UZDLLMESSAGE = new UZReceiveDLLMessageCallback(UZReceiveDLLMessage);
  765       uf.UZDLLSERVICE = new UZDLLServiceCallback(UZDLLService);
  766       uf.UZDLLMESSAGE_I32 = null; // not used
  767       uf.UZDLLSERVICE_I32 = null; // not used
  768 
  769       return uf;
  770     }
  771 
  772     private int GetLittleEndianByteOrder(FileStream fs, int len)
  773     {
  774       int result = 0;
  775       int n = 0;
  776       int [] byteArr = new int[len];
  777 
  778       //Pull the bytes from the stream
  779       for(n=0;n<len;n++)
  780         byteArr[n] = fs.ReadByte();
  781 
  782       //Left shift the bytes to get a resulting number in little endian format
  783       for(n=0;n<byteArr.Length;n++)
  784         result += (byteArr[n] << (n*8));
  785 
  786       return result;
  787     }
  788 
  789     #endregion
  790   }
  791 }