ZipFileHeader.h
Go to the documentation of this file.
1 
2 // This source file is part of the ZipArchive Library Open Source distribution
3 // and is Copyrighted 2000 - 2022 by Artpol Software - Tadeusz Dracz
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // For the licensing details refer to the License.txt file.
11 //
12 // Web Site: https://www.artpol-software.com
14 
20 #if !defined(ZIPARCHIVE_ZIPFILEHEADER_DOT_H)
21 #define ZIPARCHIVE_ZIPFILEHEADER_DOT_H
22 
23 #if _MSC_VER > 1000
24 #pragma once
25 #endif
26 
27 #include "ZipExport.h"
28 #include "ZipStorage.h"
29 #include "ZipAutoBuffer.h"
30 #include "sys/types.h"
31 #include "ZipCompatibility.h"
32 #include "ZipCollections.h"
33 #include "ZipExtraField.h"
34 #include "ZipStringStoreSettings.h"
35 #include "ZipCryptograph.h"
36 #include "BitFlag.h"
37 
38 
39 class CZipCentralDir;
40 
44 class ZIP_API CZipFileHeader
45 {
46  friend class CZipCentralDir;
47  friend class CZipArchive;
48 protected:
49  CZipFileHeader(CZipCentralDir* pCentralDir);
50 public:
58  {
59  sfNone = 0x00,
60 #ifdef _ZIP_UNICODE_CUSTOM
61  sfCustomUnicode = 0x10,
62 #endif
63  sfModified = 0x20
64  };
65 
67 #pragma warning(suppress: 26495)
68  CZipFileHeader(const CZipFileHeader& header)
69  {
70  *this = header;
71  }
72  CZipFileHeader& operator=(const CZipFileHeader& header);
73  virtual ~CZipFileHeader();
74 
81  int PredictFileNameSize() const
82  {
83  if (m_fileName.HasBuffer())
84  {
85  return m_fileName.GetBufferSize();
86  }
87  CZipAutoBuffer buffer;
88  ConvertFileName(buffer);
89  return buffer.GetSize();
90  }
91 
98  int PredictCommentSize() const
99  {
100  if (m_comment.HasBuffer())
101  {
102  return m_comment.GetBufferSize();
103  }
104  CZipAutoBuffer buffer;
105  ConvertComment(buffer);
106  return buffer.GetSize();
107  }
108 
109 
136  const CZipString& GetFileName(bool bClearBuffer = true);
137 
166  CZipString GetFileTitle(bool bLowerCase = false, bool bClearBuffer = true);
167 
168 
197  CZipString GetFileExtension(bool bLowerCase = false, bool bClearBuffer = true);
198 
227  bool SetFileName(LPCTSTR lpszFileName, bool bInCentralOnly = false);
228 
246  const CZipString& GetComment(bool bClearBuffer = false);
247 
262  bool SetComment(LPCTSTR lpszComment);
263 
270  bool IsDataDescriptor()const { return (m_uFlag & (WORD) 8) != 0;}
271 
283  WORD GetDataDescriptorSize(const CZipStorage* pStorage) const
284  {
285  return GetDataDescriptorSize(NeedsSignatureInDataDescriptor(pStorage));
286  }
287 
299  WORD GetDataDescriptorSize(bool bConsiderSignature = false) const;
300 
314  ZIP_SIZE_TYPE GetDataSize(bool bReal) const
315  {
316  DWORD uEncrSize = GetEncryptedInfoSize();
317  return bReal ? (m_uComprSize - uEncrSize) : (m_uComprSize + uEncrSize);
318  }
319 
326  DWORD GetEncryptedInfoSize() const
327  {
328  return CZipCryptograph::GetEncryptedInfoSize(m_uEncryptionMethod);
329  }
330 
337  DWORD GetSize() const;
338 
350  DWORD GetLocalSize(bool bReal) const;
351 
359  bool CompressionEfficient()
360  {
361  ZIP_SIZE_TYPE uBefore = m_uUncomprSize;
362  // ignore the length of encryption info
363  ZIP_SIZE_TYPE uAfter = GetDataSize(true);
364  return uAfter <= uBefore;
365  }
366 
373  float GetCompressionRatio()
374  {
375 #if _MSC_VER >= 1300 || !defined(_ZIP_ZIP64)
376  return m_uUncomprSize ? ((float)m_uComprSize * 100 ) / m_uUncomprSize: 0;
377 #else
378  return m_uUncomprSize ? ((float)(__int64)(m_uComprSize) / (float)(__int64)m_uUncomprSize) * 100: 0;
379 #endif
380  }
381 
395  void SetCreationTime(const time_t& ttime){m_tCreationTime = ttime;}
396 
407  time_t GetCreationTime()const{return m_tCreationTime;}
408 
428  void SetModificationTime(const time_t& ttime, bool bFullResolution = false, bool bUseUtcTime = false );
429 
439  time_t GetModificationTime()const;
440 
451  time_t GetLastAccessTime()const{return m_tLastAccessTime;}
452 
466  void SetLastAccessTime(const time_t& ttime){m_tLastAccessTime = ttime;}
467 
482  {
483  return (int)m_iSystemCompatibility;
484  }
485 
499  DWORD GetSystemAttr();
500 
501 
514  bool SetSystemAttr(DWORD uAttr);
515 
528  DWORD GetOriginalAttributes() const {return m_uExternalAttr;}
529 
540  bool IsDirectory();
541 
542 #ifdef _ZIP_UNICODE_CUSTOM
543 
555  {
556  return m_stringSettings;
557  }
558 #endif
559 
571  bool IsEncrypted()const { return m_uEncryptionMethod != CZipCryptograph::encNone;}
572 
579  int GetEncryptionMethod() const {return m_uEncryptionMethod;}
580 
587  bool IsWinZipAesEncryption() const
588  {
589  return CZipCryptograph::IsWinZipAesEncryption(m_uEncryptionMethod);
590  }
591 
598  int GetCompressionLevel() const;
599 
606  bool HasTime() const
607  {
608  return m_uModTime != 0 || m_uModDate != 0;
609  }
610 
620  bool IsModified() const
621  {
622  return m_state.IsSetAny(sfModified);
623  }
624 
625 
632  const ZipArchiveLib::CBitFlag& GetState() const
633  {
634  return m_state;
635  }
636 
637  static char m_gszSignature[];
638  static char m_gszLocalSignature[];
639  unsigned char m_uVersionMadeBy;
641  WORD m_uFlag;
642  WORD m_uMethod;
643  WORD m_uModTime;
644  WORD m_uModDate;
645  DWORD m_uCrc32;
646  ZIP_SIZE_TYPE m_uComprSize;
647  ZIP_SIZE_TYPE m_uUncomprSize;
648  ZIP_VOLUME_TYPE m_uVolumeStart;
650  ZIP_SIZE_TYPE m_uLocalComprSize;
651  ZIP_SIZE_TYPE m_uLocalUncomprSize;
652  ZIP_SIZE_TYPE m_uOffset;
655 protected:
659 
664  DWORD m_uLocalHeaderSize;
665 
667 
668 
669 
682  void SetSystemCompatibility(int iSystemID, bool bUpdateAttr = false)
683  {
684  if (bUpdateAttr)
685  {
686  if ((int)m_iSystemCompatibility != iSystemID)
687  {
688  DWORD uAttr = GetSystemAttr();
689  m_iSystemCompatibility = (char)(iSystemID & 0xFF);
690  SetSystemAttr(uAttr & 0xFFFF);
691  }
692  return;
693  }
694  m_iSystemCompatibility = (char)(iSystemID & 0xFF);
695  }
696 
700  void PrepareStringBuffers()
701  {
702  if (!m_fileName.HasBuffer())
703  {
704  ConvertFileName(m_fileName.m_buffer);
705  }
706  if (!m_comment.HasBuffer())
707  {
708  ConvertComment(m_comment.m_buffer);
709  }
710  }
711 
721  bool CheckDataDescriptor(CZipStorage* pStorage) const;
722 
723 
734  void PrepareData(int iLevel, bool bSegm);
735 
744  void WriteLocal(CZipStorage *pStorage);
745 
759  bool ReadLocal(CZipCentralDir* pCentralDir);
760 
771  DWORD Write(CZipCentralDir* pCentralDir);
772 
784  bool Read(bool bReadSignature);
785 
786 
794  bool CheckLengths(bool local) const
795  {
796  if (m_comment.GetBufferSize() > (int)USHRT_MAX || m_fileName.GetBufferSize() > (int)USHRT_MAX)
797  return false;
798  else if (local)
799  return m_aLocalExtraData.Validate();
800  else
801  return m_aCentralExtraData.Validate();
802  }
803 
810  void WriteCrc32(char* pBuf) const;
811 
812 
820  bool NeedsDataDescriptor() const;
821 
822 
832  void WriteSmallDataDescriptor(char* pDest, bool bLocal = true);
833 
840  void WriteDataDescriptor(CZipStorage* pStorage);
841 
851  bool NeedsSignatureInDataDescriptor(const CZipStorage* pStorage) const
852  {
853  return pStorage->IsSegmented() || IsEncrypted();
854  }
855 
862  void UpdateLocalHeader(CZipStorage* pStorage);
863 
867  void AdjustLocalComprSize()
868  {
869  AdjustLocalComprSize(m_uLocalComprSize);
870  }
871 
878  void AdjustLocalComprSize(ZIP_SIZE_TYPE& uLocalComprSize)
879  {
880  uLocalComprSize += GetEncryptedInfoSize();
881  }
882 
892  static bool VerifySignature(CZipAutoBuffer& buf)
893  {
894  return memcmp(buf, m_gszSignature, 4) == 0;
895  }
896 
903  void UpdateFlag(bool bSegm)
904  {
905  if (bSegm || m_uEncryptionMethod == CZipCryptograph::encStandard)
906  m_uFlag |= 8; // data descriptor present
907 
908  if (IsEncrypted())
909  m_uFlag |= 1; // encrypted file
910  }
911 
912 
913 private:
914 
915  struct StringWithBuffer
916  {
917  StringWithBuffer()
918  {
919  m_pString = NULL;
920  }
921  CZipAutoBuffer m_buffer;
922  StringWithBuffer& operator = (const StringWithBuffer& original)
923  {
924  if (original.HasString())
925  {
926  SetString(original.GetString());
927  }
928  else
929  {
930  ClearString();
931  }
932  m_buffer = original.m_buffer;
933  return *this;
934  }
935  void AllocateString()
936  {
937  ClearString();
938  m_pString = new CZipString(_T(""));
939  }
940  bool HasString() const
941  {
942  return m_pString != NULL;
943  }
944  bool HasBuffer() const
945  {
946  return m_buffer.IsAllocated() && m_buffer.GetSize() > 0;
947  }
948  void ClearString()
949  {
950  if (HasString())
951  {
952  delete m_pString;
953  m_pString = NULL;
954  }
955  }
956  void ClearBuffer()
957  {
958  m_buffer.Release();
959  }
960 
961  const CZipString& GetString() const
962  {
963  ASSERT(HasString());
964  return *m_pString;
965  }
966 
967  CZipString& GetString()
968  {
969  ASSERT(HasString());
970  return *m_pString;
971  }
972 
973  void SetString(LPCTSTR value)
974  {
975  if (!HasString())
976  AllocateString();
977  *m_pString = value;
978  }
979 
980  int GetBufferSize() const
981  {
982  return m_buffer.GetSize();
983  }
984  ~StringWithBuffer()
985  {
986  ClearString();
987  }
988  protected:
989  CZipString* m_pString;
990  };
991 
992  ZipArchiveLib::CBitFlag m_state;
993 
994  void Initialize(CZipCentralDir* pCentralDir);
995 
996  void SetModified(bool bModified = true)
997  {
998  m_state.Change(sfModified, bModified);
999  }
1000 
1001  void ConvertFileName(CZipAutoBuffer& buffer) const;
1002  void ConvertFileName(CZipString& szFileName) const;
1003  void ConvertComment(CZipAutoBuffer& buffer) const;
1004  void ConvertComment(CZipString& szComment) const;
1005 
1006  bool UpdateFileNameFlags(const CZipString* szNewFileName, bool bAllowRemoveCDir);
1007  bool UpdateCommentFlags(const CZipString* szNewComment);
1008  bool UpdateStringsFlags(bool bAllowRemoveCDir)
1009  {
1010  return UpdateFileNameFlags(NULL, bAllowRemoveCDir) | UpdateCommentFlags(NULL);
1011  }
1012 
1013  UINT GetDefaultFileNameCodePage() const
1014  {
1015  return ZipCompatibility::GetDefaultNameCodePage(GetSystemCompatibility());
1016  }
1017 
1018  UINT GetDefaultCommentCodePage() const
1019  {
1020  return ZipCompatibility::GetDefaultCommentCodePage(GetSystemCompatibility());
1021  }
1022 
1023  void ClearFileName();
1024 
1025  void GetCrcAndSizes(char* pBuffer)const;
1026 
1027  bool NeedsZip64() const
1028  {
1029  return m_uComprSize >= UINT_MAX || m_uUncomprSize >= UINT_MAX || m_uVolumeStart >= USHRT_MAX || m_uOffset >= UINT_MAX;
1030  }
1031 
1032  time_t ReadFileTime(const char* buffer);
1033  void WriteFileTime(const time_t& ttime, char* buffer, bool bUseUtcTime);
1034 
1035 
1036  void OnNewFileClose(CZipStorage* pStorage)
1037  {
1038  UpdateLocalHeader(pStorage);
1039  WriteDataDescriptor(pStorage);
1040  pStorage->Flush();
1041  }
1042 
1043 #ifdef _ZIP_UNICODE_CUSTOM
1044  CZipStringStoreSettings m_stringSettings;
1045 #endif
1046  StringWithBuffer m_fileName;
1047  StringWithBuffer m_comment;
1048  char m_iSystemCompatibility;
1049 };
1050 
1051 #endif // !defined(ZIPARCHIVE_ZIPFILEHEADER_DOT_H)

The ZipArchive Library Copyright © 2000 - 2022 Artpol Software - Tadeusz Dracz. Generated at Sat Dec 17 2022 19:57:03.