📄 simplefilebackup.h
字号:
inline BOOL IsNormalItem() const { return (m_dwFlags & ITEM_MASK) == DIRECTORY_OR_FILE_ITEM ? TRUE : FALSE; }
inline BOOL IsIncludeItem() const { return (m_dwFlags & ITEM_TYPE_MASK) == INCLUDE_ITEM ? TRUE : FALSE; }
inline BOOL IsExcludeItem() const { return (m_dwFlags & ITEM_TYPE_MASK) == EXCLUDE_ITEM ? TRUE : FALSE; }
inline BOOL IsIntermediaItem() const { return (m_dwFlags & ITEM_TYPE_MASK) == INTERMEDIA_ITEM ? TRUE : FALSE; }
protected:
inline BOOL SetItemData(LPCTSTR pctsItemName, LPCTSTR pctsFilenameMask, DWORD dwFileAttributesMask, DWORD dwFlags)
{
ClearItemData();
switch ( dwFlags & ITEM_MASK )
{
case ROOT_ITEM:
m_ptsName = NULL;
break;
case DRIVE_ITEM:
if ( pctsItemName == NULL || !(*pctsItemName >= _T('A') && *pctsItemName <= _T('Z') || *pctsItemName >= _T('a') && *pctsItemName <= _T('z')) )
return FALSE;
m_ptsName = (LPTSTR)(*pctsItemName >= _T('a') ? *pctsItemName - _T('a') : *pctsItemName - _T('A'));
break;
case DIRECTORY_OR_FILE_ITEM:
if ( pctsItemName && *pctsItemName != NULL && *pctsItemName != _T('\\') )
{
LPTSTR pTChar = (LPTSTR)pctsItemName;
int nLen;
while ( *pTChar != NULL && *pTChar != _T('\\') )
pTChar++;
nLen = pTChar - pctsItemName;
m_ptsName = (pTChar = new TCHAR[nLen + 2]) + 1;
*pTChar++ = nLen;
while ( nLen-- > 0 )
{
*pTChar++ = LOWER(*pctsItemName); // *pctsItemName >= _T('a') && *pctsItemName <= _T('z') ? *pctsItemName - _T('a') + _T('A') : *pctsItemName;
pctsItemName++;
}
*pTChar = NULL;
break;
}
default:
return FALSE;
}
if ( (dwFlags & ITEM_TYPE_MASK) != INCLUDE_ITEM )
dwFlags &= ITEM_TYPE_MASK | ITEM_MASK;
else
{
if ( (dwFlags & FILENAME_MASK_MASK) && pctsFilenameMask )
{
CFilenameMaskList* pFilenameMaskList = new CFilenameMaskList(pctsFilenameMask);
if ( pFilenameMaskList->IsAvailable(_T("*.*")) )
{
delete pFilenameMaskList;
if ( (dwFlags & FILENAME_MASK_MASK) == INCLUDE_FILENAME_MASK )
dwFlags &= ~FILENAME_MASK_MASK;
else
dwFlags = dwFlags & ITEM_MASK | EXCLUDE_ITEM;
}
else
m_pFilenameMaskList = pFilenameMaskList;
}
if ( dwFlags & FILE_ATTRIBUTES_MASK_MASK )
m_dwFileAttributesMask = dwFileAttributesMask;
}
m_dwFlags = dwFlags;
return TRUE;
}
inline void ClearItemData()
{
if ( m_pFirstChild )
delete m_pFirstChild;
if ( m_pNextSibling )
delete m_pNextSibling;
if ( (m_dwFlags & ITEM_MASK) == DIRECTORY_OR_FILE_ITEM && m_ptsName )
delete[] (m_ptsName - 1);
m_ptsName = NULL;
if ( m_pFilenameMaskList )
{
delete m_pFilenameMaskList;
m_pFilenameMaskList = NULL;
}
m_dwFlags = m_dwFileAttributesMask = NULL;
}
protected:
DWORD m_dwFlags;
LPTSTR m_ptsName;
CFilenameMaskList* m_pFilenameMaskList;
DWORD m_dwFileAttributesMask;
CParsedPathItem* m_pFirstChild;
CParsedPathItem* m_pNextSibling;
CParsedPathItem* m_pParent;
};
inline CFileFilter() : m_pRootParsedPathItem(NULL) {}
inline ~CFileFilter() { if ( m_pRootParsedPathItem ) delete m_pRootParsedPathItem; }
inline void Reset() { if ( m_pRootParsedPathItem ) delete m_pRootParsedPathItem; m_pRootParsedPathItem = NULL; }
inline BOOL AddIncludePath(LPCTSTR pctsPath, LPCTSTR pctsFilenameMask, BOOL fIsIncludeFilenameMask, DWORD* pdwFileAttributesMask, BOOL fIsIncludeFileAttributesMask)
{
if ( pctsPath && *pctsPath )
{
if ( pctsPath[1] != _T(':') || pctsPath[2] != NULL && pctsPath[2] != _T('\\') || !(*pctsPath >= _T('a') && *pctsPath <= _T('z') || *pctsPath >= _T('A') && *pctsPath <= _T('Z')) )
return FALSE;
if ( !m_pRootParsedPathItem )
m_pRootParsedPathItem = new CParsedPathItem(NULL, NULL, 0, CParsedPathItem::ROOT_ITEM | CParsedPathItem::INTERMEDIA_ITEM);
return m_pRootParsedPathItem->AddIncludePath(pctsPath, pctsFilenameMask, fIsIncludeFilenameMask, pdwFileAttributesMask, fIsIncludeFileAttributesMask);
}
else
{
DWORD dwFlags = CParsedPathItem::ROOT_ITEM | CParsedPathItem::INCLUDE_ITEM;
if ( pctsFilenameMask )
dwFlags |= fIsIncludeFilenameMask ? CParsedPathItem::INCLUDE_FILENAME_MASK : CParsedPathItem::EXCLUDE_FILENAME_MASK;
if ( pdwFileAttributesMask )
dwFlags |= fIsIncludeFileAttributesMask ? CParsedPathItem::INCLUDE_FILE_ATTRIBUTES_MASK : CParsedPathItem::EXCLUDE_FILE_ATTRIBUTES_MASK;
if ( !m_pRootParsedPathItem )
{
m_pRootParsedPathItem = new CParsedPathItem(NULL, pctsFilenameMask, pdwFileAttributesMask ? *pdwFileAttributesMask : 0, dwFlags);
return TRUE;
}
else
return m_pRootParsedPathItem->SetItemData(NULL, pctsFilenameMask, pdwFileAttributesMask ? *pdwFileAttributesMask : 0, dwFlags);
}
}
inline BOOL AddExcludePath(LPCTSTR pctsPath)
{
if ( !m_pRootParsedPathItem )
return FALSE;
else
return m_pRootParsedPathItem->AddExcludePath(pctsPath, FALSE);
}
inline BOOL MatchFilePathname(LPCTSTR pctsFilePathname)
{
if ( pctsFilePathname == NULL || m_pRootParsedPathItem == NULL )
return FALSE;
else
return m_pRootParsedPathItem->MatchFilePathname(pctsFilePathname);
}
inline CParsedPathItem::PARSED_PATH_ITEM_FLAGS_BIT_MASK MatchFilePathname(LPCTSTR pctsFilePathname, CParsedPathItem*& pItem)
{
if ( pctsFilePathname == NULL || m_pRootParsedPathItem == NULL )
return CParsedPathItem::EXCLUDE_ITEM;
else
return m_pRootParsedPathItem->MatchFilePathname(pctsFilePathname, pItem);
}
inline BOOL GetDriveBasePath(TCHAR tDrive, CString& csBasePath, CParsedPathItem*& pItem)
{
if ( !m_pRootParsedPathItem || !(tDrive >= _T('A') && tDrive <= _T('Z') || tDrive >= _T('a') && tDrive <= _T('z')) )
return FALSE;
else
{
CParsedPathItem *pDriveItem = m_pRootParsedPathItem->m_pFirstChild, *pTempItem;
int nDrive = tDrive >= _T('a') ? tDrive - _T('a') : tDrive - _T('A');
int nLen;
LPTSTR pBuf;
BOOL fOnlyDrive;
while ( pDriveItem && (int)pDriveItem->m_ptsName < nDrive )
pDriveItem = pDriveItem->m_pNextSibling;
if ( !pDriveItem || (int)pDriveItem->m_ptsName != nDrive )
return FALSE;
for ( nLen = 2, pTempItem = pDriveItem->m_pFirstChild; pTempItem && !pTempItem->m_pNextSibling; pTempItem = pTempItem->m_pFirstChild )
nLen += *(pTempItem->m_ptsName - 1) + 1;
if ( nLen < 3 )
{
fOnlyDrive = TRUE;
nLen = 3;
}
else
fOnlyDrive = FALSE;
pBuf = csBasePath.GetBuffer(nLen);
*pBuf++ = _T('a') + nDrive;
*pBuf++ = _T(':');
while ( pDriveItem->m_pFirstChild && !pDriveItem->m_pFirstChild->m_pNextSibling )
{
pDriveItem = pDriveItem->m_pFirstChild;
*pBuf++ = _T('\\');
_tcscpy(pBuf, pDriveItem->m_ptsName);
pBuf += *(pDriveItem->m_ptsName - 1);
}
pItem = pDriveItem;
if ( fOnlyDrive )
*pBuf++ = _T('\\');
csBasePath.ReleaseBuffer(nLen);
return TRUE;
}
}
inline CParsedPathItem* GetFirstAvailableDrive()
{
return !m_pRootParsedPathItem ? NULL : m_pRootParsedPathItem->m_pFirstChild;
}
inline TCHAR GetNextAvailableDrive(CParsedPathItem*& pDriveItem)
{
TCHAR tRet = NULL;
if ( pDriveItem && (pDriveItem->m_dwFlags & CParsedPathItem::ITEM_MASK) == CParsedPathItem::DRIVE_ITEM )
{
tRet = _T('a') + (int)pDriveItem->m_ptsName;
pDriveItem = pDriveItem->m_pNextSibling;
}
return tRet;
}
// Must return long pathname, actually this class should handle long pathname only
inline BOOL GetNextAvailableDriveBasePath(CParsedPathItem*& pDriveItem, CString& csBasePath, CParsedPathItem*& pItem)
{
TCHAR tDriveName;
if ( (tDriveName = GetNextAvailableDrive(pDriveItem)) == NULL )
return FALSE;
return GetDriveBasePath(tDriveName, csBasePath, pItem);
}
inline void GetIncludeItems(CStringList& objStringList, CList<CParsedPathItem*, CParsedPathItem*>& objList)
{
if ( m_pRootParsedPathItem != NULL )
m_pRootParsedPathItem->GetIncludeItems(objStringList, objList);
}
protected:
CParsedPathItem * m_pRootParsedPathItem;
};
class CRevisionInfo
{
public:
class CRevisionPath
{
public:
friend class CRevisionInfo;
inline CRevisionPath()
{
m_u64UTCRevisionTime.QuadPart = 0;
}
inline CRevisionPath& operator = (const CRevisionPath& rev)
{
m_csPathname = rev.m_csPathname;
m_u64UTCRevisionTime.QuadPart = rev.m_u64UTCRevisionTime.QuadPart;
return *this;
}
/*
inline CRevisionPath& operator = (const CRevisionPath rev)
{
m_csPathname = rev.m_csPathname;
m_u64UTCCreateDateTime = rev.m_u64UTCCreateDateTime;
m_objLocalCreateDateTime = rev.m_objLocalCreateDateTime;
}
inline BOOL WinNTSet(CString csPathname, ULARGE_INTEGER u64UTCCreateDateTime)
{
LPWSTR pws = (LPWSTR)CSimpleFileBackup::AllocateBuffer();
WIN32_FIND_DATAW objFindData;
HANDLE hFind;
m_csPathname = csPathname;
pws[0] = L'\\';
pws[1] = L'\\';
pws[2] = L'?';
pws[3] = L'\\';
#ifdef UNICODE
wcscpy(pws + 4, m_csPathname);
#else
if ( ::MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)csPathname, -1, pws + 4, CSimpleFileBackup::GetBlockSize() - 4 * sizeof(WCHAR)) == 0 )
{
CSimpleFileBackup::FreeBuffer(pws);
return FALSE;
}
#endif
if ( m_u64UTCCreateDateTime.QuadPart == 0 )
{
hFind = ::FindFirstFileW(pws, &objFindData);
if ( hFind == INVALID_HANDLE_VALUE )
{
CSimpleFileBackup::FreeBuffer(pws);
return FALSE;
}
::FindClose(hFind);
m_u64UTCCreateDateTime.HighPart = objFindData.ftCreationTime.dwHighDateTime;
m_u64UTCCreateDateTime.LowPart = objFindData.ftCreationTime.dwLowDateTime;
m_objLocalCreateDateTime = CTime(objFindData.ftCreationTime);
CSimpleFileBackup::FreeBuffer(pws);
return TRUE;
}
else
{
HANDLE hFile;
BOOL fRet;
m_u64UTCCreateDateTime.QuadPart = u64UTCCreateDateTime.QuadPart;
m_objLocalCreateDateTime = CTime((FILETIME&)u64UTCCreateDateTime);
CSimpleFileBackup::CreateDirectory(pws);
hFile = ::CreateFileW(pws, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if ( hFile == INVALID_HANDLE_VALUE )
{
CSimpleFileBackup::FreeBuffer(pws);
return FALSE;
}
fRet = SetFileTime(hFile, (FILETIME*)&u64UTCCreateDateTime, NULL, NULL);
CSimpleFileBackup::FreeBuffer(pws);
return fRet;
}
}
inline BOOL Win9xSet(CString csPathname, ULARGE_INTEGER u64UTCCreateDateTime)
{
m_csPathname = csPathname;
if ( u64UTCCreateDateTime.QuadPart == 0 )
{
WIN32_FIND_DATA objFindData;
HANDLE hFind;
hFind = ::FindFirstFile((LPCTSTR)csPathname, &objFindData);
if ( hFind == INVALID_HANDLE_VALUE )
return FALSE;
FindClose(hFind);
m_u64UTCCreateDateTime.HighPart = objFindData.ftCreationTime.dwHighDateTime;
m_u64UTCCreateDateTime.LowPart = objFindData.ftCreationTime.dwLowDateTime;
m_objLocalCreateDateTime = CTime(objFindData.ftCreationTime);
return TRUE;
}
else
{
CSimpleFileBackup::CreateDirectory((LPCTSTR)m_csPathname);
m_u64UTCCreateDateTime.QuadPart = u64UTCCreateDateTime.QuadPart;
m_objLocalCreateDateTime = CTime((FILETIME&)u64UTCCreateDateTime);
}
}
*/
protected:
CString m_csPathname;
ULARGE_INTEGER m_u64UTCRevisionTime;
};
typedef CList<CRevisionPath, CRevisionPath&> CRevisionPaths;
public:
inline CRevisionInfo() : m_dwMaxRevision(0), m_fIncrementBackup(TRUE)
{
m_u64RevisionInterval.QuadPart = (unsigned __int64)24 * 60 * 60 * 10 * 1000 * 1000;
}
inline CRevisionInfo(const CString& csBaseDestinationPath, DWORD dwMaxRevision, ULARGE_INTEGER u64RevisionIntervalTime, const CStringList& objRevisionRelativePaths)
{
SetRevisionInfo(csBaseDestinationPath, dwMaxRevision, u64RevisionIntervalTime, objRevisionRelativePaths);
}
inline void SetRevisionInfo(const CString& csBaseDestinationPath, DWORD dwMaxRevision, DWORD dwIntervalInMillisecond, const CStringList& objRevisionRelativePaths)
{
ULARGE_INTEGER u64;
u64.QuadPart = (unsigned __int64)dwIntervalInMillisecond * 10 * 1000;
SetRevisionInfo(csBaseDestinationPath, dwMaxRevision, u64, objRevisionRelativePaths);
}
inline void SetRevisionInfo(const CString& csBaseDestinationPath, DWORD dwMaxRevision = 0, DWORD dwIntervalInMillisecond = 24 * 60 * 60 * 1000)
{
}
inline BOOL IsIncrementBackup() const { return m_fIncrementBackup; }
inline void SetRevisionInfo(const CString& csBaseDestinationPath, DWORD dwMaxRevision, ULARGE_INTEGER u64RevisionIntervalTime, const CStringList& objRevisionRelativePaths)
{
CRevisionPath objRevisionPath;
POSITION pos;
SYSTEMTIME objSystemTime = {0};
FILETIME objFileTime, objUTCFileTime;
// if ( CSimpleFileBackup::IsNT() )
// m_csBaseDestinationPath.Format(_T("\\\\?\\%s"), (LPCTSTR)(csBaseDestinationPath.GetAt(csBaseDestinationPath.GetLength() - 1) == _T('\\') ? csBaseDestinationPath.Left(csBaseDestinationPath.GetLength() - 1) : csBaseDestinationPath));
// else
m_csBaseDestinationPath = csBaseDestinationPath.GetAt(csBaseDestinationPath.GetLength() - 1) == _T('\\') ? csBaseDestinationPath.Left(csBaseDestinationPath.GetLength() - 1) : csBaseDestinationPath;
m_dwMaxRevision = dwMaxRevision;
m_u64RevisionInterval.QuadPart = u64RevisionIntervalTime.QuadPart;
pos = objRevisionRelativePaths.GetHeadPosition();
while ( pos )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -