private void Dispose(bool disposing) { if (!_disposed) { // Verify that _entriesProcessed matches _entries.Count // For Xar archives, when no file list is specified in the call IInArchive.Extract(null, uint.MaxValue, ...), // the "[TOC].xml" file is not extracted, so there is an exception for that. Debug.Assert(_entries == null || _extractMode != ExtractMode.ExtractToFile || _exception != null || (_entriesProcessed == _entries.Count - 1 && _archive.Format == ArchiveFormat.Xar) || _entriesProcessed == _entries.Count); if (_extractMode == ExtractMode.ExtractToFile) { SetDirectoryAttributes(); } if (disposing) { // Dispose managed resources if (_stream != null) { _stream.Dispose(); } } _stream = null; _targetStream = null; _entries = null; _directoryEntries = null; _archive = null; // Dispose unmanaged resources _disposed = true; } }
public int SetOperationResult(OperationResult operationResult) { if (_stream != null) { _stream.Dispose(); _stream = null; } if (_lastAskMode == AskMode.Skip) { Debug.Assert(!_entries.ContainsKey(_lastEntryIndex)); return(HRESULT.S_OK); } _entriesProcessed++; _lastEntryIndexSet = false; Debug.Assert(_entriesProcessed <= _entries.Count); if (_lastFileSkipped) { _lastFileSkipped = false; ExistingFileSkippedEventArgs args = new ExistingFileSkippedEventArgs() { CurrentEntry = _entries[_lastEntryIndex], ExistingFilePath = LastExtractedFilePath, EntriesTotal = _entries.Count, EntriesProcessed = _entriesProcessed, }; return(InvokeEventHandler(args, _archive.OnExistingFileSkipped, "SevenZipArchive.ExistingFileSkipped")); } if (_exception != null) { if (_exception is PasswordRequiredException) { _exception = new PasswordRequiredException( string.Format("The file '{0}' is encrypted, and requires a password to be decrypted.", LastEntryFileName), LastEntryFileName, _exception.InnerException); } return(RaiseExtractionOrCheckFailedEvent(_exception)); } int result = HRESULT.S_OK; switch (operationResult) { case OperationResult.OK: if (_extractMode == ExtractMode.ExtractToFile || _extractMode == ExtractMode.ExtractToStream) { if (_extractMode == ExtractMode.ExtractToFile) { SetAttributes(LastExtractedFilePath, _entries[_lastEntryIndex]); } FileExtractedEventArgs args = new FileExtractedEventArgs() { CurrentEntry = _entries[_lastEntryIndex], TargetFilePath = LastExtractedFilePath, EntriesTotal = _entries.Count, EntriesProcessed = _entriesProcessed, }; result = InvokeEventHandler(args, _archive.OnFileExtracted, "SevenZipArchive.FileExtracted"); } else if (_extractMode == ExtractMode.IntegrityCheck) { FileCheckedEventArgs args = new FileCheckedEventArgs() { CurrentEntry = _entries[_lastEntryIndex], EntriesTotal = _entries.Count, EntriesProcessed = _entriesProcessed, }; result = InvokeEventHandler(args, _archive.OnFileChecked, "SevenZipArchive.FileChecked"); } else { result = HRESULT.S_OK; } break; case OperationResult.CRCError: _exception = new BadCrcException(string.Format( "The {0} is corrupted. The CRC check has failed.", (LastEntryFileName != null ? string.Format("file '{0}'", LastEntryFileName) : "archive")), LastEntryFileName); result = RaiseExtractionOrCheckFailedEvent(_exception); break; case OperationResult.DataError: if (LastEntryFileName != null) { _exception = new DataErrorException(string.Format( "The file '{0}' is corrupted. A data error has occured.", LastEntryFileName), LastEntryFileName); if (_isEncrypted) { _exception = new BadPasswordException(string.Format( "Incorrect password specified to decrypt the file '{0}'.", LastEntryFileName), LastEntryFileName, _exception); } } else { _exception = new DataErrorException("The archive is corrupted. A data error has occured."); } result = RaiseExtractionOrCheckFailedEvent(_exception); break; case OperationResult.UnSupportedMethod: _exception = new UnsupportedMethodException("An unsupported method error has occured.", LastEntryFileName); result = RaiseExtractionOrCheckFailedEvent(_exception); break; } return(result); }
public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode) { outStream = null; _lastEntryIndex = index; _lastEntryIndexSet = true; _lastAskMode = askExtractMode; Debug.Assert(_stream == null); if (_stream != null) { _stream.Dispose(); _stream = null; } if (_extractMode == ExtractMode.UnpackedSize) { return(HRESULT.E_ABORT); } else if (askExtractMode != AskMode.Extract) { if (askExtractMode == AskMode.Skip) { Debug.Assert(!_entries.ContainsKey(index)); } return(HRESULT.S_OK); } else if (!_entries.ContainsKey(index)) { Debug.Fail("Unexpected case."); _stream = new OutStreamWrapper(new DummyOutStream()); outStream = _stream; return(HRESULT.S_OK); } Debug.Assert(_archive != null, "_archive was not set correctly. The wrong constructor may have been used."); if (_targetDirectory != null) { // Writing to file system Debug.Assert(_extractMode == ExtractMode.ExtractToFile, "Wrong constructor used."); Debug.Assert(_targetDirectory.IndexOfAny(Path.GetInvalidPathChars()) == -1); string filePath; if (AutoRenamePath(LastEntryFileName, out _lastExtractedFileName)) { filePath = LastExtractedFilePath; } else { Debug.Assert(_exception == null || _exception is PasswordRequiredException); if (!(_exception is PasswordRequiredException)) { _exception = new SevenZipException(string.Format( "The file '{0}' cannot be extracted because the path contains invalid characters or components.", LastEntryFileName)); } _stream = new OutStreamWrapper(new DummyOutStream()); outStream = _stream; return(HRESULT.S_OK); } try { string directory = _entries[index].IsDirectory ? filePath : Path.GetDirectoryName(filePath); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } if (_entries[index].IsDirectory) { Debug.Assert(_directoryEntries != null); _directoryEntries[directory] = _entries[index]; _stream = new OutStreamWrapper(new DummyOutStream()); outStream = _stream; return(HRESULT.S_OK); } else { if (File.Exists(filePath)) { FileExistsEventArgs fileExistsArgs = new FileExistsEventArgs() { Action = ExtractOptionsToFileExistAction(_options), TargetDirectory = _targetDirectory, Entry = _entries[_lastEntryIndex], }; int result = InvokeEventHandler(fileExistsArgs, _archive.OnFileExists, "SevenZipArchive.FileExists"); if (result != HRESULT.S_OK) { return(result); } if (fileExistsArgs.Action == FileExistsAction.Throw) { Debug.Assert(_exception == null || _exception is PasswordRequiredException); if (!(_exception is PasswordRequiredException)) { _exception = new SevenZipException(string.Format( "The file '{0}' cannot be extracted to '{1}' because a file with the same name already exists.", Path.GetFileName(LastExtractedFileName), directory)); } _stream = new OutStreamWrapper(new DummyOutStream()); outStream = _stream; return(HRESULT.S_OK); } else if (fileExistsArgs.Action == FileExistsAction.Skip) { _lastFileSkipped = true; _stream = new OutStreamWrapper(new DummyOutStream()); outStream = _stream; return(HRESULT.S_OK); } } _stream = new OutStreamWrapper(File.Create(filePath)); outStream = _stream; return(HRESULT.S_OK); } } catch (Exception e) { Debug.Assert(_exception == null || _exception is PasswordRequiredException); if (!(_exception is PasswordRequiredException)) { _exception = new SevenZipException(string.Format( "An exception occured while extracting the file '{0}'.", LastEntryFileName), e); } _stream = new OutStreamWrapper(new DummyOutStream()); outStream = _stream; return(HRESULT.S_OK); } } else { // Writing to stream Debug.Assert(_extractMode == ExtractMode.ExtractToStream, "Wrong constructor used."); Debug.Assert(_targetStream != null); _stream = new OutStreamWrapper(_targetStream, false); outStream = _stream; return(HRESULT.S_OK); } }