"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 }