📄 simplefilebackup.cpp
字号:
return TRUE;
else
return pChild->AddExcludePath(pctsPath + 3, fUnderIncludePath);
}
}
case CParsedPathItem::DRIVE_ITEM:
case CParsedPathItem::DIRECTORY_OR_FILE_ITEM:
{
CParsedPathItem *pPrevChild = NULL, *pChild = m_pFirstChild;
TCHAR tsPathName[MAX_PATH];
int nLen;
BOOL fIsLastName;
int nCompare;
for ( nLen = 0; pctsPath[nLen] && pctsPath[nLen] != _T('\\'); nLen++ )
tsPathName[nLen] = LOWER(pctsPath[nLen]);
tsPathName[nLen] = NULL;
fIsLastName = pctsPath[nLen] == NULL || pctsPath[nLen] == _T('\\') && pctsPath[nLen + 1] == NULL;
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, NULL, 0, CParsedPathItem::EXCLUDE_ITEM | CParsedPathItem::DIRECTORY_OR_FILE_ITEM);
else
return pChild->AddExcludePath(pctsPath + nLen + 1, fUnderIncludePath);
}
if ( !fUnderIncludePath )
return FALSE;
else
{
pChild = new CParsedPathItem(this, tsPathName, NULL, 0, fIsLastName ? (CParsedPathItem::EXCLUDE_ITEM | CParsedPathItem::DIRECTORY_OR_FILE_ITEM) : (CParsedPathItem::INTERMEDIA_ITEM | CParsedPathItem::DIRECTORY_OR_FILE_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 )
return TRUE;
else
return pChild->AddExcludePath(pctsPath + nLen + 1, fUnderIncludePath);
}
}
}
return FALSE;
}
UINT CSimpleFileBackup::CWorkerThread::DummyThreadProc(CWorkerThread* pThis)
{
UINT nRet = pThis->m_pfnCustomThreadProc(pThis->m_pCustomThreadProcParam);
if ( nRet == ERROR_SUCCESS )
return pThis->ExitInstance();
else
{
pThis->ExitInstance();
return nRet;
}
}
UINT CSimpleFileBackup::CWinNTFileChangesHandlerThread::FileChangesHandlerThreadProc(CWinNTFileChangesHandlerThread* pThis)
{
DWORD dwWaitResult;
UINT nMsg;
WPARAM wParam;
LPARAM lParam;
while ( 1 )
{
dwWaitResult = ::WaitForMultipleObjects(pThis->m_nHandleNumber, pThis->m_arrayHandleBank, FALSE, INFINITE);
if ( dwWaitResult < WAIT_ABANDONED_0 )
{
FILETIME tSystemTime;
ULARGE_INTEGER tCurrent; // Get current time
DWORD dwStartTickCount = ::GetTickCount(), dwEndTickCount;
BOOL fHandled[27] = {FALSE};
__tag_AccessoryItem* pAccessory;
::GetSystemTimeAsFileTime(&tSystemTime);
tCurrent.LowPart = tSystemTime.dwLowDateTime;
tCurrent.HighPart = tSystemTime.dwHighDateTime;
// Handle Event
if ( dwWaitResult == WAIT_OBJECT_0 )
{
// Got new message
if ( pThis->PeekFirstMessage(nMsg, wParam, lParam) )
{
switch ( nMsg )
{
case UWM_DESTROY_WORKERTHREAD:
{
DWORD dwRet = pThis->OnStopLogging();
pThis->ReturnMessageResult(wParam, dwRet);
return dwRet;
}
case UWM_START_LOGGING_FILE_CHANGES:
pThis->ReturnMessageResult(wParam, pThis->OnStartLogging((CFileFilter*)lParam));
break;
case UWM_STOP_LOGGING_FILE_CHANGES:
pThis->ReturnMessageResult(wParam, pThis->OnStopLogging());
break;
}
}
dwWaitResult++;
}
// Handle File Changes
for ( pAccessory = pThis->m_arrayAccessoryBank + (dwWaitResult - 1); (int)dwWaitResult < pThis->m_nHandleNumber; dwWaitResult++, pAccessory++ )
if ( WaitForSingleObject(pThis->m_arrayHandleBank[dwWaitResult], 0) == WAIT_OBJECT_0 )
{
// Some files changed
pThis->HandleFileChanges(tCurrent, pAccessory);
fHandled[dwWaitResult] = TRUE;
}
// Give up time slice (This is a message provider rather than receiver so that we can handle other message later)
dwEndTickCount = ::GetTickCount();
if ( dwEndTickCount > dwStartTickCount )
{
dwEndTickCount -= dwStartTickCount;
if ( dwEndTickCount <= 40 )
Sleep(50 - dwEndTickCount);
}
// Start reading file changes
for ( dwWaitResult = 1, pAccessory = pThis->m_arrayAccessoryBank; (int)dwWaitResult < pThis->m_nHandleNumber; dwWaitResult++, pAccessory++ )
if ( fHandled[dwWaitResult] )
{
ResetEvent(pThis->m_arrayHandleBank[dwWaitResult]);
if ( !ReadDirectoryChangesW(pAccessory->m_hFile, pAccessory->m_pBuffer, CSimpleFileBackup::GetBlockSize(), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, NULL, &pAccessory->m_objOverlapped, NULL) )
{
DWORD dwErrorCode = ::GetLastError();
switch ( pThis->ErrorCallback(CHANGESHANDLER_READDIRECTORYCHANGESW_FAILED, (LPCTSTR)pAccessory->m_csPath, NULL, dwErrorCode) )
{
case PROGRESS_CANCEL:
case PROGRESS_STOP:
pThis->OnStopLogging();
return dwErrorCode;
}
}
}
}
else
{
if ( dwWaitResult == WAIT_ABANDONED_0 )
{
// Something wrong with the message queue
DWORD dwErrorCode = ::GetLastError();
pThis->ErrorCallback(CHANGESHANDLER_MESSAGE_QUEUE_SEMAPHORE_ABANDONED, NULL, NULL, dwErrorCode);
return dwErrorCode;
}
else
{
// Something wrong with the overlapped event
// or WaitForSingleObject function failed
DWORD dwErrorCode = ::GetLastError();
switch ( pThis->ErrorCallback(dwWaitResult == WAIT_FAILED ? CHANGESHANDLER_WAITFORSINGLEOBJECT_FAILED : CHANGESHANDLER_OVERLAPPED_EVENT_ABANDONED, NULL, NULL, dwErrorCode) )
{
case PROGRESS_CANCEL:
case PROGRESS_STOP:
pThis->OnStopLogging();
return dwErrorCode;
}
}
}
}
return ERROR_SUCCESS;
}
UINT CSimpleFileBackup::CWin9xFileChangesHandlerThread::FileChangesHandlerThreadProc(CWin9xFileChangesHandlerThread* pThis)
{
DWORD dwWaitResult;
UINT nMsg;
WPARAM wParam;
LPARAM lParam;
while ( 1 )
{
dwWaitResult = ::WaitForMultipleObjects(pThis->IsLogging() ? 2 : 1, pThis->m_arrayHandleBank, FALSE, INFINITE);
if ( dwWaitResult < WAIT_ABANDONED_0 )
{
// time_t tCurrent = time(NULL); // Get current time
DWORD dwStartTickCount = ::GetTickCount(), dwEndTickCount;
// Handle Event
if ( dwWaitResult == WAIT_OBJECT_0 )
{
// Got new message
if ( pThis->PeekFirstMessage(nMsg, wParam, lParam) )
switch ( nMsg )
{
case UWM_DESTROY_WORKERTHREAD:
{
DWORD dwRet = pThis->OnStopLogging();
pThis->ReturnMessageResult(wParam, dwRet);
return dwRet;
}
case UWM_START_LOGGING_FILE_CHANGES:
pThis->ReturnMessageResult(wParam, pThis->OnStartLogging((CFileFilter*)lParam));
break;
case UWM_STOP_LOGGING_FILE_CHANGES:
pThis->ReturnMessageResult(wParam, pThis->OnStopLogging());
break;
}
}
// Handle File Changes
if ( pThis->IsLogging() && WaitForSingleObject(pThis->m_arrayHandleBank[1], 0) == WAIT_OBJECT_0 )
{
// Some files changed
pThis->HandleFileChanges();
// Give up time slice (This is a message provider rather than receiver so that we can handle other message later)
dwEndTickCount = ::GetTickCount();
if ( dwEndTickCount > dwStartTickCount )
{
dwEndTickCount -= dwStartTickCount;
if ( dwEndTickCount <= 40 )
Sleep(50 - dwEndTickCount);
}
ResetEvent(pThis->m_arrayHandleBank[1]);
if ( !DeviceIoControl(pThis->m_hVxD, DIRMON_ReadChange, NULL, 0, pThis->m_pBuffer, CSimpleFileBackup::GetBlockSize(), NULL, &pThis->m_objOverlapped) )
{
DWORD dwErrorCode = ::GetLastError();
if ( dwErrorCode != ERROR_IO_PENDING )
{
switch ( pThis->ErrorCallback(CHANGESHANDLER_DEVICEIOCONTROL_READCHANGE_FAILED, NULL, NULL, dwErrorCode) )
{
case PROGRESS_CANCEL:
case PROGRESS_STOP:
pThis->OnStopLogging();
return dwErrorCode;
}
}
}
}
}
else
{
if ( dwWaitResult == WAIT_ABANDONED_0 )
{
// Something wrong with the message queue
DWORD dwErrorCode = ::GetLastError();
pThis->ErrorCallback(CHANGESHANDLER_MESSAGE_QUEUE_SEMAPHORE_ABANDONED, NULL, NULL, dwErrorCode);
return dwErrorCode;
}
else
{
// Something wrong with the overlapped event
// or WaitForSingleObject function failed
DWORD dwErrorCode = ::GetLastError();
switch ( pThis->ErrorCallback(dwWaitResult == WAIT_FAILED ? CHANGESHANDLER_WAITFORSINGLEOBJECT_FAILED : CHANGESHANDLER_OVERLAPPED_EVENT_ABANDONED, NULL, NULL, dwErrorCode) )
{
case PROGRESS_CANCEL:
case PROGRESS_STOP:
pThis->OnStopLogging();
return dwErrorCode;
}
}
}
}
return ERROR_SUCCESS;
}
UINT AFX_CDECL CSimpleFileBackup::CWinNTCopyFileThread::CopyFileThreadProc()
{
DWORD dwWaitResult;
UINT nMsg;
WPARAM wParam;
LPARAM lParam;
while ( 1 )
{
dwWaitResult = ::WaitForSingleObject(m_hMessageQueueSemaphore, INFINITE);
if ( dwWaitResult == WAIT_OBJECT_0 )
{
// Got new message
if ( PeekFirstMessage(nMsg, wParam, lParam) )
{
switch ( nMsg )
{
case UWM_CANCELALLREALTIMECOPYFILESMESSAGE:
OnCancelAllRealtimeCopyFilesMessage();
ReturnMessageResult(wParam, ERROR_SUCCESS);
break;
case UWM_DESTROY_WORKERTHREAD:
if ( !IsMessageQueueEmpty() )
{
switch ( ErrorCallback(COPYFILES_TERMINATE_WHILE_MESSAGE_QUEUE_NOT_EMPTY, NULL, NULL, 0, 0) )
{
case PROGRESS_CONTINUE:
case PROGRESS_QUIET:
ReturnMessageResult(wParam, ERROR_CANCELLED);
break;
case PROGRESS_CANCEL:
case PROGRESS_STOP:
case PROGRESS_QUIT_AFTER_FINISH_THIS_FILE:
case PROGRESS_QUIT_AFTER_FINISH_THIS_OPERATION:
ReturnMessageResult(wParam, ERROR_CANCELLED);
return ERROR_CANCELLED;
case PROGRESS_QUIT_AFTER_ALL_EXISTING_OPERATION:
m_nProgressStatus = PROGRESS_QUIT_AFTER_ALL_EXISTING_OPERATION;
CMessageQueue::BlockNewMessage();
ReturnMessageResult(wParam, ERROR_SIGNAL_PENDING);
}
break;
}
else
{
ReturnMessageResult(wParam, ERROR_SUCCESS);
return ERROR_SUCCESS;
}
case UWM_START_REVISION_CONTROL:
ReturnMessageResult(wParam, OnStartRevisionControl((CRevisionInfo*)lParam));
break;
case UWM_STOP_REVISION_CONTROL:
ReturnMessageResult(wParam, OnStopRevisionControl());
break;
case UWM_SET_REVISION_INFO:
ReturnMessageResult(wParam, OnSetRevisionInfo((CRevisionInfo*)lParam));
break;
case UWM_POST_REALTIME_COPY_FILES:
if ( !m_pRevisionInfo )
ReturnMessageResult(wParam, ERROR_NOT_READY);
else
{
ReturnMessageResult(wParam, RealtimeCopyFiles((PCOPYFILES_BUFFER)lParam));
switch ( m_nProgressStatus )
{
case PROGRESS_CANCEL:
case PROGRESS_STOP:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -