* contrib/hbziparch/_features.h
* contrib/hbziparch/_platform.h
* contrib/hbziparch/Aes.cpp
* contrib/hbziparch/Aes.h
* contrib/hbziparch/BaseLibCompressor.cpp
* contrib/hbziparch/BaseLibCompressor.h
* contrib/hbziparch/BytesWriter.h
* contrib/hbziparch/Bzip2Compressor.cpp
* contrib/hbziparch/Bzip2Compressor.h
* contrib/hbziparch/DeflateCompressor.cpp
* contrib/hbziparch/DeflateCompressor.h
* contrib/hbziparch/DirEnumerator.cpp
* contrib/hbziparch/DirEnumerator.h
* contrib/hbziparch/FileFilter.cpp
* contrib/hbziparch/FileFilter.h
* contrib/hbziparch/FileInfo.h
* contrib/hbziparch/Hmac.cpp
* contrib/hbziparch/Hmac.h
* contrib/hbziparch/RandomPool.cpp
* contrib/hbziparch/RandomPool.h
* contrib/hbziparch/Sha1.cpp
* contrib/hbziparch/Sha1.h
* contrib/hbziparch/std_mfc.h
* contrib/hbziparch/std_stl.h
* contrib/hbziparch/Wildcard.cpp
* contrib/hbziparch/Wildcard.h
* contrib/hbziparch/ZipAbstractFile.h
* contrib/hbziparch/ZipAesCryptograph.cpp
* contrib/hbziparch/ZipAesCryptograph.h
* contrib/hbziparch/ZipArchive.cpp
* contrib/hbziparch/ZipArchive.h
* contrib/hbziparch/ZipAutoBuffer.cpp
* contrib/hbziparch/ZipAutoBuffer.h
* contrib/hbziparch/ZipBaseException.h
* contrib/hbziparch/ZipCallback.h
* contrib/hbziparch/ZipCallbackProvider.h
* contrib/hbziparch/ZipCentralDir.cpp
* contrib/hbziparch/ZipCentralDir.h
* contrib/hbziparch/ZipCollections.h
* contrib/hbziparch/ZipCollections_mfc.h
* contrib/hbziparch/ZipCollections_stl.h
* contrib/hbziparch/ZipCompatibility.cpp
* contrib/hbziparch/ZipCompatibility.h
* contrib/hbziparch/ZipCompressor.cpp
* contrib/hbziparch/ZipCompressor.h
* contrib/hbziparch/ZipCrc32Cryptograph.cpp
* contrib/hbziparch/ZipCrc32Cryptograph.h
* contrib/hbziparch/ZipCryptograph.cpp
* contrib/hbziparch/ZipCryptograph.h
* contrib/hbziparch/ZipException.cpp
* contrib/hbziparch/ZipException.h
* contrib/hbziparch/ZipExtraData.cpp
* contrib/hbziparch/ZipExtraData.h
* contrib/hbziparch/ZipExtraField.cpp
* contrib/hbziparch/ZipExtraField.h
* contrib/hbziparch/ZipFile.h
* contrib/hbziparch/ZipFile_mfc.cpp
* contrib/hbziparch/ZipFile_mfc.h
* contrib/hbziparch/ZipFile_stl.cpp
* contrib/hbziparch/ZipFile_stl.h
* contrib/hbziparch/ZipFileHeader.cpp
* contrib/hbziparch/ZipFileHeader.h
* contrib/hbziparch/ZipFileMapping.h
* contrib/hbziparch/ZipFileMapping_lnx.h
* contrib/hbziparch/ZipFileMapping_win.h
* contrib/hbziparch/ZipMemFile.cpp
* contrib/hbziparch/ZipMemFile.h
* contrib/hbziparch/ZipMutex.h
* contrib/hbziparch/ZipMutex_lnx.h
* contrib/hbziparch/ZipMutex_win.h
* contrib/hbziparch/ZipPathComponent.h
* contrib/hbziparch/ZipPlatform.h
* contrib/hbziparch/ZipPlatformComm.cpp
* contrib/hbziparch/ZipStorage.cpp
* contrib/hbziparch/ZipStorage.h
* contrib/hbziparch/ZipString.h
* contrib/hbziparch/ZipString_mfc.h
* contrib/hbziparch/ZipString_stl.h
* contrib/hbziparch/ZipStringStoreSettings.h
+ ZipArchive lib update finished.
; Pass 2/2
; Please test.
620 lines
13 KiB
C++
620 lines
13 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// This source file is part of the ZipArchive library source distribution and
|
|
// is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your option) any later version.
|
|
//
|
|
// For the licensing details refer to the License.txt file.
|
|
//
|
|
// Web Site: http://www.artpol-software.com
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* \file ZipStorage.h
|
|
* Includes the CZipStorage class.
|
|
*
|
|
*/
|
|
|
|
#if !defined(ZIPARCHIVE_ZIPSTORAGE_DOT_H)
|
|
#define ZIPARCHIVE_ZIPSTORAGE_DOT_H
|
|
|
|
#if _MSC_VER > 1000
|
|
#pragma once
|
|
#if defined ZIP_HAS_DLL
|
|
#pragma warning (push)
|
|
#pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class
|
|
#endif
|
|
#endif
|
|
|
|
#include "ZipFile.h"
|
|
#include "ZipAutoBuffer.h"
|
|
#include "ZipString.h"
|
|
#include "ZipMemFile.h"
|
|
#include "ZipExport.h"
|
|
#include "ZipCallback.h"
|
|
|
|
|
|
|
|
/**
|
|
Represents the storage layer for an archive.
|
|
*/
|
|
class ZIP_API CZipStorage
|
|
{
|
|
friend class CZipArchive;
|
|
friend class CZipCentralDir;
|
|
public:
|
|
|
|
/**
|
|
The type of the segmentation of the archive.
|
|
|
|
\see
|
|
<a href="kb">0610051553</a>
|
|
\see
|
|
CZipArchive::GetSegmMode
|
|
*/
|
|
enum ZipSegmentationMode
|
|
{
|
|
noSegments, ///< No archive segmentation.
|
|
spannedArchive, ///< A spanned archive.
|
|
splitArchive, ///< A split archive.
|
|
|
|
/**
|
|
The archive segmentation type will be auto-detected.
|
|
If the archive is on the removable device,
|
|
assume a spanned archive, otherwise assume a split archive.
|
|
*/
|
|
suggestedAuto,
|
|
|
|
/**
|
|
If a segmented archive is on a removable device, assume a split archive.
|
|
Normally you create spanned archives on removable devices.
|
|
*/
|
|
suggestedSplit
|
|
};
|
|
|
|
/**
|
|
The direction of seeking operation.
|
|
|
|
\see
|
|
CZipStorage::Seek
|
|
*/
|
|
enum SeekType
|
|
{
|
|
seekFromBeginning, ///< Start seeking from the beginning of a file.
|
|
seekFromEnd, ///< Start seeking from the end of a file.
|
|
/**
|
|
Start seeking from the current position in an archive.
|
|
This value can cause a volume change when a segmented archive is opened for reading.
|
|
*/
|
|
seekCurrent
|
|
};
|
|
CZipStorage();
|
|
virtual ~CZipStorage();
|
|
|
|
void Initialize();
|
|
/**
|
|
Opens a new or existing archive in memory.
|
|
The meaning for the parameters is the same as in the CZipArchive::Open(CZipAbstractFile& , int) method.
|
|
*/
|
|
void Open(CZipAbstractFile& af, int iMode);
|
|
|
|
/**
|
|
Opens or creates an archive.
|
|
|
|
The meaning for the parameters is the same as in the CZipArchive::Open(LPCTSTR, int, ZIP_SIZE_TYPE) method.
|
|
*/
|
|
void Open(LPCTSTR lpszPathName, int iMode, ZIP_SIZE_TYPE uVolumeSize);
|
|
|
|
|
|
/**
|
|
Closes a segmented archive in creation and reopens it as an existing segmented archive (no modifications allowed).
|
|
The archive may also turn out to be a not segmented archive.
|
|
*/
|
|
void FinalizeSegm();
|
|
|
|
|
|
/**
|
|
Called only by CZipCentralDir::Read when opening an existing archive.
|
|
|
|
\param uLastVolume
|
|
The number of the volme the central directory is on.
|
|
|
|
\note Throws exceptions.
|
|
|
|
*/
|
|
void UpdateSegmMode(ZIP_VOLUME_TYPE uLastVolume);
|
|
|
|
/**
|
|
Ensures than in a segmented archive, there is enough free space on the current volume.
|
|
|
|
\param uNeeded
|
|
The size of the required free space in bytes.
|
|
|
|
\return
|
|
The number of free bytes on the current volume.
|
|
|
|
\note
|
|
Throws exceptions.
|
|
*/
|
|
ZIP_SIZE_TYPE AssureFree(ZIP_SIZE_TYPE uNeeded);
|
|
|
|
/**
|
|
Writes a chunk of data to the archive.
|
|
|
|
\param pBuf
|
|
The buffer with data.
|
|
|
|
\param iSize
|
|
The number of bytes to write.
|
|
|
|
\param bAtOnce
|
|
If \c true, the whole chunk must fit in the current volume.
|
|
If there is not enough free space, a volume change is performed.
|
|
|
|
\note
|
|
Throws exceptions.
|
|
*/
|
|
void Write(const void *pBuf, DWORD iSize, bool bAtOnce);
|
|
|
|
/**
|
|
Gets the total size currently occupied by the archive.
|
|
|
|
\return
|
|
The length of the current archive file increased by the number of bytes in the write buffer.
|
|
*/
|
|
ZIP_SIZE_TYPE GetOccupiedSpace() const
|
|
{
|
|
return ZIP_SIZE_TYPE(m_pFile->GetLength() + m_uBytesInWriteBuffer);
|
|
}
|
|
|
|
/**
|
|
The same as the CZipArchive::IsClosed method.
|
|
*/
|
|
bool IsClosed(bool bArchive) const
|
|
{
|
|
if (bArchive)
|
|
return GetCurrentVolume() == ZIP_VOLUME_NUMBER_UNSPECIFIED;
|
|
else
|
|
return !m_pFile || !m_bInMemory && m_pFile->IsClosed();
|
|
}
|
|
|
|
/**
|
|
Reads a chunk of data from the archive.
|
|
|
|
\param pBuf
|
|
The buffer to receive the data.
|
|
|
|
\param iSize
|
|
The number of bytes to read.
|
|
|
|
\param bAtOnce
|
|
If \c true, the specified number of bytes must be read
|
|
from the same volume (no volume change is allowed).
|
|
|
|
\note
|
|
Throws exceptions.
|
|
*/
|
|
DWORD Read(void* pBuf, DWORD iSize, bool bAtOnce);
|
|
|
|
/**
|
|
Gets the position in the file, taking into account the number of bytes in the write buffer
|
|
and the number of bytes before the archive.
|
|
|
|
\return
|
|
The position in the file.
|
|
|
|
\note
|
|
Throws exceptions.
|
|
*/
|
|
ZIP_SIZE_TYPE GetPosition() const
|
|
{
|
|
ZIP_SIZE_TYPE uPos = (ZIP_SIZE_TYPE)(m_pFile->GetPosition()) + m_uBytesInWriteBuffer;
|
|
if (m_uCurrentVolume == 0)
|
|
uPos -= m_uBytesBeforeZip;
|
|
return uPos;
|
|
}
|
|
|
|
|
|
/**
|
|
Flushes the data from the read buffer to the disk.
|
|
|
|
\note
|
|
Throws exceptions.
|
|
*/
|
|
void Flush();
|
|
|
|
|
|
/**
|
|
Forces any data remaining in the file buffer to be written to the disk.
|
|
*/
|
|
void FlushFile()
|
|
{
|
|
if (!m_bInMemory && !IsReadOnly())
|
|
m_pFile->Flush();
|
|
}
|
|
|
|
void FlushBuffers()
|
|
{
|
|
Flush();
|
|
FlushFile();
|
|
}
|
|
|
|
/**
|
|
Changes volumes during writing to a segmented archive.
|
|
|
|
\param uNeeded
|
|
The number of bytes needed in the volume.
|
|
|
|
\note
|
|
Throws exceptions.
|
|
*/
|
|
void NextVolume(ZIP_SIZE_TYPE uNeeded);
|
|
|
|
|
|
/**
|
|
Gets a zero-based number of the current volume.
|
|
*/
|
|
ZIP_VOLUME_TYPE GetCurrentVolume() const {return m_uCurrentVolume;}
|
|
|
|
|
|
/**
|
|
Changes the volume during extract operations.
|
|
|
|
\param uNumber
|
|
A zero-based number of the requested volume.
|
|
*/
|
|
void ChangeVolume(ZIP_VOLUME_TYPE uNumber);
|
|
|
|
/**
|
|
Changes the current volume to the next volume during extract operations.
|
|
*/
|
|
void ChangeVolume()
|
|
{
|
|
ChangeVolume((ZIP_VOLUME_TYPE)(m_uCurrentVolume + 1));
|
|
}
|
|
|
|
/**
|
|
Detects the segmentation mode.
|
|
|
|
\return
|
|
- \c -1 : An existing segmented archive is opened.
|
|
- \c 0 : The archive is not segmented.
|
|
- \c 1 : A segmented archive in creation.
|
|
*/
|
|
int IsSegmented() const
|
|
{
|
|
return m_iSegmMode == noSegments ? 0 : (m_bNewSegm ? 1 : -1);
|
|
}
|
|
|
|
/**
|
|
Checks, if the archive is a split archive.
|
|
|
|
\return
|
|
\c true, if the archive is a split archive; \c false otherwise.
|
|
*/
|
|
bool IsSplit() const
|
|
{
|
|
return m_iSegmMode == splitArchive;
|
|
}
|
|
|
|
/**
|
|
Checks, if the archive is a spanned archive.
|
|
|
|
\return
|
|
\c true, if the archive is a spanned archive; \c false otherwise.
|
|
*/
|
|
bool IsSpanned() const
|
|
{
|
|
return m_iSegmMode == spannedArchive;
|
|
}
|
|
|
|
/**
|
|
The same as the CZipArchive::IsReadOnly method.
|
|
*/
|
|
bool IsReadOnly()
|
|
{
|
|
return m_bReadOnly || IsSegmented() < 0;
|
|
}
|
|
|
|
/**
|
|
Performs the seeking operation on the #m_pFile.
|
|
|
|
\param lOff
|
|
The new position in the file.
|
|
|
|
\param iSeekType
|
|
The direction of the seek operation.
|
|
It can be one of the #SeekType values.
|
|
*/
|
|
ULONGLONG Seek(ULONGLONG lOff, SeekType iSeekType = seekFromBeginning);
|
|
|
|
/**
|
|
Gets the number of free bytes on the current volume.
|
|
|
|
\return
|
|
The number of free bytes on the current volume.
|
|
*/
|
|
ZIP_SIZE_TYPE VolumeLeft() const;
|
|
|
|
/**
|
|
Closes the storage.
|
|
|
|
\param bAfterException
|
|
Set to \c true, if an exception was thrown before.
|
|
|
|
\return
|
|
The file path of the archive.
|
|
|
|
\note
|
|
Throws exceptions.
|
|
*/
|
|
CZipString Close(bool bAfterException);
|
|
|
|
/**
|
|
Represents the physical storage of the current archive segment.
|
|
*/
|
|
CZipAbstractFile* m_pFile;
|
|
|
|
/**
|
|
The signature of the extended header.
|
|
*/
|
|
static char m_gszExtHeaderSignat[];
|
|
|
|
protected:
|
|
|
|
/**
|
|
Returns the file offset after the last data byte in the archive.
|
|
|
|
\return
|
|
The file offset after the last data byte in the archive.
|
|
*/
|
|
ZIP_SIZE_TYPE GetLastDataOffset()
|
|
{
|
|
return (ZIP_SIZE_TYPE)m_pFile->GetLength() - m_uBytesBeforeZip;
|
|
}
|
|
|
|
/**
|
|
Reverse-finds the location of the given signature starting from the current position in file.
|
|
|
|
\param szSignature
|
|
The signature to locate.
|
|
|
|
\param uMaxDepth
|
|
The maximum number of bytes to search for \a szSignature.
|
|
|
|
\return
|
|
The location of the signature.
|
|
|
|
\note
|
|
Throws exceptions.
|
|
*/
|
|
ZIP_FILE_USIZE LocateSignature(char* szSignature, ZIP_SIZE_TYPE uMaxDepth);
|
|
|
|
|
|
/**
|
|
Flushes without writing. Can be used only on not segmented archives.
|
|
*/
|
|
void EmptyWriteBuffer()
|
|
{
|
|
m_uBytesInWriteBuffer = 0;
|
|
}
|
|
|
|
/**
|
|
Opens a physical file.
|
|
|
|
\param lpszName
|
|
The name of the file to open.
|
|
|
|
\param uFlags
|
|
The file open flags.
|
|
|
|
\param bThrow
|
|
If \c true, throw an exception in case of failure.
|
|
|
|
\return
|
|
\c true if successful; \c false otherwise.
|
|
*/
|
|
bool OpenFile(LPCTSTR lpszName, UINT uFlags, bool bThrow = true);
|
|
|
|
/**
|
|
Renames the last segment file in a split archive when finalizing the whole archive.
|
|
|
|
\return
|
|
The name of the last segment.
|
|
*/
|
|
CZipString RenameLastFileInSplitArchive();
|
|
|
|
/**
|
|
Writes data to the internal buffer.
|
|
|
|
\param *pBuf
|
|
The buffer to copy the data from.
|
|
|
|
\param uSize
|
|
The number of bytes to write.
|
|
|
|
\note
|
|
Throws exceptions.
|
|
*/
|
|
void WriteInternalBuffer(const char *pBuf, DWORD uSize);
|
|
|
|
/**
|
|
Gets the free space size on the current removable disk.
|
|
|
|
\return
|
|
The free space in bytes.
|
|
*/
|
|
ZIP_SIZE_TYPE GetFreeVolumeSpace() const;
|
|
|
|
/**
|
|
Notifies the callback object.
|
|
Throws an exception if the callback method returns \c false.
|
|
|
|
\param uNeeded
|
|
The minimum number of free bytes required on the disk.
|
|
|
|
\param iCode
|
|
The code to be passed to the callback method.
|
|
|
|
\param szTemp
|
|
The string to be used as a filename (as an argument
|
|
in the CZipException::Throw method) when an exception must be thrown.
|
|
|
|
\note
|
|
Throws exceptions.
|
|
\see
|
|
CZipArchive::SetSegmCallback
|
|
*/
|
|
void CallCallback(ZIP_SIZE_TYPE uNeeded, int iCode, CZipString szTemp);
|
|
|
|
/**
|
|
Constructs the name of a segment in a split archive.
|
|
|
|
\param bLast
|
|
Set it to \c true, if constructing the last volume name.
|
|
|
|
\return
|
|
The segment name.
|
|
*/
|
|
CZipString GetSplitVolumeName(bool bLast) const;
|
|
|
|
/**
|
|
Changes a file when processing a split archive.
|
|
*/
|
|
CZipString ChangeSplitRead();
|
|
|
|
/**
|
|
Changes a disk when processing a spanned archive.
|
|
*/
|
|
CZipString ChangeSpannedRead();
|
|
|
|
/**
|
|
Gets the free space left in the write buffer.
|
|
|
|
\return
|
|
The free space left in the write buffer in bytes.
|
|
*/
|
|
DWORD GetFreeInBuffer() const {return m_pWriteBuffer.GetSize() - m_uBytesInWriteBuffer;}
|
|
|
|
/**
|
|
The value it holds, depends on the current mode:
|
|
- An opened existing split archive - stores the number of the last volume ( the one with "zip" extension).
|
|
- A split archive in creation - the size of the volume.
|
|
|
|
This method is used only when processing split archives.
|
|
*/
|
|
ZIP_SIZE_TYPE m_uSplitData;
|
|
|
|
/**
|
|
The extension of the last segment.
|
|
*/
|
|
CZipString m_szSplitExtension;
|
|
|
|
/**
|
|
The number of bytes available in the write buffer.
|
|
*/
|
|
DWORD m_uBytesInWriteBuffer;
|
|
|
|
/**
|
|
The value it holds depends on the segmentation mode:
|
|
- A split archive : the total size of the current volume.
|
|
- A spanned archive: the free space on the current volume.
|
|
*/
|
|
ZIP_SIZE_TYPE m_uCurrentVolSize;
|
|
|
|
/**
|
|
The write buffer caching data.
|
|
*/
|
|
CZipAutoBuffer m_pWriteBuffer;
|
|
|
|
/**
|
|
Stores the number of bytes that have been written physically to the current segment.
|
|
Used only when processing a segmented archive in creation.
|
|
*/
|
|
ZIP_SIZE_TYPE m_uBytesWritten;
|
|
|
|
/**
|
|
\c true, if the current archive is a new segmented archive; \c false otherwise.
|
|
*/
|
|
bool m_bNewSegm;
|
|
|
|
/**
|
|
The current volume number in a segmented archive.
|
|
The value is zero-based.
|
|
*/
|
|
ZIP_VOLUME_TYPE m_uCurrentVolume;
|
|
|
|
/**
|
|
\c true when the archive is created in memory; \c false otherwise.
|
|
*/
|
|
bool m_bInMemory;
|
|
|
|
/**
|
|
\c true if OpenMode::zipOpenReadOnly was specified when opening the archive.
|
|
*/
|
|
bool m_bReadOnly;
|
|
|
|
/**
|
|
The number of bytes before the actual zip archive in a file.
|
|
\see
|
|
CZipArchive::GetBytesBeforeZip
|
|
*/
|
|
ZIP_SIZE_TYPE m_uBytesBeforeZip;
|
|
|
|
|
|
/**
|
|
The size of the write buffer.
|
|
|
|
\see
|
|
CZipArchive::SetAdvanced
|
|
*/
|
|
int m_iWriteBufferSize;
|
|
|
|
/**
|
|
The size of the buffer used in searching for the central directory.
|
|
|
|
\see
|
|
CZipArchive::SetAdvanced
|
|
*/
|
|
int m_iLocateBufferSize;
|
|
|
|
/**
|
|
Takes one of the #ZipSegmentationMode values.
|
|
*/
|
|
int m_iSegmMode;
|
|
|
|
/**
|
|
A callback object called when there is a need for a volume change
|
|
in a spanned archive.
|
|
|
|
\see
|
|
CZipArchive::SetSegmCallback
|
|
*/
|
|
CZipSegmCallback* m_pSpanChangeVolumeFunc;
|
|
|
|
/**
|
|
A callback object called when there is a need for a volume change
|
|
in a split archive.
|
|
|
|
\see
|
|
CZipArchive::SetSegmCallback
|
|
*/
|
|
CZipSegmCallback* m_pSplitChangeVolumeFunc;
|
|
private:
|
|
CZipSegmCallback* m_pChangeVolumeFunc;
|
|
CZipString m_szArchiveName;
|
|
CZipFile m_internalfile;
|
|
static const ZIP_FILE_USIZE SignatureNotFound;
|
|
void ThrowError(int err);
|
|
};
|
|
|
|
#if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL)
|
|
#pragma warning (pop)
|
|
#endif
|
|
|
|
|
|
#endif // !defined(ZIPARCHIVE_ZIPSTORAGE_DOT_H)
|