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

📄 filebackupe.cpp

📁 实时文件备份
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				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 CFileBackupE::CWorkerThreadWrapper::DummyThreadProc(CWorkerThreadWrapper* pThis)
{
	UINT nRet = pThis->m_pfnThreadProc(pThis->m_lParam);

	if ( nRet == ERROR_SUCCESS )
		return pThis->ExitInstance();
	else
	{
		pThis->ExitInstance();
		return nRet;
	}
}

BOOL CFileBackupE::CFileChangesHandler::InitInstance()
{
	if ( CFileBackupE::m_objInitObject.IsNT() )
	{
	}
	else
	{
		if ( (m_hVxD = CreateFile(_T("\\\\.\\dirmon.vxd"), 0, 0, NULL, 0, FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE )
		{
#if 0
			THROW(new CVxDException(TRUE, ::GetLastError(), _T(".\\dirmon.vxd")));
#else
			if ( m_pCallback )
			{
				FILEBACKUP_CALLBACK_PARAM param = {LOAD_VXD_ERROR, _T(".\\dirmon.vxd"), NULL, ::GetLastError(), 0};

				m_pCallback(&param);
			}
#endif
			CFileBackupE::m_objInitObject.DebugPrint(_T("CFileBackupE::CFileChangesHandler::InitInstance()  FAILED\n"));
			return FALSE;
		}
	}
	CFileBackupE::m_objInitObject.DebugPrint(_T("CFileBackupE::CFileChangesHandler::InitInstance()\n"));
	return TRUE;
}

DWORD CFileBackupE::CFileChangesHandler::ExitInstance()
{
	m_pThread = NULL;
	CFileBackupE::m_objInitObject.DebugPrint(_T("CFileBackupE::CFileChangesHandler::ExitInstance()\n"));
	return ERROR_SUCCESS;
}

UINT CFileBackupE::CFileChangesHandler::Win9xFileChangesHandlerThreadProc(CFileChangesHandler* pThis)
{
	DWORD dwWaitResult;
	int nIndex;
	UINT nMsg;
	WPARAM wParam;
	LPARAM lParam;

	while ( 1 )
	{
		dwWaitResult = ::WaitForMultipleObjects(pThis->m_nHandleNumber, pThis->m_arrayHandleBank, FALSE, INFINITE);
		if ( dwWaitResult >= WAIT_ABANDONED_0 )
		{
			if ( (nIndex = dwWaitResult - WAIT_ABANDONED_0) == 0 )
			{
				//	Something wrong with the message queue
				break;
			}
			else
			{
				//	The file handle of directory changed
			}
		}
		else
		{
			if ( dwWaitResult - WAIT_OBJECT_0 == 0 )
			{
				//	Got new message
				if ( pThis->GetFirstMessage(nMsg, wParam, lParam) )
				{
					switch ( nMsg )
					{
					case UWM_DESTROY_WORKERTHREAD:
						if ( wParam )
						{
							((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->Win9xStopLoggingFileChanges();
							SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
						}
						else
							pThis->Win9xStopLoggingFileChanges();
						return ERROR_SUCCESS;

					case UWM_START_LOGGING_FILE_CHANGES:
						if ( wParam )
						{
							((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->Win9xStartLoggingFileChanges((CFileFilter*)lParam);
							SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
						}
						else
							pThis->Win9xStartLoggingFileChanges((CFileFilter*)lParam);
						continue;

					case UWM_STOP_LOGGING_FILE_CHANGES:
						if ( wParam )
						{
							((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->Win9xStopLoggingFileChanges();
							SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
						}
						else
							pThis->Win9xStopLoggingFileChanges();
						continue;
					}
				}
			}
			//	Check any directory handle is ready
			for ( nIndex = 1; nIndex < pThis->m_nHandleNumber; nIndex++ )
				if ( WaitForSingleObject(pThis->m_arrayHandleBank[nIndex], 0) == WAIT_OBJECT_0 )
				{
					//	Some file changed

					ResetEvent(pThis->m_arrayHandleBank[nIndex]);
				}
		}
	}

	return ERROR_SUCCESS;
}

void CFileBackupE::CFileChangesHandler::WinNTHandleDirectoryNameChange(
	int								nPathnameLength,
	CFileFilter::CParsedPathItem*	pParsedPathItem,
	struct __tag_SpecialParamForWinNTHandleDirectoryNameChange* pExt)
{
}

UINT CFileBackupE::CFileChangesHandler::WinNTFileChangesHandlerThreadProc(CFileChangesHandler* pThis)
{
	DWORD dwWaitResult;
	int nIndex;
	UINT nMsg;
	WPARAM wParam;
	LPARAM lParam;
	time_t tCurrent;

	while ( 1 )
	{
		dwWaitResult = ::WaitForMultipleObjects(pThis->m_nHandleNumber, pThis->m_arrayHandleBank, FALSE, INFINITE);
		if ( dwWaitResult >= WAIT_ABANDONED_0 )
		{
			if ( (nIndex = dwWaitResult - WAIT_ABANDONED_0) == 0 )
			{
				//	Something wrong with the message queue
				break;
			}
			else
			{
				//	The file handle of directory changed
			}
		}
		else
		{
			tCurrent = time(NULL);

			if ( dwWaitResult - WAIT_OBJECT_0 == 0 )
			{
				//	Got new message
				if ( pThis->GetFirstMessage(nMsg, wParam, lParam) )
				{
					switch ( nMsg )
					{
					case UWM_DESTROY_WORKERTHREAD:
						if ( wParam )
						{
							((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->WinNTStopLoggingFileChanges();
							SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
						}
						else
							pThis->WinNTStopLoggingFileChanges();
						return ERROR_SUCCESS;

					case UWM_START_LOGGING_FILE_CHANGES:
						if ( wParam )
						{
							((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->WinNTStartLoggingFileChanges((CFileFilter*)lParam);
							SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
						}
						else
							pThis->WinNTStartLoggingFileChanges((CFileFilter*)lParam);
						continue;

					case UWM_STOP_LOGGING_FILE_CHANGES:
						if ( wParam )
						{
							((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->WinNTStopLoggingFileChanges();
							SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
						}
						else
							pThis->WinNTStopLoggingFileChanges();
						continue;
					}
				}
			}
			//	Check any directory handle is ready
			for ( nIndex = 1; nIndex < pThis->m_nHandleNumber; nIndex++ )
				if ( WaitForSingleObject(pThis->m_arrayHandleBank[nIndex], 0) == WAIT_OBJECT_0 )
				{
					//	Some file changed
					__tag_ACCESSORY_ITEM* pAccessoryItem = pThis->m_arrayAccessoryBank + nIndex;
					PFILE_NOTIFY_INFORMATION pNotifyInfo = (PFILE_NOTIFY_INFORMATION)pAccessoryItem->m_pBuffer;
					CFileFilter::CParsedPathItem *pParsedPathItem = pAccessoryItem->m_pParsedPathItemPointer;
					LPVOID pPostDataPage = NULL;
					PFILECHANGES_INFORMATION pPrevPostInfo, pPostInfo, pTempPostInfo;
					LPVOID pTempStringBuffer = CLargeBufferBlockBank::Allocate();
					LPVOID pTempStringBufferForDirectory = NULL;
					PWCHAR pwsTemp;
					PTCHAR ptsTemp;
					int nPathnameLength;
					int n;

					while ( 1 )
					{
						if ( pNotifyInfo->Action == FILE_ACTION_ADDED || pNotifyInfo->Action == FILE_ACTION_MODIFIED || pNotifyInfo->Action == FILE_ACTION_RENAMED_NEW_NAME )
						{
							for ( pwsTemp = pNotifyInfo->FileName, n = pNotifyInfo->FileNameLength; n > 0; n-- )
								if ( *pwsTemp++ == L'~' )
									break;

							//	Generate Unicode absolute pathname
							pwsTemp = (LPWSTR)pTempStringBuffer;
							*pwsTemp++ = L'\\';
							*pwsTemp++ = L'\\';
							*pwsTemp++ = L'?';
							*pwsTemp++ = L'\\';
#ifdef UNICODE
							lstrcpyW(pwsTemp, (LPCWSTR)pAccessoryItem->m_csPath);
							pwsTemp += pAccessoryItem->m_csPath.GetLength();
#else
							if ( (pwsTemp += MultiByteToWideChar(CP_THREAD_ACP, 0, (LPCSTR)pAccessoryItem->m_csPath, pAccessoryItem->m_csPath.GetLength() + 1, pwsTemp, CLargeBufferBlockBank::GetBlockSize() - 4 * sizeof(WCHAR))) == (LPCWSTR)pTempStringBuffer + 4 )
							{
								if ( pThis->m_pCallback )
								{
									FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_MULTIBYTETOWIDECHAR_ERROR, (LPCTSTR)pAccessoryItem->m_csPath, NULL, ::GetLastError(), 0};

									pThis->m_pCallback(&param);
								}
								goto NEXT_NOTIFY_INFO;
							}
#endif
							if ( pAccessoryItem->m_csPath.GetAt(pAccessoryItem->m_csPath.GetLength() - 1) != _T('\\') )
								*pwsTemp++ = L'\\';
							memcpy(pwsTemp, pNotifyInfo->FileName, pNotifyInfo->FileNameLength);
							*pwsTemp++ = NULL;

							//	Get long pathname and calculate its length
							if ( n!= 0 )	//	May be short pathname
							{
								if ( (nPathnameLength = GetLongPathNameW((LPCWSTR)pTempStringBuffer, (LPWSTR)pTempStringBuffer, CLargeBufferBlockBank::GetBlockSize())) == 0 )
								{
									if ( pThis->m_pCallback )
									{
										FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_GETLONGPATHNAME_ERROR, (LPCTSTR)pTempStringBuffer, NULL, ::GetLastError(), 0};

#ifndef UNICODE
										WideCharToMultiByte(CP_THREAD_ACP, 0, (LPCWSTR)pTempStringBuffer + 4, lstrlenW((LPCWSTR)pTempStringBuffer + 4), (LPSTR)pTempStringBuffer, CLargeBufferBlockBank::GetBlockSize(), NULL, NULL);
#endif
										pThis->m_pCallback(&param);
									}
									goto NEXT_NOTIFY_INFO;
								}
							}
							else			//	It's long pathname already
								nPathnameLength = ((DWORD)pwsTemp - (DWORD)pTempStringBuffer) / sizeof(WCHAR) - 1 - 4;

							//	check file attributes, because we should treat rename of directory specially
							if ( GetFileAttributesW((LPCWSTR)pTempStringBuffer) & FILE_ATTRIBUTE_DIRECTORY )
							{
								if ( pNotifyInfo->Action == FILE_ACTION_RENAMED_NEW_NAME )
								{
									CFileFilter::CParsedPathItem* pItem;

#ifdef UNICODE
									if ( sizeof(*pPostInfo) + nPathnameLength * sizeof(WCHAR) > CLargeBufferBlockBank::GetBlockSize() )
									{
										if ( pThis->m_pCallback )
										{
											FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_PATHNAMETOOLONG_ERROR, (LPCTSTR)pTempStringBuffer + 4, NULL, ERROR_NOT_SUPPORTED, 0};

											pThis->m_pCallback(&param);
										}
										goto NEXT_NOTIFY_INFO;
									}
									ptsTemp = (LPWSTR)pTempStringBuffer + 4;
#else
									if ( pTempStringBufferForDirectory == NULL )
											pTempStringBufferForDirectory = CLargeBufferBlockBank::Allocate();
									if ( WideCharToMultiByte(CP_THREAD_ACP, 0, (LPCWSTR)pTempStringBuffer, nPathnameLength + 1, (LPSTR)pTempStringBufferForDirectory, CLargeBufferBlockBank::GetBlockSize(), NULL, NULL) == 0 )
									{
										if ( pThis->m_pCallback )
										{
											FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_WIDECHARTOMULTIBYTE_ERROR, (LPCTSTR)pTempStringBuffer, NULL, ::GetLastError(), 0};

											pThis->m_pCallback(&param);
										}
										goto NEXT_NOTIFY_INFO;
									}
									ptsTemp = (LPSTR)pTempStringBufferForDirectory;
#endif
									switch ( pParsedPathItem->MatchFilePathname(ptsTemp + pAccessoryItem->m_csPath.GetLength() + (pAccessoryItem->m_pParsedPathItemPointer->IsDriveItem() ? 0 : 1), pItem) )
									{
									case CFileFilter::CParsedPathItem::INCLUDE_ITEM:
										{
											struct __tag_SpecialParamForWinNTHandleDirectoryNameChange objExt = {(LPWSTR)pTempStringBuffer, (LPTSTR)pTempStringBufferForDirectory, pThis->m_pCallback, &pPostDataPage, &pPrevPostInfo, &pPostInfo};

											pThis->WinNTHandleDirectoryNameChange(nPathnameLength, pItem, &objExt);
										}
										break;
									case CFileFilter::CParsedPathItem::INTERMEDIA_ITEM:
										{
											CList<CFileFilter::CParsedPathItem*, CFileFilter::CParsedPathItem*> objParsedPathItemList;
											POSITION pos;

											pItem->GetIncludeItems(objParsedPathItemList);
											pos = objParsedPathItemList.GetHeadPosition();
											while ( pos )
											{
												pItem = objParsedPathItemList.GetNext(pos);
												//pItem-
											}
										}
									}
								}
							}
							else	//	Normal File
							{
#ifdef UNICODE
								if ( sizeof(*pPostInfo) + nPathnameLength * sizeof(WCHAR) > CLargeBufferBlockBank::GetBlockSize() )
								{
									if ( pThis->m_pCallback )
									{
										FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_PATHNAMETOOLONG_ERROR, (LPCTSTR)pTempStringBuffer + 4, NULL, ERROR_NOT_SUPPORTED, 0};

										pThis->m_pCallback(&param);
									}
									goto NEXT_NOTIFY_INFO;
								}
								ptsTemp = (LPWSTR)pTempStringBuffer + 4;
#else
								if ( (nPathnameLength = WideCharToMultiByte(CP_THREAD_ACP, 0, (LPCWSTR)pTempStringBuffer + 4, nPathnameLength + 1, (LPSTR)pTempStringBuffer, CLargeBufferBlockBank::GetBlockSize(), NULL, NULL)) == 0 )
								{
									if ( pThis->m_pCallback )
									{
										FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_WIDECHARTOMULTIBYTE_ERROR, (LPCTSTR)pTempStringBuffer, NULL, ::GetLastError(), 0};

										pThis->m_pCallback(&param);
									}
									goto NEXT_NOTIFY_INFO;
								}
								nPathnameLength--;
								ptsTemp = (LPSTR)pTempStringBuffer;
#endif
								if ( pParsedPathItem->MatchFilePathname(ptsTemp + pAccessoryItem->m_csPath.GetLength() + (pAccessoryItem->m_pParsedPathItemPointer->IsDriveItem() ? 0 : 1)) )
								{
									if ( pPostDataPage != NULL )
									{
										if ( (DWORD)pPostDataPage != (DWORD)pPostInfo )
										{
											pTempPostInfo = (PFILECHANGES_INFORMATION)pPostDataPage;
											do
											{
												if ( pTempPostInfo->m_nPathnameLength == nPathnameLength && _tcsicmp(pTempPostInfo->m_tsPathname, ptsTemp) == 0 )
													goto NEXT_NOTIFY_INFO;
												else
													pTempPostInfo = pTempPostInfo->m_pNext;
											} while ( pTempPostInfo != pPostInfo );
										}
										if ( (LPBYTE)pPostDataPage + CLargeBufferBlockBank::GetBlockSize() < (LPBYTE)pPostInfo + sizeof(*pPostInfo) + nPathnameLength * sizeof(TCHAR) )
										{
											ASSERT(pPrevPostInfo != NULL);
											pPrevPostInfo->m_pNext = NULL;
											if ( !pThis->m_pDatabassAccessThread->PostFileChanges(pPostDataPage) )
											{
												if ( pThis->m_pCallback )
												{
													FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_POSTFILECHANGES_ERROR, NULL, NULL, ::GetLastError(), 0};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -