public void Dispose() { if (this.archiveHandle != IntPtr.Zero) { Unrar.RARCloseArchive(this.archiveHandle); this.archiveHandle = IntPtr.Zero; } }
private void Extract(string destinationPath, string destinationName) { int result = Unrar.RARProcessFile(this.archiveHandle, ( int )Operation.Extract, destinationPath, destinationName); // Check result if (result != 0) { ProcessFileError(result); } }
/// <summary> /// Tests the ability to extract the current file without saving extracted data to disk /// </summary> /// <returns></returns> public void Test() { int result = Unrar.RARProcessFile(this.archiveHandle, ( int )Operation.Test, string.Empty, string.Empty); // Check result if (result != 0) { ProcessFileError(result); } }
/// <summary> /// Close the currently open archive /// </summary> /// <returns></returns> public void Close() { // Exit without exception if no archive is open if (this.archiveHandle == IntPtr.Zero) { return; } // Close archive int result = Unrar.RARCloseArchive(this.archiveHandle); // Check result if (result != 0) { ProcessFileError(result); } else { this.archiveHandle = IntPtr.Zero; } }
private void ExtractFiles() { if (_needsPatching) { DirectoryInfo patchFolder = new DirectoryInfo(_patchFolder); FileInfo[] zipFiles = patchFolder.GetFiles("*.zip"); FileInfo[] rarFiles = patchFolder.GetFiles("*.rar"); for (int i = 0; i < zipFiles.Length; i++) { ZipInputStream s = null; FileStream streamWriter = null; bool fail = false; try { OnStatusChange(null, new StatusChangeEventArgs("Extracting " + zipFiles[i].Name + "...")); using (s = new ZipInputStream(File.OpenRead(zipFiles[i].FullName))) { ZipEntry entry; while ((entry = s.GetNextEntry()) != null) { string fileName = Path.GetFileName(entry.Name); if (fileName != String.Empty) { if (!File.Exists(Path.Combine(_patchFolder, fileName)) || (entry.Size != new FileInfo(Path.Combine(_patchFolder, fileName)).Length)) { using (streamWriter = File.Create(Path.Combine(_patchFolder, entry.Name))) { int size = 2048; byte[] data = new byte[2048]; while (true) { size = s.Read(data, 0, data.Length); if (size > 0) { streamWriter.Write(data, 0, size); } else { break; } } } } } } } } catch (Exception e) { MessageBox.Show("An error occured while trying to extract " + zipFiles[i].Name + ". This patch will not be applied and you should inform the server admin about this issue", "Extraction Error"); fail = true; } finally { if (s != null) { s.Close(); } if (streamWriter != null) { streamWriter.Close(); } if (fail) { File.Delete(zipFiles[i].FullName); } } } for (int i = 0; i < rarFiles.Length; i++) { Unrar rar = null; bool fail = false; try { OnStatusChange(null, new StatusChangeEventArgs("Extracting " + rarFiles[i].Name + "...")); rar = new Unrar(rarFiles[i].FullName); rar.DestinationPath = _patchFolder; rar.ExtractionProgress += new ExtractionProgressHandler(rar_ExtractionProgress); rar.Open(); while (rar.ReadHeader()) { if (!File.Exists(Path.Combine(_patchFolder, rar.CurrentFile.FileName)) || new FileInfo(Path.Combine(_patchFolder, rar.CurrentFile.FileName)).Length != rar.CurrentFile.UnpackedSize) { rar.Extract(); } } rar.Close(); } catch (Exception e) { MessageBox.Show("While trying to extract " + rarFiles[i].Name + " the following Exception was thrown.\n\n" + e.Message + "\n\nThis patch will not be applied and you should inform the server admin about this issue", "Extraction Error"); fail = true; } finally { if (rar != null) { rar.Close(); } if (fail) { File.Delete(rarFiles[i].FullName); } } } ApplyPatches(patchFolder); } else if (!CheckFileHash()) { OnStatusChange(null, new StatusChangeEventArgs("Hash check failed, re-applying patches... ")); _needsPatching = true; ExtractFiles(); } else { Invoke((MethodInvoker) delegate { Close(); }); } }
private void ExtractFiles() { if (_needsPatching) { DirectoryInfo patchFolder = new DirectoryInfo(_patchFolder); FileInfo[] zipFiles = patchFolder.GetFiles("*.zip"); FileInfo[] rarFiles = patchFolder.GetFiles("*.rar"); for (int i = 0; i < zipFiles.Length; i++) { ZipInputStream s = null; FileStream streamWriter = null; bool fail = false; try { OnStatusChange(null, new StatusChangeEventArgs("Extracting " + zipFiles[i].Name + "...")); using (s = new ZipInputStream(File.OpenRead(zipFiles[i].FullName))) { ZipEntry entry; while ((entry = s.GetNextEntry()) != null) { string fileName = Path.GetFileName(entry.Name); if (fileName != String.Empty) { if (!File.Exists(Path.Combine(_patchFolder, fileName)) || (entry.Size != new FileInfo(Path.Combine(_patchFolder, fileName)).Length)) using (streamWriter = File.Create(Path.Combine(_patchFolder, entry.Name))) { int size = 2048; byte[] data = new byte[2048]; while (true) { size = s.Read(data, 0, data.Length); if (size > 0) { streamWriter.Write(data, 0, size); } else { break; } } } } } } } catch (Exception e) { MessageBox.Show("An error occured while trying to extract " + zipFiles[i].Name + ". This patch will not be applied and you should inform the server admin about this issue", "Extraction Error"); fail = true; } finally { if (s != null) s.Close(); if (streamWriter != null) streamWriter.Close(); if (fail) File.Delete(zipFiles[i].FullName); } } for (int i = 0; i < rarFiles.Length; i++) { Unrar rar = null; bool fail = false; try { OnStatusChange(null, new StatusChangeEventArgs("Extracting " + rarFiles[i].Name + "...")); rar = new Unrar(rarFiles[i].FullName); rar.DestinationPath = _patchFolder; rar.ExtractionProgress += new ExtractionProgressHandler(rar_ExtractionProgress); rar.Open(); while (rar.ReadHeader()) { if (!File.Exists(Path.Combine(_patchFolder, rar.CurrentFile.FileName)) || new FileInfo(Path.Combine(_patchFolder, rar.CurrentFile.FileName)).Length != rar.CurrentFile.UnpackedSize) rar.Extract(); } rar.Close(); } catch (Exception e) { MessageBox.Show("While trying to extract " + rarFiles[i].Name + " the following Exception was thrown.\n\n" + e.Message + "\n\nThis patch will not be applied and you should inform the server admin about this issue", "Extraction Error"); fail = true; } finally { if (rar != null) rar.Close(); if (fail) File.Delete(rarFiles[i].FullName); } } ApplyPatches(patchFolder); } else if (!CheckFileHash()) { OnStatusChange(null, new StatusChangeEventArgs("Hash check failed, re-applying patches... ")); _needsPatching = true; ExtractFiles(); } else Invoke((MethodInvoker)delegate { Close(); }); }
/// <summary> /// Reads the next archive header and populates CurrentFile property data /// </summary> /// <returns></returns> public bool ReadHeader() { // Throw exception if archive not open if (this.archiveHandle == IntPtr.Zero) { throw new IOException("Archive is not open."); } // Initialize header struct this.header = new RARHeaderDataEx(); header.Initialize(); // Read next entry currentFile = null; int result = Unrar.RARReadHeaderEx(this.archiveHandle, ref this.header); // Check for error or end of archive if (( RarError )result == RarError.EndOfArchive) { return(false); } else if (( RarError )result == RarError.BadData) { throw new IOException("Archive data is corrupt."); } // Determine if new file if (((header.Flags & 0x01) != 0) && currentFile != null) { currentFile.ContinuedFromPrevious = true; } else { // New file, prepare header currentFile = new RARFileInfo(); currentFile.FileName = header.FileNameW.ToString(); if ((header.Flags & 0x02) != 0) { currentFile.ContinuedOnNext = true; } if (header.PackSizeHigh != 0) { currentFile.PackedSize = (header.PackSizeHigh * 0x100000000) + header.PackSize; } else { currentFile.PackedSize = header.PackSize; } if (header.UnpSizeHigh != 0) { currentFile.UnpackedSize = (header.UnpSizeHigh * 0x100000000) + header.UnpSize; } else { currentFile.UnpackedSize = header.UnpSize; } currentFile.HostOS = ( int )header.HostOS; currentFile.FileCRC = header.FileCRC; currentFile.FileTime = FromMSDOSTime(header.FileTime); currentFile.VersionToUnpack = ( int )header.UnpVer; currentFile.Method = ( int )header.Method; currentFile.FileAttributes = ( int )header.FileAttr; currentFile.BytesExtracted = 0; if ((header.Flags & 0xE0) == 0xE0) { currentFile.IsDirectory = true; } this.OnNewFile(); } // Return success return(true); }
/// <summary> /// Opens specified archive using the specified mode. /// </summary> /// <param name="archivePathName">Path of archive to open</param> /// <param name="openMode">Mode in which to open archive</param> public void Open(string archivePathName, OpenMode openMode) { IntPtr handle = IntPtr.Zero; // Close any previously open archives if (this.archiveHandle != IntPtr.Zero) { this.Close(); } // Prepare extended open archive struct this.ArchivePathName = archivePathName; RAROpenArchiveDataEx openStruct = new RAROpenArchiveDataEx(); openStruct.Initialize(); openStruct.ArcName = this.archivePathName + "\0"; openStruct.ArcNameW = this.archivePathName + "\0"; openStruct.OpenMode = ( uint )openMode; if (this.retrieveComment) { openStruct.CmtBuf = new string(( char )0, 65536 ); openStruct.CmtBufSize = 65536; } else { openStruct.CmtBuf = null; openStruct.CmtBufSize = 0; } // Open archive handle = Unrar.RAROpenArchiveEx(ref openStruct); // Check for success if (openStruct.OpenResult != 0) { switch (( RarError )openStruct.OpenResult) { case RarError.InsufficientMemory: throw new OutOfMemoryException("Insufficient memory to perform operation."); case RarError.BadData: throw new IOException("Archive header broken"); case RarError.BadArchive: throw new IOException("File is not a valid archive."); case RarError.OpenError: throw new IOException("File could not be opened."); } } // Save handle and flags this.archiveHandle = handle; this.archiveFlags = ( ArchiveFlags )openStruct.Flags; // Set callback Unrar.RARSetCallback(this.archiveHandle, this.callback, this.GetHashCode()); // If comment retrieved, save it if (openStruct.CmtState == 1) { this.comment = openStruct.CmtBuf.ToString(); } // If password supplied, set it if (this.password.Length != 0) { Unrar.RARSetPassword(this.archiveHandle, this.password); } // Fire NewVolume event for first volume this.OnNewVolume(this.archivePathName); }