⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplefilebackup.cpp

📁 实时文件备份
💻 CPP
📖 第 1 页 / 共 4 页
字号:
					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 + -