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

📄 simplefilebackup.h

📁 实时文件备份
💻 H
📖 第 1 页 / 共 5 页
字号:
			inline BOOL IsNormalItem() const { return (m_dwFlags & ITEM_MASK) == DIRECTORY_OR_FILE_ITEM ? TRUE : FALSE; }
			inline BOOL IsIncludeItem() const { return (m_dwFlags & ITEM_TYPE_MASK) == INCLUDE_ITEM ? TRUE : FALSE; }
			inline BOOL IsExcludeItem() const { return (m_dwFlags & ITEM_TYPE_MASK) == EXCLUDE_ITEM ? TRUE : FALSE; }
			inline BOOL IsIntermediaItem() const { return (m_dwFlags & ITEM_TYPE_MASK) == INTERMEDIA_ITEM ? TRUE : FALSE; }

		protected:
			inline BOOL SetItemData(LPCTSTR pctsItemName, LPCTSTR pctsFilenameMask, DWORD dwFileAttributesMask, DWORD dwFlags)
			{
				ClearItemData();

				switch ( dwFlags & ITEM_MASK )
				{
				case ROOT_ITEM:
					m_ptsName = NULL;
					break;
				case DRIVE_ITEM:
					if ( pctsItemName == NULL || !(*pctsItemName >= _T('A') && *pctsItemName <= _T('Z') || *pctsItemName >= _T('a') && *pctsItemName <= _T('z')) )
						return FALSE;
					m_ptsName = (LPTSTR)(*pctsItemName >= _T('a') ? *pctsItemName - _T('a') : *pctsItemName - _T('A'));
					break;
				case DIRECTORY_OR_FILE_ITEM:
					if ( pctsItemName && *pctsItemName != NULL && *pctsItemName != _T('\\') )
					{
						LPTSTR pTChar = (LPTSTR)pctsItemName;
						int nLen;

						while ( *pTChar != NULL && *pTChar != _T('\\') )
							pTChar++;
						nLen = pTChar - pctsItemName;
						m_ptsName = (pTChar = new TCHAR[nLen + 2]) + 1;
						*pTChar++ = nLen;
						while ( nLen-- > 0 )
						{
							*pTChar++ =	LOWER(*pctsItemName);	//	*pctsItemName >= _T('a') && *pctsItemName <= _T('z') ? *pctsItemName - _T('a') + _T('A') : *pctsItemName;
							pctsItemName++;
						}
						*pTChar = NULL;
						break;
					}
				default:
					return FALSE;
				}
				if ( (dwFlags & ITEM_TYPE_MASK) != INCLUDE_ITEM )
					dwFlags &= ITEM_TYPE_MASK | ITEM_MASK;
				else
				{
					if ( (dwFlags & FILENAME_MASK_MASK) && pctsFilenameMask )
					{
						CFilenameMaskList* pFilenameMaskList = new CFilenameMaskList(pctsFilenameMask);

						if ( pFilenameMaskList->IsAvailable(_T("*.*")) )
						{
							delete pFilenameMaskList;
							if ( (dwFlags & FILENAME_MASK_MASK) == INCLUDE_FILENAME_MASK )
								dwFlags &= ~FILENAME_MASK_MASK;
							else
								dwFlags = dwFlags & ITEM_MASK | EXCLUDE_ITEM;
						}
						else
							m_pFilenameMaskList = pFilenameMaskList;
					}
					if ( dwFlags & FILE_ATTRIBUTES_MASK_MASK )
						m_dwFileAttributesMask = dwFileAttributesMask;
				}
				m_dwFlags = dwFlags;
				return TRUE;
			}

			inline void ClearItemData()
			{
				if ( m_pFirstChild )
					delete m_pFirstChild;
				if ( m_pNextSibling )
					delete m_pNextSibling;

				if ( (m_dwFlags & ITEM_MASK) == DIRECTORY_OR_FILE_ITEM && m_ptsName )
					delete[] (m_ptsName - 1);
				m_ptsName = NULL;
				if ( m_pFilenameMaskList )
				{
					delete m_pFilenameMaskList;
					m_pFilenameMaskList = NULL;
				}
				m_dwFlags = m_dwFileAttributesMask = NULL;
			}

		protected:
			DWORD								m_dwFlags;
			LPTSTR								m_ptsName;
			CFilenameMaskList*					m_pFilenameMaskList;
			DWORD								m_dwFileAttributesMask;

			CParsedPathItem*					m_pFirstChild;
			CParsedPathItem*					m_pNextSibling;

			CParsedPathItem*					m_pParent;
		};

		inline CFileFilter() : m_pRootParsedPathItem(NULL) {}
		inline ~CFileFilter() { if ( m_pRootParsedPathItem ) delete m_pRootParsedPathItem; }

		inline void Reset() { if ( m_pRootParsedPathItem ) delete m_pRootParsedPathItem; m_pRootParsedPathItem = NULL; }

		inline BOOL AddIncludePath(LPCTSTR pctsPath, LPCTSTR pctsFilenameMask, BOOL fIsIncludeFilenameMask, DWORD* pdwFileAttributesMask, BOOL fIsIncludeFileAttributesMask)
		{
			if ( pctsPath && *pctsPath )
			{
				if ( pctsPath[1] != _T(':') || pctsPath[2] != NULL && pctsPath[2] != _T('\\') || !(*pctsPath >= _T('a') && *pctsPath <= _T('z') || *pctsPath >= _T('A') && *pctsPath <= _T('Z')) )
					return FALSE;
				if ( !m_pRootParsedPathItem )
					m_pRootParsedPathItem = new CParsedPathItem(NULL, NULL, 0, CParsedPathItem::ROOT_ITEM | CParsedPathItem::INTERMEDIA_ITEM);
				return m_pRootParsedPathItem->AddIncludePath(pctsPath, pctsFilenameMask, fIsIncludeFilenameMask, pdwFileAttributesMask, fIsIncludeFileAttributesMask);
			}
			else
			{
				DWORD dwFlags = CParsedPathItem::ROOT_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;

				if ( !m_pRootParsedPathItem )
				{
					m_pRootParsedPathItem = new CParsedPathItem(NULL, pctsFilenameMask, pdwFileAttributesMask ? *pdwFileAttributesMask : 0, dwFlags);
					return TRUE;
				}
				else
					return m_pRootParsedPathItem->SetItemData(NULL, pctsFilenameMask, pdwFileAttributesMask ? *pdwFileAttributesMask : 0, dwFlags);
			}
		}

		inline BOOL AddExcludePath(LPCTSTR pctsPath)
		{
			if ( !m_pRootParsedPathItem )
				return FALSE;
			else
				return m_pRootParsedPathItem->AddExcludePath(pctsPath, FALSE);
		}

		inline BOOL MatchFilePathname(LPCTSTR pctsFilePathname)
		{
			if ( pctsFilePathname == NULL || m_pRootParsedPathItem == NULL )
				return FALSE;
			else
				return m_pRootParsedPathItem->MatchFilePathname(pctsFilePathname);
		}

		inline CParsedPathItem::PARSED_PATH_ITEM_FLAGS_BIT_MASK MatchFilePathname(LPCTSTR pctsFilePathname, CParsedPathItem*& pItem)
		{
			if ( pctsFilePathname == NULL || m_pRootParsedPathItem == NULL )
				return CParsedPathItem::EXCLUDE_ITEM;
			else
				return m_pRootParsedPathItem->MatchFilePathname(pctsFilePathname, pItem);
		}

		inline BOOL GetDriveBasePath(TCHAR tDrive, CString& csBasePath, CParsedPathItem*& pItem)
		{
			if ( !m_pRootParsedPathItem || !(tDrive >= _T('A') && tDrive <= _T('Z') || tDrive >= _T('a') && tDrive <= _T('z')) )
				return FALSE;
			else
			{
				CParsedPathItem *pDriveItem = m_pRootParsedPathItem->m_pFirstChild, *pTempItem;
				int nDrive = tDrive >= _T('a') ? tDrive - _T('a') : tDrive - _T('A');
				int nLen;
				LPTSTR pBuf;
				BOOL fOnlyDrive;

				while ( pDriveItem && (int)pDriveItem->m_ptsName < nDrive )
					pDriveItem = pDriveItem->m_pNextSibling;
				if ( !pDriveItem || (int)pDriveItem->m_ptsName != nDrive )
					return FALSE;
				for ( nLen = 2, pTempItem = pDriveItem->m_pFirstChild; pTempItem && !pTempItem->m_pNextSibling; pTempItem = pTempItem->m_pFirstChild )
					nLen += *(pTempItem->m_ptsName - 1) + 1;
				if ( nLen < 3 )
				{
					fOnlyDrive = TRUE;
					nLen = 3;
				}
				else
					fOnlyDrive = FALSE;
				pBuf = csBasePath.GetBuffer(nLen);
				*pBuf++ = _T('a') + nDrive;
				*pBuf++ = _T(':');
				while ( pDriveItem->m_pFirstChild && !pDriveItem->m_pFirstChild->m_pNextSibling )
				{
					pDriveItem = pDriveItem->m_pFirstChild;
					*pBuf++ = _T('\\');
					_tcscpy(pBuf, pDriveItem->m_ptsName);
					pBuf += *(pDriveItem->m_ptsName - 1);
				}
				pItem = pDriveItem;
				if ( fOnlyDrive )
					*pBuf++ = _T('\\');
				csBasePath.ReleaseBuffer(nLen);
				return TRUE;
			}
		}

		inline CParsedPathItem* GetFirstAvailableDrive()
		{
			return !m_pRootParsedPathItem ? NULL : m_pRootParsedPathItem->m_pFirstChild;
		}

		inline TCHAR GetNextAvailableDrive(CParsedPathItem*& pDriveItem)
		{
			TCHAR tRet = NULL;

			if ( pDriveItem && (pDriveItem->m_dwFlags & CParsedPathItem::ITEM_MASK) == CParsedPathItem::DRIVE_ITEM )
			{
				tRet = _T('a') + (int)pDriveItem->m_ptsName;
				pDriveItem = pDriveItem->m_pNextSibling;
			}
			return tRet;
		}

		//	Must return long pathname, actually this class should handle long pathname only
		inline BOOL GetNextAvailableDriveBasePath(CParsedPathItem*& pDriveItem, CString& csBasePath, CParsedPathItem*& pItem)
		{
			TCHAR tDriveName;

			if ( (tDriveName = GetNextAvailableDrive(pDriveItem)) == NULL )
				return FALSE;
			return GetDriveBasePath(tDriveName, csBasePath, pItem);
		}

		inline void GetIncludeItems(CStringList& objStringList, CList<CParsedPathItem*, CParsedPathItem*>& objList)
		{
			if ( m_pRootParsedPathItem != NULL )
				m_pRootParsedPathItem->GetIncludeItems(objStringList, objList);
		}

	protected:
		CParsedPathItem *						m_pRootParsedPathItem;
	};

	class CRevisionInfo
	{
	public:
		class CRevisionPath
		{
		public:
			friend class CRevisionInfo;

			inline CRevisionPath()
			{
				m_u64UTCRevisionTime.QuadPart = 0;
			}

			inline CRevisionPath& operator = (const CRevisionPath& rev)
			{
				m_csPathname = rev.m_csPathname;
				m_u64UTCRevisionTime.QuadPart = rev.m_u64UTCRevisionTime.QuadPart;
				return *this;
			}
/*
			inline CRevisionPath& operator = (const CRevisionPath rev)
			{
				m_csPathname = rev.m_csPathname;
				m_u64UTCCreateDateTime = rev.m_u64UTCCreateDateTime;
				m_objLocalCreateDateTime = rev.m_objLocalCreateDateTime;
			}

			inline BOOL WinNTSet(CString csPathname, ULARGE_INTEGER u64UTCCreateDateTime)
			{
				LPWSTR pws = (LPWSTR)CSimpleFileBackup::AllocateBuffer();
				WIN32_FIND_DATAW objFindData;
				HANDLE hFind;

				m_csPathname = csPathname;

				pws[0] = L'\\';
				pws[1] = L'\\';
				pws[2] = L'?';
				pws[3] = L'\\';
#ifdef UNICODE
				wcscpy(pws + 4, m_csPathname);
#else
				if ( ::MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)csPathname, -1, pws + 4, CSimpleFileBackup::GetBlockSize() - 4 * sizeof(WCHAR)) == 0 )
				{
					CSimpleFileBackup::FreeBuffer(pws);
					return FALSE;
				}
#endif
				if ( m_u64UTCCreateDateTime.QuadPart == 0 )
				{
					hFind = ::FindFirstFileW(pws, &objFindData);
					if ( hFind == INVALID_HANDLE_VALUE )
					{
						CSimpleFileBackup::FreeBuffer(pws);
						return FALSE;
					}
					::FindClose(hFind);

					m_u64UTCCreateDateTime.HighPart = objFindData.ftCreationTime.dwHighDateTime;
					m_u64UTCCreateDateTime.LowPart = objFindData.ftCreationTime.dwLowDateTime;
					m_objLocalCreateDateTime = CTime(objFindData.ftCreationTime);
					CSimpleFileBackup::FreeBuffer(pws);
					return TRUE;
				}
				else
				{
					HANDLE hFile;
					BOOL fRet;

					m_u64UTCCreateDateTime.QuadPart = u64UTCCreateDateTime.QuadPart;
					m_objLocalCreateDateTime = CTime((FILETIME&)u64UTCCreateDateTime);

					CSimpleFileBackup::CreateDirectory(pws);
					hFile = ::CreateFileW(pws, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
					if ( hFile == INVALID_HANDLE_VALUE )
					{
						CSimpleFileBackup::FreeBuffer(pws);
						return FALSE;
					}
					fRet = SetFileTime(hFile, (FILETIME*)&u64UTCCreateDateTime, NULL, NULL);
					CSimpleFileBackup::FreeBuffer(pws);
					return fRet;
				}
			}

			inline BOOL Win9xSet(CString csPathname, ULARGE_INTEGER u64UTCCreateDateTime)
			{
				m_csPathname = csPathname;

				if ( u64UTCCreateDateTime.QuadPart == 0 )
				{
					WIN32_FIND_DATA objFindData;
					HANDLE hFind;

					hFind = ::FindFirstFile((LPCTSTR)csPathname, &objFindData);
					if ( hFind == INVALID_HANDLE_VALUE )
						return FALSE;
					FindClose(hFind);

					m_u64UTCCreateDateTime.HighPart = objFindData.ftCreationTime.dwHighDateTime;
					m_u64UTCCreateDateTime.LowPart = objFindData.ftCreationTime.dwLowDateTime;
					m_objLocalCreateDateTime = CTime(objFindData.ftCreationTime);
					return TRUE;
				}
				else
				{
					CSimpleFileBackup::CreateDirectory((LPCTSTR)m_csPathname);
					m_u64UTCCreateDateTime.QuadPart = u64UTCCreateDateTime.QuadPart;
					m_objLocalCreateDateTime = CTime((FILETIME&)u64UTCCreateDateTime);
				}
			}
*/
		protected:
			CString					m_csPathname;
			ULARGE_INTEGER			m_u64UTCRevisionTime;
		};
		typedef CList<CRevisionPath, CRevisionPath&>	CRevisionPaths;

	public:

		inline CRevisionInfo() : m_dwMaxRevision(0), m_fIncrementBackup(TRUE)
		{
			m_u64RevisionInterval.QuadPart = (unsigned __int64)24 * 60 * 60 * 10 * 1000 * 1000;
		}

		inline CRevisionInfo(const CString& csBaseDestinationPath, DWORD dwMaxRevision, ULARGE_INTEGER u64RevisionIntervalTime, const CStringList& objRevisionRelativePaths)
		{
			SetRevisionInfo(csBaseDestinationPath, dwMaxRevision, u64RevisionIntervalTime, objRevisionRelativePaths);
		}

		inline void SetRevisionInfo(const CString& csBaseDestinationPath, DWORD dwMaxRevision, DWORD dwIntervalInMillisecond, const CStringList& objRevisionRelativePaths)
		{
			ULARGE_INTEGER u64;

			u64.QuadPart = (unsigned __int64)dwIntervalInMillisecond * 10 * 1000;
			SetRevisionInfo(csBaseDestinationPath, dwMaxRevision, u64, objRevisionRelativePaths);
		}

		inline void SetRevisionInfo(const CString& csBaseDestinationPath, DWORD dwMaxRevision = 0, DWORD dwIntervalInMillisecond = 24 * 60 * 60 * 1000)
		{
		}

		inline BOOL IsIncrementBackup() const { return m_fIncrementBackup; }

		inline void SetRevisionInfo(const CString& csBaseDestinationPath, DWORD dwMaxRevision, ULARGE_INTEGER u64RevisionIntervalTime, const CStringList& objRevisionRelativePaths)
		{
			CRevisionPath objRevisionPath;
			POSITION pos;
			SYSTEMTIME objSystemTime = {0};
			FILETIME objFileTime, objUTCFileTime;

//			if ( CSimpleFileBackup::IsNT() )
//				m_csBaseDestinationPath.Format(_T("\\\\?\\%s"), (LPCTSTR)(csBaseDestinationPath.GetAt(csBaseDestinationPath.GetLength() - 1) == _T('\\') ? csBaseDestinationPath.Left(csBaseDestinationPath.GetLength() - 1) : csBaseDestinationPath));
//			else
				m_csBaseDestinationPath = csBaseDestinationPath.GetAt(csBaseDestinationPath.GetLength() - 1) == _T('\\') ? csBaseDestinationPath.Left(csBaseDestinationPath.GetLength() - 1) : csBaseDestinationPath;
			m_dwMaxRevision = dwMaxRevision;
			m_u64RevisionInterval.QuadPart = u64RevisionIntervalTime.QuadPart;
			pos = objRevisionRelativePaths.GetHeadPosition();
			while ( pos )
			{

⌨️ 快捷键说明

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