Initialer Commit

This commit is contained in:
Tino Reichardt
2016-06-25 21:15:50 +02:00
commit c3967fe27a
1199 changed files with 290375 additions and 0 deletions

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,411 @@
// Rar5Handler.h
#ifndef __RAR5_HANDLER_H
#define __RAR5_HANDLER_H
#include "../../../../C/Blake2.h"
#include "../../../Common/MyBuffer.h"
#include "../../../Windows/PropVariant.h"
#include "../../Common/CreateCoder.h"
#include "../IArchive.h"
namespace NArchive {
namespace NRar5 {
namespace NHeaderFlags
{
const unsigned kExtra = 1 << 0;
const unsigned kData = 1 << 1;
// const unsigned kUnknown = 1 << 2;
const unsigned kPrevVol = 1 << 3;
const unsigned kNextVol = 1 << 4;
// const unsigned kIsChild = 1 << 5;
// const unsigned kPreserveChild = 1 << 6;
}
namespace NHeaderType
{
enum
{
kArc = 1,
kFile,
kService,
kArcEncrypt,
kEndOfArc
};
}
namespace NArcFlags
{
const unsigned kVol = 1 << 0;
const unsigned kVolNumber = 1 << 1;
const unsigned kSolid = 1 << 2;
// const unsigned kRecovery = 1 << 3;
// const unsigned kLocked = 1 << 4;
}
const unsigned kArcExtraRecordType_Locator = 1;
namespace NLocatorFlags
{
const unsigned kQuickOpen = 1 << 0;
const unsigned kRecovery = 1 << 1;
}
namespace NFileFlags
{
const unsigned kIsDir = 1 << 0;
const unsigned kUnixTime = 1 << 1;
const unsigned kCrc32 = 1 << 2;
const unsigned kUnknownSize = 1 << 3;
}
namespace NMethodFlags
{
// const unsigned kVersionMask = 0x3F;
const unsigned kSolid = 1 << 6;
}
namespace NArcEndFlags
{
const unsigned kMoreVols = 1 << 0;
}
enum EHostOS
{
kHost_Windows = 0,
kHost_Unix
};
// ---------- Extra ----------
namespace NExtraRecordType
{
enum
{
kCrypto = 1,
kHash,
kTime,
kVersion,
kLink,
kUnixOwner,
kSubdata
};
}
// const unsigned kCryptoAlgo_AES = 0;
namespace NCryptoFlags
{
const unsigned kPswCheck = 1 << 0;
const unsigned kUseMAC = 1 << 1;
}
struct CCryptoInfo
{
UInt64 Algo;
UInt64 Flags;
Byte Cnt;
bool UseMAC() const { return (Flags & NCryptoFlags::kUseMAC) != 0; }
bool IsThereCheck() const { return (Flags & NCryptoFlags::kPswCheck) != 0; }
bool Parse(const Byte *p, size_t size);
};
const unsigned kHashID_Blake2sp = 0;
namespace NTimeRecord
{
enum
{
k_Index_MTime = 0,
k_Index_CTime,
k_Index_ATime
};
namespace NFlags
{
const unsigned kUnixTime = 1 << 0;
const unsigned kMTime = 1 << 1;
// const unsigned kCTime = 1 << 2;
// const unsigned kATime = 1 << 3;
}
}
namespace NLinkType
{
enum
{
kUnixSymLink = 1,
kWinSymLink,
kWinJunction,
kHardLink,
kFileCopy
};
}
namespace NLinkFlags
{
const unsigned kTargetIsDir = 1 << 0;
}
struct CItem
{
UInt32 CommonFlags;
UInt32 Flags;
Byte RecordType;
bool Version_Defined;
int ACL;
AString Name;
int VolIndex;
int NextItem;
UInt32 UnixMTime;
UInt32 CRC;
UInt32 Attrib;
UInt32 Method;
CByteBuffer Extra;
UInt64 Size;
UInt64 PackSize;
UInt64 HostOS;
UInt64 DataPos;
UInt64 Version;
CItem() { Clear(); }
void Clear()
{
CommonFlags = 0;
Flags = 0;
VolIndex = 0;
NextItem = -1;
Version_Defined = false;
Version = 0;
Name.Empty();
Extra.Free();
ACL = -1;
}
bool IsSplitBefore() const { return (CommonFlags & NHeaderFlags::kPrevVol) != 0; }
bool IsSplitAfter() const { return (CommonFlags & NHeaderFlags::kNextVol) != 0; }
bool IsSplit() const { return (CommonFlags & (NHeaderFlags::kPrevVol | NHeaderFlags::kNextVol)) != 0; }
bool IsDir() const { return (Flags & NFileFlags::kIsDir) != 0; }
bool Has_UnixMTime() const { return (Flags & NFileFlags::kUnixTime) != 0; }
bool Has_CRC() const { return (Flags & NFileFlags::kCrc32) != 0; }
bool Is_UnknownSize() const { return (Flags & NFileFlags::kUnknownSize) != 0; }
bool IsNextForItem(const CItem &prev) const
{
return !IsDir() && !prev.IsDir() && IsSplitBefore() && prev.IsSplitAfter() && (Name == prev.Name);
// && false;
}
bool IsSolid() const { return ((UInt32)Method & NMethodFlags::kSolid) != 0; }
unsigned GetAlgoVersion() const { return (unsigned)Method & 0x3F; }
unsigned GetMethod() const { return ((unsigned)Method >> 7) & 0x7; }
UInt32 GetDictSize() const { return (((UInt32)Method >> 10) & 0xF); }
bool IsService() const { return RecordType == NHeaderType::kService; }
bool Is_STM() const { return IsService() && Name == "STM"; }
bool Is_CMT() const { return IsService() && Name == "CMT"; }
bool Is_ACL() const { return IsService() && Name == "ACL"; }
// bool Is_QO() const { return IsService() && Name == "QO"; }
int FindExtra(unsigned type, unsigned &recordDataSize) const;
bool IsEncrypted() const
{
unsigned size;
return FindExtra(NExtraRecordType::kCrypto, size) >= 0;
}
int FindExtra_Blake() const
{
unsigned size = 0;
int offset = FindExtra(NExtraRecordType::kHash, size);
if (offset >= 0
&& size == BLAKE2S_DIGEST_SIZE + 1
&& Extra[(unsigned)offset] == kHashID_Blake2sp)
return offset + 1;
return -1;
}
bool FindExtra_Version(UInt64 &version) const;
struct CLinkInfo
{
UInt64 Type;
UInt64 Flags;
unsigned NameOffset;
unsigned NameLen;
};
bool FindExtra_Link(CLinkInfo &link) const;
void Link_to_Prop(unsigned linkType, NWindows::NCOM::CPropVariant &prop) const;
bool Is_CopyLink() const;
bool NeedUse_as_CopyLink() const { return PackSize == 0 && Is_CopyLink(); }
bool GetAltStreamName(AString &name) const;
UInt32 GetWinAttrib() const
{
UInt32 a;
switch (HostOS)
{
case kHost_Windows: a = Attrib; break;
case kHost_Unix: a = (Attrib << 16); break;
default: a = 0;
}
// if (IsDir()) a |= FILE_ATTRIBUTE_DIRECTORY;
return a;
}
UInt64 GetDataPosition() const { return DataPos; }
};
struct CInArcInfo
{
UInt64 Flags;
UInt64 VolNumber;
UInt64 StartPos;
UInt64 EndPos;
UInt64 EndFlags;
bool EndOfArchive_was_Read;
bool IsEncrypted;
// CByteBuffer Extra;
/*
struct CLocator
{
UInt64 Flags;
UInt64 QuickOpen;
UInt64 Recovery;
bool Is_QuickOpen() const { return (Flags & NLocatorFlags::kQuickOpen) != 0; }
bool Is_Recovery() const { return (Flags & NLocatorFlags::kRecovery) != 0; }
};
int FindExtra(unsigned type, unsigned &recordDataSize) const;
bool FindExtra_Locator(CLocator &locator) const;
*/
CInArcInfo():
Flags(0),
VolNumber(0),
StartPos(0),
EndPos(0),
EndFlags(0),
EndOfArchive_was_Read(false),
IsEncrypted(false)
{}
/*
void Clear()
{
Flags = 0;
VolNumber = 0;
StartPos = 0;
EndPos = 0;
EndFlags = 0;
EndOfArchive_was_Read = false;
Extra.Free();
}
*/
UInt64 GetPhySize() const { return EndPos - StartPos; }
bool AreMoreVolumes() const { return (EndFlags & NArcEndFlags::kMoreVols) != 0; }
bool IsVolume() const { return (Flags & NArcFlags::kVol) != 0; }
bool IsSolid() const { return (Flags & NArcFlags::kSolid) != 0; }
bool Is_VolNumber_Defined() const { return (Flags & NArcFlags::kVolNumber) != 0; }
UInt64 GetVolIndex() const { return Is_VolNumber_Defined() ? VolNumber : 0; }
};
struct CRefItem
{
unsigned Item;
unsigned Last;
int Parent;
int Link;
};
struct CArc
{
CMyComPtr<IInStream> Stream;
CInArcInfo Info;
};
class CHandler:
public IInArchive,
public IArchiveGetRawProps,
PUBLIC_ISetCompressCodecsInfo
public CMyUnknownImp
{
public:
CRecordVector<CRefItem> _refs;
CObjectVector<CItem> _items;
private:
CObjectVector<CArc> _arcs;
CObjectVector<CByteBuffer> _acls;
UInt32 _errorFlags;
// UInt32 _warningFlags;
bool _isArc;
CByteBuffer _comment;
UString _missingVolName;
DECL_EXTERNAL_CODECS_VARS
UInt64 GetPackSize(unsigned refIndex) const;
void FillLinks();
HRESULT Open2(IInStream *stream,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openCallback);
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
QUERY_ENTRY_ISetCompressCodecsInfo
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
INTERFACE_IInArchive(;)
INTERFACE_IArchiveGetRawProps(;)
DECL_ISetCompressCodecsInfo
};
}}
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,116 @@
// RarHandler.h
#ifndef __RAR_HANDLER_H
#define __RAR_HANDLER_H
#include "../IArchive.h"
#include "../../Common/CreateCoder.h"
#include "RarItem.h"
namespace NArchive {
namespace NRar {
struct CInArcInfo
{
UInt32 Flags;
Byte EncryptVersion;
UInt64 StartPos;
UInt64 EndPos;
UInt64 FileSize;
UInt32 EndFlags;
UInt32 VolNumber;
UInt32 DataCRC;
bool EndOfArchive_was_Read;
CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false) {}
UInt64 GetPhySize() const { return EndPos - StartPos; }
bool ExtraZeroTail_is_Possible() const { return IsVolume() && IsRecovery() && EndOfArchive_was_Read; }
bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; }
bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; }
// kLock
bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; }
bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; }
// kAuthenticity
bool IsRecovery() const { return (Flags & NHeader::NArchive::kRecovery) != 0; }
bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; }
bool IsFirstVolume() const { return (Flags & NHeader::NArchive::kFirstVolume) != 0; }
// bool IsThereEncryptVer() const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; }
// bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); }
bool AreMoreVolumes() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_NextVol) != 0; }
bool Is_VolNumber_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) != 0; }
bool Is_DataCRC_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) != 0; }
};
struct CArc
{
CMyComPtr<IInStream> Stream;
UInt64 PhySize;
// CByteBuffer Comment;
CArc(): PhySize(0) {}
ISequentialInStream *CreateLimitedStream(UInt64 offset, UInt64 size) const;
};
struct CRefItem
{
unsigned VolumeIndex;
unsigned ItemIndex;
unsigned NumItems;
};
class CHandler:
public IInArchive,
PUBLIC_ISetCompressCodecsInfo
public CMyUnknownImp
{
CRecordVector<CRefItem> _refItems;
CObjectVector<CItem> _items;
CObjectVector<CArc> _arcs;
NArchive::NRar::CInArcInfo _arcInfo;
// AString _errorMessage;
UInt32 _errorFlags;
UInt32 _warningFlags;
bool _isArc;
UString _missingVolName;
DECL_EXTERNAL_CODECS_VARS
UInt64 GetPackSize(unsigned refIndex) const;
bool IsSolid(unsigned refIndex) const;
/*
void AddErrorMessage(const AString &s)
{
if (!_errorMessage.IsEmpty())
_errorMessage += '\n';
_errorMessage += s;
}
*/
HRESULT Open2(IInStream *stream,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openCallback);
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
QUERY_ENTRY_ISetCompressCodecsInfo
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
INTERFACE_IInArchive(;)
DECL_ISetCompressCodecsInfo
};
}}
#endif

View File

@@ -0,0 +1,209 @@
// Archive/RarHeader.h
#ifndef __ARCHIVE_RAR_HEADER_H
#define __ARCHIVE_RAR_HEADER_H
#include "../../../Common/MyTypes.h"
namespace NArchive {
namespace NRar {
namespace NHeader {
const unsigned kMarkerSize = 7;
const unsigned kArchiveSolid = 0x1;
namespace NBlockType
{
enum EBlockType
{
kMarker = 0x72,
kArchiveHeader,
kFileHeader,
kCommentHeader,
kOldAuthenticity,
kOldSubBlock,
kRecoveryRecord,
kAuthenticity,
kSubBlock,
kEndOfArchive
};
}
namespace NArchive
{
const UInt16 kVolume = 1;
const UInt16 kComment = 2;
const UInt16 kLock = 4;
const UInt16 kSolid = 8;
const UInt16 kNewVolName = 0x10; // ('volname.partN.rar')
const UInt16 kAuthenticity = 0x20;
const UInt16 kRecovery = 0x40;
const UInt16 kBlockEncryption = 0x80;
const UInt16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later)
// const UInt16 kEncryptVer = 0x200; // RAR 3.6 : that feature was discarded by origial RAR
const UInt16 kEndOfArc_Flags_NextVol = 1;
const UInt16 kEndOfArc_Flags_DataCRC = 2;
const UInt16 kEndOfArc_Flags_RevSpace = 4;
const UInt16 kEndOfArc_Flags_VolNumber = 8;
const unsigned kHeaderSizeMin = 7;
const unsigned kArchiveHeaderSize = 13;
const unsigned kBlockHeadersAreEncrypted = 0x80;
}
namespace NFile
{
const unsigned kSplitBefore = 1 << 0;
const unsigned kSplitAfter = 1 << 1;
const unsigned kEncrypted = 1 << 2;
const unsigned kComment = 1 << 3;
const unsigned kSolid = 1 << 4;
const unsigned kDictBitStart = 5;
const unsigned kNumDictBits = 3;
const unsigned kDictMask = (1 << kNumDictBits) - 1;
const unsigned kDictDirectoryValue = 0x7;
const unsigned kSize64Bits = 1 << 8;
const unsigned kUnicodeName = 1 << 9;
const unsigned kSalt = 1 << 10;
const unsigned kOldVersion = 1 << 11;
const unsigned kExtTime = 1 << 12;
// const unsigned kExtFlags = 1 << 13;
// const unsigned kSkipIfUnknown = 1 << 14;
const unsigned kLongBlock = 1 << 15;
/*
struct CBlock
{
// UInt16 HeadCRC;
// Byte Type;
// UInt16 Flags;
// UInt16 HeadSize;
UInt32 PackSize;
UInt32 UnPackSize;
Byte HostOS;
UInt32 FileCRC;
UInt32 Time;
Byte UnPackVersion;
Byte Method;
UInt16 NameSize;
UInt32 Attributes;
};
*/
/*
struct CBlock32
{
UInt16 HeadCRC;
Byte Type;
UInt16 Flags;
UInt16 HeadSize;
UInt32 PackSize;
UInt32 UnPackSize;
Byte HostOS;
UInt32 FileCRC;
UInt32 Time;
Byte UnPackVersion;
Byte Method;
UInt16 NameSize;
UInt32 Attributes;
UInt16 GetRealCRC(const void *aName, UInt32 aNameSize,
bool anExtraDataDefined = false, Byte *anExtraData = 0) const;
};
struct CBlock64
{
UInt16 HeadCRC;
Byte Type;
UInt16 Flags;
UInt16 HeadSize;
UInt32 PackSizeLow;
UInt32 UnPackSizeLow;
Byte HostOS;
UInt32 FileCRC;
UInt32 Time;
Byte UnPackVersion;
Byte Method;
UInt16 NameSize;
UInt32 Attributes;
UInt32 PackSizeHigh;
UInt32 UnPackSizeHigh;
UInt16 GetRealCRC(const void *aName, UInt32 aNameSize) const;
};
*/
const unsigned kLabelFileAttribute = 0x08;
const unsigned kWinFileDirectoryAttributeMask = 0x10;
enum CHostOS
{
kHostMSDOS = 0,
kHostOS2 = 1,
kHostWin32 = 2,
kHostUnix = 3,
kHostMacOS = 4,
kHostBeOS = 5
};
}
namespace NBlock
{
const UInt16 kLongBlock = 1 << 15;
struct CBlock
{
UInt16 CRC;
Byte Type;
UInt16 Flags;
UInt16 HeadSize;
// UInt32 DataSize;
};
}
/*
struct CSubBlock
{
UInt16 HeadCRC;
Byte HeadType;
UInt16 Flags;
UInt16 HeadSize;
UInt32 DataSize;
UInt16 SubType;
Byte Level; // Reserved : Must be 0
};
struct CCommentBlock
{
UInt16 HeadCRC;
Byte HeadType;
UInt16 Flags;
UInt16 HeadSize;
UInt16 UnpSize;
Byte UnpVer;
Byte Method;
UInt16 CommCRC;
};
struct CProtectHeader
{
UInt16 HeadCRC;
Byte HeadType;
UInt16 Flags;
UInt16 HeadSize;
UInt32 DataSize;
Byte Version;
UInt16 RecSectors;
UInt32 TotalBlocks;
Byte Mark[8];
};
*/
}}}
#endif

View File

@@ -0,0 +1,97 @@
// RarItem.h
#ifndef __ARCHIVE_RAR_ITEM_H
#define __ARCHIVE_RAR_ITEM_H
#include "../../../Common/StringConvert.h"
#include "RarHeader.h"
namespace NArchive {
namespace NRar {
struct CRarTime
{
UInt32 DosTime;
Byte LowSecond;
Byte SubTime[3];
};
struct CItem
{
UInt64 Size;
UInt64 PackSize;
CRarTime CTime;
CRarTime ATime;
CRarTime MTime;
UInt32 FileCRC;
UInt32 Attrib;
UInt16 Flags;
Byte HostOS;
Byte UnPackVersion;
Byte Method;
bool CTimeDefined;
bool ATimeDefined;
AString Name;
UString UnicodeName;
Byte Salt[8];
bool Is_Size_Defined() const { return Size != (UInt64)(Int64)-1; }
bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; }
bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 0; }
bool IsCommented() const { return (Flags & NHeader::NFile::kComment) != 0; }
bool IsSplitBefore() const { return (Flags & NHeader::NFile::kSplitBefore) != 0; }
bool IsSplitAfter() const { return (Flags & NHeader::NFile::kSplitAfter) != 0; }
bool HasSalt() const { return (Flags & NHeader::NFile::kSalt) != 0; }
bool HasExtTime() const { return (Flags & NHeader::NFile::kExtTime) != 0; }
bool HasUnicodeName()const { return (Flags & NHeader::NFile::kUnicodeName) != 0; }
bool IsOldVersion() const { return (Flags & NHeader::NFile::kOldVersion) != 0; }
UInt32 GetDictSize() const { return (Flags >> NHeader::NFile::kDictBitStart) & NHeader::NFile::kDictMask; }
bool IsDir() const;
bool IgnoreItem() const;
UInt32 GetWinAttrib() const;
UInt64 Position;
unsigned MainPartSize;
UInt16 CommentSize;
UInt16 AlignSize;
// int BaseFileIndex;
// bool IsAltStream;
UString GetName() const
{
if (( /* IsAltStream || */ HasUnicodeName()) && !UnicodeName.IsEmpty())
return UnicodeName;
return MultiByteToUnicodeString(Name, CP_OEMCP);
}
void Clear()
{
CTimeDefined = false;
ATimeDefined = false;
Name.Empty();
UnicodeName.Empty();
// IsAltStream = false;
// BaseFileIndex = -1;
}
CItem() { Clear(); }
UInt64 GetFullSize() const { return MainPartSize + CommentSize + AlignSize + PackSize; }
// DWORD GetHeaderWithCommentSize() const { return MainPartSize + CommentSize; }
UInt64 GetCommentPosition() const { return Position + MainPartSize; }
UInt64 GetDataPosition() const { return GetCommentPosition() + CommentSize + AlignSize; }
};
}}
#endif

View File

@@ -0,0 +1,129 @@
// RarVol.h
#ifndef __ARCHIVE_RAR_VOL_H
#define __ARCHIVE_RAR_VOL_H
#include "../../../Common/StringConvert.h"
#include "RarHeader.h"
namespace NArchive {
namespace NRar {
inline bool IsDigit(wchar_t c)
{
return c >= L'0' && c <= L'9';
}
class CVolumeName
{
bool _needChangeForNext;
UString _before;
UString _changed;
UString _after;
public:
CVolumeName(): _needChangeForNext(true) {};
bool InitName(const UString &name, bool newStyle = true)
{
_needChangeForNext = true;
_after.Empty();
UString base = name;
int dotPos = name.ReverseFind_Dot();
if (dotPos >= 0)
{
const UString ext = name.Ptr(dotPos + 1);
if (ext.IsEqualTo_Ascii_NoCase("rar"))
{
_after = name.Ptr(dotPos);
base.DeleteFrom(dotPos);
}
else if (ext.IsEqualTo_Ascii_NoCase("exe"))
{
_after.SetFromAscii(".rar");
base.DeleteFrom(dotPos);
}
else if (!newStyle)
{
if (ext.IsEqualTo_Ascii_NoCase("000") ||
ext.IsEqualTo_Ascii_NoCase("001") ||
ext.IsEqualTo_Ascii_NoCase("r00") ||
ext.IsEqualTo_Ascii_NoCase("r01"))
{
_changed = ext;
_before = name.Left(dotPos + 1);
return true;
}
}
}
if (newStyle)
{
unsigned i = base.Len();
for (; i != 0; i--)
if (!IsDigit(base[i - 1]))
break;
if (i != base.Len())
{
_before = base.Left(i);
_changed = base.Ptr(i);
return true;
}
}
_after.Empty();
_before = base;
_before += L'.';
_changed.SetFromAscii("r00");
_needChangeForNext = false;
return true;
}
/*
void MakeBeforeFirstName()
{
unsigned len = _changed.Len();
_changed.Empty();
for (unsigned i = 0; i < len; i++)
_changed += L'0';
}
*/
UString GetNextName()
{
if (_needChangeForNext)
{
unsigned i = _changed.Len();
if (i == 0)
return UString();
for (;;)
{
wchar_t c = _changed[--i];
if (c == L'9')
{
c = L'0';
_changed.ReplaceOneCharAtPos(i, c);
if (i == 0)
{
_changed.InsertAtFront(L'1');
break;
}
continue;
}
c++;
_changed.ReplaceOneCharAtPos(i, c);
break;
}
}
_needChangeForNext = true;
return _before + _changed + _after;
}
};
}}
#endif

View File

@@ -0,0 +1,3 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@@ -0,0 +1,8 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif