00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00014
00021 #if !defined(ZIPARCHIVE_ZIPFILEHEADER_DOT_H)
00022 #define ZIPARCHIVE_ZIPFILEHEADER_DOT_H
00023
00024 #if _MSC_VER > 1000
00025 #pragma once
00026 #endif
00027
00028 #include "ZipExport.h"
00029 #include "ZipStorage.h"
00030 #include "ZipAutoBuffer.h"
00031 #include "sys/types.h"
00032 #include "ZipCompatibility.h"
00033 #include "ZipCollections.h"
00034 #include "ZipExtraField.h"
00035 #include "ZipStringStoreSettings.h"
00036 #include "ZipCryptograph.h"
00037 #include "BitFlag.h"
00038
00039
00040 class CZipCentralDir;
00041
00045 class ZIP_API CZipFileHeader
00046 {
00047 friend class CZipCentralDir;
00048 friend class CZipArchive;
00049 protected:
00050 CZipFileHeader(CZipCentralDir* pCentralDir);
00051 public:
00058 enum StateFlags
00059 {
00060 sfNone = 0x00,
00061 #ifdef _ZIP_UNICODE_CUSTOM
00062 sfCustomUnicode = 0x10,
00063 #endif
00064 sfModified = 0x20
00065 };
00066
00067 CZipFileHeader();
00068 CZipFileHeader(const CZipFileHeader& header)
00069 {
00070 *this = header;
00071 }
00072 CZipFileHeader& operator=(const CZipFileHeader& header);
00073 virtual ~CZipFileHeader();
00074
00081 int PredictFileNameSize() const
00082 {
00083 if (m_fileName.HasBuffer())
00084 {
00085 return m_fileName.GetBufferSize();
00086 }
00087 CZipAutoBuffer buffer;
00088 ConvertFileName(buffer);
00089 return buffer.GetSize();
00090 }
00091
00098 int PredictCommentSize() const
00099 {
00100 if (m_comment.HasBuffer())
00101 {
00102 return m_comment.GetBufferSize();
00103 }
00104 CZipAutoBuffer buffer;
00105 ConvertComment(buffer);
00106 return buffer.GetSize();
00107 }
00108
00109
00132 const CZipString& GetFileName(bool bClearBuffer = true);
00133
00152 bool SetFileName(LPCTSTR lpszFileName);
00153
00171 const CZipString& GetComment(bool bClearBuffer = false);
00172
00187 bool SetComment(LPCTSTR lpszComment);
00188
00195 bool IsDataDescriptor()const { return (m_uFlag & (WORD) 8) != 0;}
00196
00208 WORD GetDataDescriptorSize(const CZipStorage* pStorage) const
00209 {
00210 return GetDataDescriptorSize(NeedsSignatureInDataDescriptor(pStorage));
00211 }
00212
00224 WORD GetDataDescriptorSize(bool bConsiderSignature = false) const;
00225
00239 ZIP_SIZE_TYPE GetDataSize(bool bReal) const
00240 {
00241 DWORD uEncrSize = GetEncryptedInfoSize();
00242 return bReal ? (m_uComprSize - uEncrSize) : (m_uComprSize + uEncrSize);
00243 }
00244
00251 DWORD GetEncryptedInfoSize() const
00252 {
00253 return CZipCryptograph::GetEncryptedInfoSize(m_uEncryptionMethod);
00254 }
00255
00262 DWORD GetSize() const;
00263
00275 DWORD GetLocalSize(bool bReal) const;
00276
00284 bool CompressionEfficient()
00285 {
00286 ZIP_SIZE_TYPE uBefore = m_uUncomprSize;
00287
00288 ZIP_SIZE_TYPE uAfter = GetDataSize(true);
00289 return uAfter <= uBefore;
00290 }
00291
00298 float GetCompressionRatio()
00299 {
00300 #if _MSC_VER >= 1300 || !defined(_ZIP_ZIP64)
00301 return m_uUncomprSize ? ((float)m_uComprSize * 100 ) / m_uUncomprSize: 0;
00302 #else
00303 return m_uUncomprSize ? ((float)(__int64)(m_uComprSize) / (float)(__int64)m_uUncomprSize) * 100: 0;
00304 #endif
00305 }
00306
00316 void SetTime(const time_t& ttime);
00317
00327 time_t GetTime()const;
00328
00342 int GetSystemCompatibility()const
00343 {
00344 return (int)m_iSystemCompatibility;
00345 }
00346
00360 DWORD GetSystemAttr();
00361
00362
00375 bool SetSystemAttr(DWORD uAttr);
00376
00389 DWORD GetOriginalAttributes() const {return m_uExternalAttr;}
00390
00401 bool IsDirectory();
00402
00403 #ifdef _ZIP_UNICODE_CUSTOM
00404
00415 CZipStringStoreSettings GetStringStoreSettings()
00416 {
00417 return m_stringSettings;
00418 }
00419 #endif
00420
00432 bool IsEncrypted()const { return m_uEncryptionMethod != CZipCryptograph::encNone;}
00433
00440 int GetEncryptionMethod() const {return m_uEncryptionMethod;}
00441
00448 bool IsWinZipAesEncryption() const
00449 {
00450 return CZipCryptograph::IsWinZipAesEncryption(m_uEncryptionMethod);
00451 }
00452
00459 int GetCompressionLevel() const;
00460
00467 bool HasTime() const
00468 {
00469 return m_uModTime != 0 || m_uModDate != 0;
00470 }
00471
00481 bool IsModified() const
00482 {
00483 return m_state.IsSetAny(sfModified);
00484 }
00485
00486
00493 const ZipArchiveLib::CBitFlag& GetState() const
00494 {
00495 return m_state;
00496 }
00497
00498 static char m_gszSignature[];
00499 static char m_gszLocalSignature[];
00500 unsigned char m_uVersionMadeBy;
00501 WORD m_uVersionNeeded;
00502 WORD m_uFlag;
00503 WORD m_uMethod;
00504 WORD m_uModTime;
00505 WORD m_uModDate;
00506 DWORD m_uCrc32;
00507 ZIP_SIZE_TYPE m_uComprSize;
00508 ZIP_SIZE_TYPE m_uUncomprSize;
00509 ZIP_VOLUME_TYPE m_uVolumeStart;
00510 WORD m_uInternalAttr;
00511 ZIP_SIZE_TYPE m_uLocalComprSize;
00512 ZIP_SIZE_TYPE m_uLocalUncomprSize;
00513 ZIP_SIZE_TYPE m_uOffset;
00514 CZipExtraField m_aLocalExtraData;
00515 CZipExtraField m_aCentralExtraData;
00516 protected:
00517 DWORD m_uExternalAttr;
00518 WORD m_uLocalFileNameSize;
00519 BYTE m_uEncryptionMethod;
00520 bool m_bIgnoreCrc32;
00521 DWORD m_uLocalHeaderSize;
00522
00523 CZipCentralDir* m_pCentralDir;
00524
00525
00526
00539 void SetSystemCompatibility(int iSystemID, bool bUpdateAttr = false)
00540 {
00541 if (bUpdateAttr)
00542 {
00543 if ((int)m_iSystemCompatibility != iSystemID)
00544 {
00545 DWORD uAttr = GetSystemAttr();
00546 m_iSystemCompatibility = (char)(iSystemID & 0xFF);
00547 SetSystemAttr(uAttr & 0xFFFF);
00548 }
00549 return;
00550 }
00551 m_iSystemCompatibility = (char)(iSystemID & 0xFF);
00552 }
00553
00557 void PrepareStringBuffers()
00558 {
00559 if (!m_fileName.HasBuffer())
00560 {
00561 ConvertFileName(m_fileName.m_buffer);
00562 }
00563 if (!m_comment.HasBuffer())
00564 {
00565 ConvertComment(m_comment.m_buffer);
00566 }
00567 }
00568
00578 bool CheckDataDescriptor(CZipStorage* pStorage) const;
00579
00580
00591 void PrepareData(int iLevel, bool bSegm);
00592
00601 void WriteLocal(CZipStorage *pStorage);
00602
00616 bool ReadLocal(CZipCentralDir* pCentralDir);
00617
00628 DWORD Write(CZipStorage *pStorage);
00629
00641 bool Read(bool bReadSignature);
00642
00643
00651 bool CheckLengths(bool local) const
00652 {
00653 if (m_comment.GetBufferSize() > (int)USHRT_MAX || m_fileName.GetBufferSize() > (int)USHRT_MAX)
00654 return false;
00655 else if (local)
00656 return m_aLocalExtraData.Validate();
00657 else
00658 return m_aCentralExtraData.Validate();
00659 }
00660
00667 void WriteCrc32(char* pBuf) const;
00668
00669
00677 bool NeedsDataDescriptor() const;
00678
00679
00689 void WriteSmallDataDescriptor(char* pDest, bool bLocal = true);
00690
00697 void WriteDataDescriptor(CZipStorage* pStorage);
00698
00708 bool NeedsSignatureInDataDescriptor(const CZipStorage* pStorage) const
00709 {
00710 return pStorage->IsSegmented() || IsEncrypted();
00711 }
00712
00719 void UpdateLocalHeader(CZipStorage* pStorage);
00720
00724 void AdjustLocalComprSize()
00725 {
00726 AdjustLocalComprSize(m_uLocalComprSize);
00727 }
00728
00735 void AdjustLocalComprSize(ZIP_SIZE_TYPE& uLocalComprSize)
00736 {
00737 uLocalComprSize += GetEncryptedInfoSize();
00738 }
00739
00749 static bool VerifySignature(CZipAutoBuffer& buf)
00750 {
00751 return memcmp(buf, m_gszSignature, 4) == 0;
00752 }
00753
00760 void UpdateFlag(bool bSegm)
00761 {
00762 if (bSegm || m_uEncryptionMethod == CZipCryptograph::encStandard)
00763 m_uFlag |= 8;
00764
00765 if (IsEncrypted())
00766 m_uFlag |= 1;
00767 }
00768
00769
00770 private:
00771
00772 struct StringWithBuffer
00773 {
00774 StringWithBuffer()
00775 {
00776 m_pString = NULL;
00777 }
00778 CZipAutoBuffer m_buffer;
00779 StringWithBuffer& operator = (const StringWithBuffer& original)
00780 {
00781 if (original.HasString())
00782 {
00783 SetString(original.GetString());
00784 }
00785 else
00786 {
00787 ClearString();
00788 }
00789 m_buffer = original.m_buffer;
00790 return *this;
00791 }
00792 void AllocateString()
00793 {
00794 ClearString();
00795 m_pString = new CZipString(_T(""));
00796 }
00797 bool HasString() const
00798 {
00799 return m_pString != NULL;
00800 }
00801 bool HasBuffer() const
00802 {
00803 return m_buffer.IsAllocated() && m_buffer.GetSize() > 0;
00804 }
00805 void ClearString()
00806 {
00807 if (HasString())
00808 {
00809 delete m_pString;
00810 m_pString = NULL;
00811 }
00812 }
00813 void ClearBuffer()
00814 {
00815 m_buffer.Release();
00816 }
00817
00818 const CZipString& GetString() const
00819 {
00820 ASSERT(HasString());
00821 return *m_pString;
00822 }
00823
00824 CZipString& GetString()
00825 {
00826 ASSERT(HasString());
00827 return *m_pString;
00828 }
00829
00830 void SetString(LPCTSTR value)
00831 {
00832 if (!HasString())
00833 AllocateString();
00834 *m_pString = value;
00835 }
00836
00837 int GetBufferSize() const
00838 {
00839 return m_buffer.GetSize();
00840 }
00841 ~StringWithBuffer()
00842 {
00843 ClearString();
00844 }
00845 protected:
00846 CZipString* m_pString;
00847 };
00848
00849 ZipArchiveLib::CBitFlag m_state;
00850
00851 void Initialize(CZipCentralDir* pCentralDir);
00852
00853 void SetModified(bool bModified = true)
00854 {
00855 m_state.Change(sfModified, bModified);
00856 }
00857
00858 void ConvertFileName(CZipAutoBuffer& buffer) const;
00859 void ConvertFileName(CZipString& szFileName) const;
00860 void ConvertComment(CZipAutoBuffer& buffer) const;
00861 void ConvertComment(CZipString& szComment) const;
00862
00863 bool UpdateFileNameFlags(const CZipString* szNewFileName, bool bAllowRemoveCDir);
00864 bool UpdateCommentFlags(const CZipString* szNewComment);
00865 bool UpdateStringsFlags(bool bAllowRemoveCDir)
00866 {
00867 return UpdateFileNameFlags(NULL, bAllowRemoveCDir) | UpdateCommentFlags(NULL);
00868 }
00869
00870 UINT GetDefaultFileNameCodePage() const
00871 {
00872 return ZipCompatibility::GetDefaultNameCodePage(GetSystemCompatibility());
00873 }
00874
00875 UINT GetDefaultCommentCodePage() const
00876 {
00877 return ZipCompatibility::GetDefaultCommentCodePage(GetSystemCompatibility());
00878 }
00879
00880 void ClearFileName();
00881
00882 void GetCrcAndSizes(char* pBuffer)const;
00883
00884 bool NeedsZip64() const
00885 {
00886 return m_uComprSize >= UINT_MAX || m_uUncomprSize >= UINT_MAX || m_uVolumeStart >= USHRT_MAX || m_uOffset >= UINT_MAX;
00887 }
00888
00889
00890 void OnNewFileClose(CZipStorage* pStorage)
00891 {
00892 UpdateLocalHeader(pStorage);
00893 WriteDataDescriptor(pStorage);
00894 pStorage->Flush();
00895 }
00896
00897 #ifdef _ZIP_UNICODE_CUSTOM
00898 CZipStringStoreSettings m_stringSettings;
00899 #endif
00900 StringWithBuffer m_fileName;
00901 StringWithBuffer m_comment;
00902 char m_iSystemCompatibility;
00903 };
00904
00905 #endif // !defined(ZIPARCHIVE_ZIPFILEHEADER_DOT_H)