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

📄 filebackupe.h

📁 实时文件备份
💻 H
📖 第 1 页 / 共 5 页
字号:
		}

		inline void PostMessage(UINT nMsg, WPARAM wParam, LPARAM lParam) { m_objMessageQueue.PostMessage(nMsg, wParam, lParam); }

		inline BOOL SetPriority(int nPriority)
		{
			return m_pThread ? m_pThread->SetThreadPriority(nPriority) : FALSE;
		}

		inline BOOL IsThreadAvailable() const { return m_pThread != NULL; }

	protected:
		static UINT DummyThreadProc(CWorkerThreadWrapper* pThis);

		inline BOOL GetFirstMessage(UINT& nMsg, WPARAM& wParam, LPARAM& lParam) { return m_objMessageQueue.GetFirstMessage(nMsg, wParam, lParam); }
		inline HANDLE GetSemaphore() const { return m_objMessageQueue.GetSemaphore(); }

	protected:
		AFX_THREADPROC				m_pfnThreadProc;
		LPVOID						m_lParam;

		CWinThread*					m_pThread;
		CMessageQueue				m_objMessageQueue;
	};

	class CDatabaseAccessThread;

	class CFileChangesHandler : public CWorkerThreadWrapper
	{
	public:
		inline CFileChangesHandler(LPFILEBACKUP_CALLBACK pCallback, CDatabaseAccessThread* pDatabaseAccessThread) : CWorkerThreadWrapper(), m_pCallback(pCallback), m_pDatabassAccessThread(pDatabaseAccessThread), m_fIsLogging(FALSE), m_hVxD(INVALID_HANDLE_VALUE)
		{
			m_arrayHandleBank[0] = GetSemaphore();
			m_nHandleNumber = 1;
		}

		virtual BOOL InitInstance();
		virtual DWORD ExitInstance();

		inline BOOL CreateThread(int nPriority = THREAD_PRIORITY_BELOW_NORMAL)
		{
			return CWorkerThreadWrapper::CreateThread((AFX_THREADPROC)(CFileBackupE::m_objInitObject.IsNT() ? CFileChangesHandler::WinNTFileChangesHandlerThreadProc : CFileChangesHandler::Win9xFileChangesHandlerThreadProc), this, nPriority);
		}

		inline DWORD TerminateThread(DWORD dwTimeout = 5000)
		{
			if ( m_pThread )
			{
				MESSAGE_RESULT objResult;
				DWORD dwWaitResult;

				if ( (objResult.m_hFinishedEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL )
					AfxThrowResourceException();
				CWorkerThreadWrapper::PostMessage(UWM_DESTROY_WORKERTHREAD, (WPARAM)&objResult, NULL);
				if ( (dwWaitResult = WaitForSingleObject(objResult.m_hFinishedEvent, dwTimeout)) != WAIT_OBJECT_0 )
				{
					CloseHandle(objResult.m_hFinishedEvent);
					m_pThread = NULL;
					return dwWaitResult;
				}
				else
				{
					CloseHandle(objResult.m_hFinishedEvent);
					m_pThread = NULL;
					return objResult.m_dwResult;
				}
			}
			else
				return ERROR_ACCESS_DENIED;
		}

		inline DWORD StartLogging(CFileFilter* pFileFilter, DWORD dwTimeout = 500)
		{
			if ( !pFileFilter )
				return ERROR_INVALID_PARAMETER;
			else if ( m_pThread )
			{
				MESSAGE_RESULT objResult;
				DWORD dwWaitResult;

				if ( m_fIsLogging )
					StopLogging(dwTimeout);

				if ( (objResult.m_hFinishedEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL )
					AfxThrowResourceException();
				CWorkerThreadWrapper::PostMessage(UWM_START_LOGGING_FILE_CHANGES, (WPARAM)&objResult, (LPARAM)pFileFilter);
				if ( (dwWaitResult = WaitForSingleObject(objResult.m_hFinishedEvent, dwTimeout)) != WAIT_OBJECT_0 )
				{
					CloseHandle(objResult.m_hFinishedEvent);
					return dwWaitResult;
				}
				else
				{
					CloseHandle(objResult.m_hFinishedEvent);
					return objResult.m_dwResult;
				}
			}
			else
				return ERROR_ACCESS_DENIED;
		}

		inline DWORD StopLogging(DWORD dwTimeout = 500)
		{
			if ( m_pThread )
			{
				MESSAGE_RESULT objResult;
				DWORD dwWaitResult;

				if ( (objResult.m_hFinishedEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL )
					AfxThrowResourceException();
				CWorkerThreadWrapper::PostMessage(UWM_STOP_LOGGING_FILE_CHANGES, (WPARAM)&objResult, NULL);
				if ( (dwWaitResult = WaitForSingleObject(objResult.m_hFinishedEvent, dwTimeout)) != WAIT_OBJECT_0 )
				{
					CloseHandle(objResult.m_hFinishedEvent);
					return dwWaitResult;
				}
				else
				{
					CloseHandle(objResult.m_hFinishedEvent);
					return objResult.m_dwResult;
				}
			}
			else
				return ERROR_ACCESS_DENIED;
		}

		inline DWORD SetFileFilter(CFileFilter* pFileFilter, DWORD dwTimeout = 500) { return StartLogging(pFileFilter, dwTimeout); }

	protected:
		static UINT Win9xFileChangesHandlerThreadProc(CFileChangesHandler* pThis);
		static UINT WinNTFileChangesHandlerThreadProc(CFileChangesHandler* pThis);

		inline DWORD Win9xStartLoggingFileChanges(CFileFilter* pFileFilter)
		{
			CFileFilter::CParsedPathItem *pDriveItem, *pItem;
			CString csBasePath;
			TCHAR tsShortPathname[MAX_PATH];
			int nShortPathnameLength;

			if ( m_fIsLogging )
				Win9xStopLoggingFileChanges();
#if 0
			DWORD dwDataBufferLength;

			dwDataBufferLength = 0;
			pDriveItem = pFileFilter->GetFirstAvailableDrive();
			while ( pDriveItem )
				if ( pFileFilter->GetNextAvailableDriveBasePath(pDriveItem, csBasePath, pItem) )
				{
					CreateDirectory(csBasePath, NULL);
					dwDataBufferLength += csBasePath.GetLength() + GetShortPathName((LPCTSTR)csBasePath, tsShortPathname, sizeof(tsShortPathname)) + 2;
				}
			if ( dwDataBufferLength )
			{
	#ifndef UNICODE
				char* pBuf = new char[++dwDataBufferLength];
				PCHAR pChar = pBuf;
	#else
				char* pBuf = new char[++dwDataBufferLength * sizeof(WCHAR)];
				int nCharCount = 0;
	#endif

				pDriveItem = pFileFilter->GetFirstAvailableDrive();
				while ( pDriveItem )
				{
					if ( pFileFilter->GetNextAvailableDriveBasePath(pDriveItem, csBasePath, pItem) )
					{
	#ifndef UNICODE
						strcpy(pChar, (LPCTSTR)csBasePath);
						pChar += csBasePath.GetLength() + 1;
						if ( (nShortPathnameLength = ::GetShortPathName((LPCTSTR)csBasePath, tsShortPathname, sizeof(tsShortPathname))) != 0 )
						{
							strcpy(pChar, tsShortPathname);
							pChar += nShortPathnameLength + 1;
						}
						else
							*pChar++ = NULL;
	#else
						nCharCount += ::WideCharToMultiByte(CP_THREAD_ACP, 0, (LPCTSTR)csBasePath, csBasePath.GetLength() + 1, pBuf + nCharCount, dwDataBufferLength * sizeof(WCHAR) - nCharCount, NULL, NULL);
						if ( (nShortPathnameLength = ::GetShortPathName((LPCTSTR)csBasePath, tsShortPathname, sizeof(tsShortPathname))) != 0 )
							nCharCount += ::WideCharToMultiByte(CP_THREAD_ACP, 0, tsShortPathname, nShortPathnameLength + 1, pBuf + nCharCount, dwDataBufferLength * sizeof(WCHAR) - nCharCount, NULL, NULL);
						else
							pBuf[nCharCount++] = NULL;
	#endif
					}
				}
	#ifndef UNICODE
				*pChar++ = NULL;
	#else
				pBuf[nCharCount++] = NULL;
	#endif

				if ( DeviceIoControl(m_hVxD, DIRMON_StartLogging, pBuf, dwDataBufferLength, NULL, 0, NULL, NULL) )
				{
					if ( (m_arrayHandleBank[1] = m_arrayAccessoryBank[1].m_objOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL )
					{
						m_arrayAccessoryBank[1].m_pBuffer = CLargeBufferBlockBank::Allocate();
						if ( DeviceIoControl(m_hVxD, DIRMON_ReadChange, NULL, 0, m_arrayAccessoryBank[1].m_pBuffer, CLargeBufferBlockBank::GetBlockSize(), NULL, &m_arrayAccessoryBank[1].m_objOverlapped) )
						{
							m_arrayAccessoryBank[1].m_pParsedPathItemPointer = pItem;
							m_arrayAccessoryBank[1].m_csPath = csBasePath;
							m_nHandleNumber = 2;
						}
						else
						{
							DeviceIoControl(m_hVxD, DIRMON_StopLogging, NULL, 0, NULL, 0, NULL, NULL);
							CloseHandle(m_arrayAccessoryBank[1].m_objOverlapped.hEvent);
							CLargeBufferBlockBank::Free(m_arrayAccessoryBank[1].m_pBuffer);
						}
					}
					else
						DeviceIoControl(m_hVxD, DIRMON_StopLogging, NULL, 0, NULL, 0, NULL, NULL);
				}

				delete[] pBuf;
			}
#else
			char pBuf[MAX_PATH * 26 * 2];
			char* pChar = pBuf;

			pDriveItem = pFileFilter->GetFirstAvailableDrive();
			while ( pDriveItem )
				if ( pFileFilter->GetNextAvailableDriveBasePath(pDriveItem, csBasePath, pItem) )
				{
					CreateDirectory(csBasePath, NULL);
	#ifndef UNICODE
					strcpy(pChar, (LPCTSTR)csBasePath);
					pChar += csBasePath.GetLength() + 1;
					if ( (nShortPathnameLength = ::GetShortPathName((LPCTSTR)csBasePath, tsShortPathname, sizeof(tsShortPathname))) != 0 )
					{
						strcpy(pChar, tsShortPathname);
						pChar += nShortPathnameLength + 1;
					}
					else
						*pChar++ = NULL;
	#else
					pChar += ::WideCharToMultiByte(CP_THREAD_ACP, 0, (LPCTSTR)csBasePath, csBasePath.GetLength() + 1, pChar, sizeof(pBuf) - (pChar - pBuf), NULL, NULL);
					if ( (nShortPathnameLength = ::GetShortPathName((LPCTSTR)csBasePath, tsShortPathname, sizeof(tsShortPathname))) != 0 )
						pChar += ::WideCharToMultiByte(CP_THREAD_ACP, 0, tsShortPathname, nShortPathnameLength + 1, pChar, sizeof(pBuf) - (pChar - pBuf), NULL, NULL);
					else
						*pChar++ = NULL;
	#endif
				}

			if ( pChar != pBuf )
			{
				*pChar++ = NULL;
				if ( DeviceIoControl(m_hVxD, DIRMON_StartLogging, pBuf, pChar - pBuf, NULL, 0, NULL, NULL) )
				{
					if ( (m_arrayHandleBank[1] = m_arrayAccessoryBank[1].m_objOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL )
					{
						m_arrayAccessoryBank[1].m_pBuffer = CLargeBufferBlockBank::Allocate();
						if ( DeviceIoControl(m_hVxD, DIRMON_ReadChange, NULL, 0, m_arrayAccessoryBank[1].m_pBuffer, CLargeBufferBlockBank::GetBlockSize(), NULL, &m_arrayAccessoryBank[1].m_objOverlapped) )
						{
							m_arrayAccessoryBank[1].m_pParsedPathItemPointer = pItem;
							m_arrayAccessoryBank[1].m_csPath = csBasePath;
							m_nHandleNumber = 2;
						}
						else
						{
							DeviceIoControl(m_hVxD, DIRMON_StopLogging, NULL, 0, NULL, 0, NULL, NULL);
							CloseHandle(m_arrayAccessoryBank[1].m_objOverlapped.hEvent);
							CLargeBufferBlockBank::Free(m_arrayAccessoryBank[1].m_pBuffer);
						}
					}
					else
						DeviceIoControl(m_hVxD, DIRMON_StopLogging, NULL, 0, NULL, 0, NULL, NULL);
				}
			}
#endif
			if ( m_nHandleNumber > 1 )
			{
				m_pFileFilter = pFileFilter;
				m_fIsLogging = TRUE;
				return ERROR_SUCCESS;
			}
			else
				return ERROR_NOT_READY;
		}

		inline DWORD Win9xStopLoggingFileChanges()
		{
			if ( m_fIsLogging )
			{
				DWORD dwRet = ERROR_SUCCESS;

				//	Actually, it's not necessary to call CancelReadChange, because StopLogging does it automatically.
				//	Keep this line just for more clear process.
				if ( !DeviceIoControl(m_hVxD, DIRMON_CancelReadChange, NULL, 0, NULL, 0, NULL, NULL) )
					dwRet = GetLastError();
				if ( !DeviceIoControl(m_hVxD, DIRMON_StopLogging, NULL, 0, NULL, 0, NULL, NULL) )
					dwRet = GetLastError();
				if ( !CloseHandle(m_arrayAccessoryBank[1].m_objOverlapped.hEvent) )
					dwRet = GetLastError();
				m_arrayAccessoryBank[1].m_csPath.Empty();
				CLargeBufferBlockBank::Free(m_arrayAccessoryBank[1].m_pBuffer);

				m_nHandleNumber = 1;
				m_fIsLogging = FALSE;

				return dwRet;
			}
			else
				return ERROR_SUCCESS;
		}

		inline DWORD WinNTStartLoggingFileChanges(CFileFilter* pFileFilter)
		{
			CFileFilter::CParsedPathItem *pDriveItem, *pItem;
			CString csBasePath;

			if ( m_fIsLogging )
				WinNTStopLoggingFileChanges();

			pDriveItem = pFileFilter->GetFirstAvailableDrive();
			while ( pDriveItem )
			{
				if ( pFileFilter->GetNextAvailableDriveBasePath(pDriveItem, csBasePath, pItem) )
				{
					CreateDirectory(csBasePath, NULL);
					if ( (m_arrayAccessoryBank[m_nHandleNumber].m_hFile = CreateFile(csBasePath, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL))
						== INVALID_HANDLE_VALUE )
						continue;
					if ( (m_arrayHandleBank[m_nHandleNumber] = m_arrayAccessoryBank[m_nHandleNumber].m_objOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))
						== NULL )
					{
						CloseHandle(m_arrayAccessoryBank[m_nHandleNumber].m_hFile);
						continue;
					}
					m_arrayAccessoryBank[m_nHandleNumber].m_pBuffer = CLargeBufferBlockBank::Allocate();
					if ( !ReadDirectoryChangesW(m_arrayAccessoryBank[m_nHandleNumber].m_hFile, m_arrayAccessoryBank[m_nHandleNumber].m_pBuffer, CLargeBufferBlockBank::GetBlockSize(), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, NULL, &m_arrayAccessoryBank[m_nHandleNumber].m_objOverlapped, NULL) )
					{
						CloseHandle(m_arrayAccessoryBank[m_nHandleNumber].m_hFile);
						CloseHandle(m_arrayAccessoryBank[m_nHandleNumber].m_objOverlapped.hEvent);
						CLargeBufferBlockBank::Free(m_arrayAccessoryBank[m_nHandleNumber].m_pBuffer);
						continue;
					}
					m_arrayAccessoryBank[m_nHandleNumber].m_pParsedPathItemPointer = pItem;
					m_arrayAccessoryBank[m_nHandleNumber].m_csPath = csBasePath;
					m_nHandleNumber++;
				}
			}
			if ( m_nHandleNumber > 1 )
			{
				m_pFileFilter = pFileFilter;
				m_fIsLogging = TRUE;
				return ERROR_SUCCESS;
			}
			else
				return ERROR_NOT_READY;
		}

		inline DWORD WinNTStopLoggingFileChanges()
		{
			if ( m_fIsLogging )
			{
				DWORD dwRet = ERROR_SUCCESS;
				int i;

				for ( i = 1; i < m_nHandleNumber; i++ )
				{
					if ( !CancelIo(m_arrayAccessoryBank[i].m_hFile) )
						dwRet = GetLastError();
					if ( !CloseHandle(m_arrayAccessoryBank[i].m_hFile) )
						dwRet = GetLastError();
					if ( !CloseHandle(m_arrayAccessoryBank[i].m_objOverlapped.hEvent) )
						dwRet = GetLastError();
					m_arrayAccessoryBank[i].m_csPath.Empty();
					CLargeBufferBlockBank::Free(m_arrayAccessoryBank[i].m_pBuffer);
				}

				m_nHandleNumber = 1;
				m_fIsLogging = FALSE;

				return dwRet;
			}
			else
				return ERROR_SUCCESS;
		}

		struct __tag_SpecialParamForWinNTHandleDirectoryNameChange
		{
			LPWSTR							pStringBuffer1;
			LPTSTR							pStringBuffer2;
			LPFILEBACKUP_CALLBACK			pCallback;
			LPVOID*							ppPostDataPage;
			PFILECHANGES_INFORMATION*		ppPrevPostInfo;
			PFILECHANGES_INFORMATION*		pPostInfo;
		};
		void WinNTHandleDirectoryNameChange(
			int								nPathnameLength,
			CFileFilter::CParsedPathItem*	pParsedPathItem,
			struct __tag_SpecialParamForWinNTHandleDirectoryNameChange* pExt);

	protected:
		HANDLE									m_hVxD;

		HANDLE									m_arrayHandleBank[32];
		class __tag_ACCESSORY_ITEM {		//	Actually I want to declare a struct
		public:
			__tag_ACCESSORY_ITEM() : m_hFile(NULL), m_pParsedPathItemPointer(NULL), m_pBuffer(NULL)
			{
				m_objOverlapped.Internal = m_objOverlapped.InternalHigh = 0;
				m_objOverlapped.Pointer = m_objOverlapped.hEvent = NULL;
			}

		public:
			HANDLE							m_hFile;
			CString							m_csPath;
			CFileFilter::CParsedPathItem*	m_pParsedPathItemPointer;
			LPVOID							m_pBuffer;
			OVERLAPPED						m_objOverlapped;
		}										m_arrayAccessoryBank[32];
		int										m_nHandleNumber;

		BOOL									m_fIsLogging;

		CFileFilter*							m_pFileFilter;
		CDatabaseAccessThread*					m_pDatabassAccessThread;
		LPFILEBACKUP_CALLBACK					m_pCallback;
	};

	class CFileCopyThreadWrapper : public CWorkerThreadWrapper
	{
	public:
		inline CFileCopyThreadWrapper(LPFILEBACKUP_CALLBACK pCallback, CDatabaseAccessThread* pDatabaseAccessThread) : CWorkerThreadWrapper(), m_pCallback(pCallback), m_pDatabaseAccessThread(pDatabaseAccessTh

⌨️ 快捷键说明

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