📄 simplefilebackup.cpp
字号:
// SimpleFileBackup.cpp: implementation of the CSimpleFileBackup class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SimpleFileBackup.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// Global or Static variable declare
TCHAR g_tsSQLInitializeCrashRecover[] = _T("UPDATE [") TABLE_NAME _T("] SET [") FIELD_FILE_STATUS _T("]=1 WHERE [") FIELD_FILE_STATUS _T("] <> 1");
TCHAR g_tsSQLUpdateChangedFile[] = _T("SELECT [") FIELD_FILE_PATHNAME _T("], [") FIELD_FILE_UPDATETIME _T("], [") FIELD_FILE_STATUS _T("] FROM [") TABLE_NAME _T("] WHERE [") FIELD_FILE_PATHNAME _T("]='%s'");
TCHAR g_tsSQLGetWaitingRecords[] = _T("SELECT [") FIELD_FILE_PATHNAME _T("], [") FIELD_FILE_UPDATETIME _T("], [") FIELD_FILE_STATUS _T("] FROM [") TABLE_NAME _T("] WHERE ([") FIELD_FILE_STATUS _T("] = 1 OR [") FIELD_FILE_STATUS _T("] = 2) AND [") FIELD_FILE_UPDATETIME _T("] <= NOW()");
TCHAR g_tsSQLGetMinWaitTime[] = _T("SELECT [") FIELD_FILE_PATHNAME _T("], [") FIELD_FILE_UPDATETIME _T("], [") FIELD_FILE_STATUS _T("] FROM [") TABLE_NAME _T("] WHERE [") FIELD_FILE_STATUS _T("] = 1 OR [") FIELD_FILE_STATUS _T("] = 2 ORDER BY [") FIELD_FILE_UPDATETIME _T("] ASC");
TCHAR* g_tsSQLStartCopying = g_tsSQLUpdateChangedFile;
//TCHAR* g_tsSQLCancelCopying = g_tsSQLUpdateChangedFile;
TCHAR g_tsSQLFinishedCopying[] = _T("DELETE FROM [") TABLE_NAME _T("] WHERE [") FIELD_FILE_PATHNAME _T("]='%s' AND [") FIELD_FILE_STATUS _T("] = 3");
TCHAR g_tsSQLFailedInCopying[] = _T("UPDATE [") TABLE_NAME _T("] SET [") FIELD_FILE_STATUS _T("]=1 WHERE [") FIELD_FILE_PATHNAME _T("]='%s' AND [") FIELD_FILE_STATUS _T("] = 3");
DWORD CSimpleFileBackup::m_dwOSVersion = ::GetVersion();
CSimpleFileBackup::CBufferManager CSimpleFileBackup::m_objBufferManager;
CSimpleFileBackup::CMessageItemsPool CSimpleFileBackup::CMessageQueue::m_objMessageItemsPool;
//IMPLEMENT_DYNAMIC(CSimpleFileBackup::CDatabaseAccessThread, CWinThread)
#ifdef _AFXDLL
CRuntimeClass* PASCAL CSimpleFileBackup::CDatabaseAccessThread::_GetBaseClass() { return RUNTIME_CLASS(CWinThread); }
AFX_COMDAT const AFX_DATADEF CRuntimeClass CSimpleFileBackup::CDatabaseAccessThread::classCSimpleFileBackup_CDatabaseAccessThread = {
"CSimpleFileBackup_CDatabaseAccessThread",
sizeof(class CSimpleFileBackup::CDatabaseAccessThread),
0xFFFF,
NULL,
&(CSimpleFileBackup::CDatabaseAccessThread::_GetBaseClass),
NULL
};
CRuntimeClass* CSimpleFileBackup::CDatabaseAccessThread::GetRuntimeClass() const { return ((CRuntimeClass*)(&CSimpleFileBackup::CDatabaseAccessThread::classCSimpleFileBackup_CDatabaseAccessThread)); }
#else
AFX_COMDAT const AFX_DATADEF CRuntimeClass CSimpleFileBackup::CDatabaseAccessThread::classCSimpleFileBackup_CDatabaseAccessThread = {
"CSimpleFileBackup_CDatabaseAccessThread",
sizeof(class CSimpleFileBackup::CDatabaseAccessThread),
0xFFFF,
NULL,
RUNTIME_CLASS(CWinThread),
NULL
};
CRuntimeClass* CSimpleFileBackup::CDatabaseAccessThread::GetRuntimeClass() const { return ((CRuntimeClass*)(&CSimpleFileBackup::CDatabaseAccessThread::classCSimpleFileBackup_CDatabaseAccessThread)); }
#endif
BEGIN_MESSAGE_MAP(CSimpleFileBackup::CDatabaseAccessThread, CWinThread)
{ UWM_INITIALIZE_DATABASE, 0, 0, 0, AfxSig_vwl, (AFX_PMSG)(AFX_PMSGT)(void (AFX_MSG_CALL CWinThread::*)(WPARAM, LPARAM))&(CSimpleFileBackup::CDatabaseAccessThread::OnInitializeDatabase) },
{ UWM_UNINITIALIZE_DATABASE, 0, 0, 0, AfxSig_vwl, (AFX_PMSG)(AFX_PMSGT)(void (AFX_MSG_CALL CWinThread::*)(WPARAM, LPARAM))&(CSimpleFileBackup::CDatabaseAccessThread::OnUninitializeDatabase) },
{ UWM_POST_FILE_CHANGES, 0, 0, 0, AfxSig_vwl, (AFX_PMSG)(AFX_PMSGT)(void (AFX_MSG_CALL CWinThread::*)(WPARAM, LPARAM))&(CSimpleFileBackup::CDatabaseAccessThread::OnPostFileChanges) },
{ WM_TIMER, 0, 0, 0, AfxSig_vw, (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT))&(CSimpleFileBackup::CDatabaseAccessThread::OnTimer) },
{ UWM_START_COPYING_FILE_CALLBACK, 0, 0, 0, AfxSig_vwl, (AFX_PMSG)(AFX_PMSGT)(void (AFX_MSG_CALL CWinThread::*)(WPARAM, LPARAM))&(CSimpleFileBackup::CDatabaseAccessThread::OnStartCopyingFileCallback) },
{ UWM_CANCEL_COPYING_FILE_CALLBACK, 0, 0, 0, AfxSig_vwl, (AFX_PMSG)(AFX_PMSGT)(void (AFX_MSG_CALL CWinThread::*)(WPARAM, LPARAM))&(CSimpleFileBackup::CDatabaseAccessThread::OnCancelCopyingFileCallback) },
{ UWM_FINISHED_COPYING_FILE_CALLBACK, 0, 0, 0, AfxSig_vwl, (AFX_PMSG)(AFX_PMSGT)(void (AFX_MSG_CALL CWinThread::*)(WPARAM, LPARAM))&(CSimpleFileBackup::CDatabaseAccessThread::OnFinishedCopyingFileCallback) },
{ UWM_FAILED_IN_COPYING_FILE_CALLBACK, 0, 0, 0, AfxSig_vwl, (AFX_PMSG)(AFX_PMSGT)(void (AFX_MSG_CALL CWinThread::*)(WPARAM, LPARAM))&(CSimpleFileBackup::CDatabaseAccessThread::OnFailedInCopyingFileCallback) },
{ UWM_SET_LOG_MODE, 0, 0, 0, AfxSig_vwl, (AFX_PMSG)(AFX_PMSGT)(void (AFX_MSG_CALL CWinThread::*)(WPARAM, LPARAM))&(CSimpleFileBackup::CDatabaseAccessThread::OnSetLogMode) },
END_MESSAGE_MAP()
BOOL CSimpleFileBackup::CFilenameMaskList::CFilenameMask::IsSubNameMatch(LPCTSTR pcstrMask, LPCTSTR pcstrName)
{
LPCTSTR pMask = pcstrMask, pName = pcstrName;
LPCTSTR pTempMask, pTempName;
int nCharLimit = 0;
while ( 1 )
{
if ( *pMask == _T('*') )
nCharLimit = INT_MAX;
else if ( *pMask == _T('?') )
{
if ( nCharLimit != INT_MAX )
nCharLimit++;
}
else
break;
pMask++;
}
if ( *pMask == NULL )
return _tcslen(pName) <= (unsigned int)nCharLimit;
while ( nCharLimit-- >= 0 && *pName != NULL )
{
pTempMask = pMask;
pTempName = pName;
while ( 1 )
{
if ( *pTempMask == _T('*') || *pTempMask == _T('?') )
{
if ( IsSubNameMatch(pTempMask, pTempName) )
return TRUE;
else
break;
}
else
{
if ( *pTempMask != *pTempName )
break;
else if ( *pTempMask == NULL )
return TRUE;
}
pTempMask++;
pTempName++;
}
pName++;
}
return FALSE;
}
BOOL CSimpleFileBackup::CFilenameMaskList::CFilenameMask::IsSubNameMatchWithoutDot(LPCTSTR pcstrMask, LPCTSTR pcstrName)
{
LPCTSTR pMask = pcstrMask, pName = pcstrName;
LPCTSTR pTempMask, pTempName;
int nCharLimit = 0;
while ( 1 )
{
if ( *pMask == _T('*') )
nCharLimit = INT_MAX;
else if ( *pMask == _T('?') )
{
if ( nCharLimit != INT_MAX )
nCharLimit++;
}
else
break;
pMask++;
}
if ( *pMask == NULL )
return _tcslen(pName) <= (unsigned int)nCharLimit;
pTempMask = pMask;
pTempName = pName;
while ( nCharLimit-- >= 0 && *pName != NULL )
{
while ( 1 )
{
if ( *pTempMask == _T('*') || *pTempMask == _T('?') )
{
if ( IsSubNameMatchWithoutDot(pTempMask, pTempName) )
return TRUE;
else
break;
}
else
{
if ( *pTempMask != *pTempName )
{
if ( *pTempName == NULL && *pTempMask == _T('.') && *(pTempMask + 1) == NULL )
return TRUE;
else
break;
}
else if ( *pTempMask == NULL )
return TRUE;
}
pTempMask++;
pTempName++;
}
pTempMask = pMask;
pTempName = ++pName;
}
return *pName == 0 && *pTempMask == _T('.') && *(pTempMask + 1) == NULL;
}
BOOL CSimpleFileBackup::CFileFilter::CParsedPathItem::AddIncludePath(LPCTSTR pctsPath, LPCTSTR pctsFilenameMask, BOOL fIsIncludeFilenameMask, DWORD* pdwFileAttributesMask, BOOL fIsIncludeFileAttributesMask)
{
if ( (m_dwFlags & CParsedPathItem::ITEM_TYPE_MASK) != CParsedPathItem::INTERMEDIA_ITEM )
return FALSE;
switch ( m_dwFlags & CParsedPathItem::ITEM_MASK )
{
case CParsedPathItem::ROOT_ITEM:
{
CParsedPathItem *pPrevChild, *pChild;
int nDrive;
BOOL fIsLastName;
DWORD dwFlags = 0;
if ( pctsPath[1] != _T(':') || pctsPath[2] != NULL && pctsPath[2] != _T('\\') )
return FALSE;
else if ( *pctsPath >= _T('A') && *pctsPath <= _T('Z') )
nDrive = *pctsPath - _T('A');
else if ( *pctsPath >= _T('a') && *pctsPath <= _T('z') )
nDrive = *pctsPath - _T('a');
else
return FALSE;
if ( (fIsLastName = pctsPath[2] == NULL || pctsPath[2] == _T('\\') && pctsPath[3] == NULL) )
{
dwFlags = CParsedPathItem::DRIVE_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;
}
else
dwFlags = CParsedPathItem::DRIVE_ITEM | CParsedPathItem::INTERMEDIA_ITEM;
pPrevChild = NULL;
pChild = m_pFirstChild;
while ( pChild && (int)pChild->m_ptsName < nDrive )
{
pPrevChild = pChild;
pChild = pChild->m_pNextSibling;
}
if ( pChild && nDrive == (int)pChild->m_ptsName )
{
if ( fIsLastName )
return pChild->SetItemData(pctsPath, pctsFilenameMask, pdwFileAttributesMask ? *pdwFileAttributesMask : 0, dwFlags);
else
return pChild->AddIncludePath(pctsPath + 3, pctsFilenameMask, fIsIncludeFilenameMask, pdwFileAttributesMask, fIsIncludeFileAttributesMask);
}
else
{
pChild = new CParsedPathItem(this, pctsPath, pctsFilenameMask, pdwFileAttributesMask ? *pdwFileAttributesMask : 0, dwFlags);
if ( pPrevChild == NULL )
{
pChild->m_pNextSibling = m_pFirstChild;
m_pFirstChild = pChild;
}
else
{
pChild->m_pNextSibling = pPrevChild->m_pNextSibling;
pPrevChild->m_pNextSibling = pChild;
}
if ( fIsLastName )
return TRUE;
else
return pChild->AddIncludePath(pctsPath + 3, pctsFilenameMask, fIsIncludeFilenameMask, pdwFileAttributesMask, fIsIncludeFileAttributesMask);
}
}
case CParsedPathItem::DRIVE_ITEM:
case CParsedPathItem::DIRECTORY_OR_FILE_ITEM:
{
CParsedPathItem *pPrevChild = NULL, *pChild = m_pFirstChild;
TCHAR tsPathName[MAX_PATH];
int nLen;
BOOL fIsLastName;
DWORD dwFlags = 0;
int nCompare;
for ( nLen = 0; pctsPath[nLen] && pctsPath[nLen] != _T('\\'); nLen++ )
tsPathName[nLen] = LOWER(pctsPath[nLen]);
tsPathName[nLen] = NULL;
if ( (fIsLastName = pctsPath[nLen] == NULL || pctsPath[nLen] == _T('\\') && pctsPath[nLen + 1] == NULL) )
{
dwFlags = CParsedPathItem::DIRECTORY_OR_FILE_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;
}
else
dwFlags = CParsedPathItem::DIRECTORY_OR_FILE_ITEM | CParsedPathItem::INTERMEDIA_ITEM;
nCompare = -1;
while ( pChild && (nLen != *(pChild->m_ptsName - 1) || (nCompare = _tcsncmp(pChild->m_ptsName, tsPathName, nLen)) < 0) )
{
pPrevChild = pChild;
pChild = pChild->m_pNextSibling;
}
if ( pChild && nCompare == 0 )
{
if ( fIsLastName )
return pChild->SetItemData(tsPathName, pctsFilenameMask, pdwFileAttributesMask ? *pdwFileAttributesMask : 0, dwFlags);
else
return pChild->AddIncludePath(pctsPath + nLen + 1, pctsFilenameMask, fIsIncludeFilenameMask, pdwFileAttributesMask, fIsIncludeFileAttributesMask);
}
else
{
pChild = new CParsedPathItem(this, tsPathName, pctsFilenameMask, pdwFileAttributesMask ? *pdwFileAttributesMask : 0, dwFlags);
if ( pPrevChild == NULL )
{
pChild->m_pNextSibling = m_pFirstChild;
m_pFirstChild = pChild;
}
else
{
pChild->m_pNextSibling = pPrevChild->m_pNextSibling;
pPrevChild->m_pNextSibling = pChild;
}
if ( fIsLastName )
return TRUE;
else
return pChild->AddIncludePath(pctsPath + nLen + 1, pctsFilenameMask, fIsIncludeFilenameMask, pdwFileAttributesMask, fIsIncludeFileAttributesMask);
}
}
}
return FALSE;
}
BOOL CSimpleFileBackup::CFileFilter::CParsedPathItem::AddExcludePath(LPCTSTR pctsPath, BOOL fUnderIncludePath)
{
switch ( m_dwFlags & CParsedPathItem::ITEM_TYPE_MASK )
{
case CParsedPathItem::EXCLUDE_ITEM:
return FALSE;
case CParsedPathItem::INCLUDE_ITEM:
fUnderIncludePath = TRUE;
}
switch ( m_dwFlags & CParsedPathItem::ITEM_MASK )
{
case CParsedPathItem::ROOT_ITEM:
{
CParsedPathItem *pPrevChild, *pChild;
int nDrive;
BOOL fIsLastName;
if ( pctsPath[1] != _T(':') )
return FALSE;
else if ( *pctsPath >= _T('A') && *pctsPath <= _T('Z') )
nDrive = *pctsPath - _T('A');
else if ( *pctsPath >= _T('a') && *pctsPath <= _T('z') )
nDrive = *pctsPath - _T('a');
else
return FALSE;
fIsLastName = pctsPath[2] == NULL || pctsPath[2] == _T('\\') && pctsPath[3] == NULL;
pPrevChild = NULL;
pChild = m_pFirstChild;
while ( pChild && (int)pChild->m_ptsName < nDrive )
{
pPrevChild = pChild;
pChild = pChild->m_pNextSibling;
}
if ( pChild && nDrive == (int)pChild->m_ptsName )
{
if ( fIsLastName )
return pChild->SetItemData(pctsPath, NULL, 0, CParsedPathItem::EXCLUDE_ITEM | CParsedPathItem::DRIVE_ITEM);
else
return pChild->AddExcludePath(pctsPath + 3, fUnderIncludePath);
}
if ( !fUnderIncludePath )
return FALSE;
else
{
pChild = new CParsedPathItem(this, pctsPath, NULL, 0, fIsLastName ? (CParsedPathItem::EXCLUDE_ITEM | CParsedPathItem::DRIVE_ITEM) : (CParsedPathItem::INTERMEDIA_ITEM | CParsedPathItem::DRIVE_ITEM));
if ( pPrevChild == NULL )
{
pChild->m_pNextSibling = m_pFirstChild;
m_pFirstChild = pChild;
}
else
{
pChild->m_pNextSibling = pPrevChild->m_pNextSibling;
pPrevChild->m_pNextSibling = pChild;
}
if ( fIsLastName )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -