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

📄 fastcopy.cpp

📁 fastcopy是一个非常快速的数据拷贝软件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			if (isSameDrv) {				if (IsDir(dstStat->dwFileAttributes))					ret = DeleteDirProc(confirmDst, confirm_len, dstStat->cFileName, dstStat);				else					ret = DeleteFileProc(confirmDst, confirm_len, dstStat->cFileName, dstStat);			}			else {				SendRequest(DELETE_FILES, 0, dstStat);			}			if (isAbort)				goto END;		}	}	// 僨傿儗僋僩儕張棟	for (srcStat = (FileStat *)(dirStatBuf.Buf() + curDirStatSize); srcStat < statEnd; srcStat = (FileStat *)((BYTE *)srcStat + srcStat->size)) {		BOOL	is_reparse = IsReparse(srcStat->dwFileAttributes) && (info.flags & DIR_REPARSE) == 0;		total.readDirs++;		ReqBuf	req_buf = {0};		new_dir_len = dir_len + sprintfV(MakeAddr(src, dir_len), FMT_STR_V, srcStat->cFileName);		if (confirm_dir && srcStat->isExists)			sprintfV(MakeAddr(confirmDst, confirm_len), FMT_CAT_ASTER_V, srcStat->cFileName);		if ((info.flags & LISTING_ONLY) == 0) {			if (enableAcl || is_reparse) {				GetDirExtData(&req_buf, srcStat);			}		}//	ReadFile 偱懳張//		if (!is_reparse && IsReparse(srcStat->dwFileAttributes)) {//			srcSectorSize = max(srcSectorSize, OPT_SECTOR_SIZE);//			sectorSize = max(srcSectorSize, dstSectorSize);//		}		new_dir_len += sprintfV(MakeAddr(src, new_dir_len), FMT_CAT_ASTER_V, L"") - 1;		if (SendRequest(confirm_dir && srcStat->isExists ? INTODIR : MKDIR, req_buf.buf ? &req_buf : 0, srcStat), isAbort)			goto END;		if (!is_reparse) {			if (ReadProc(new_dir_len, confirm_dir && srcStat->isExists), isAbort)				goto END;			if (SendRequest(RETURN_PARENT), isAbort)				goto END;		}	}END:	// 僇儗儞僩偺 dir梡Buf 僒僀僘傪暅尦	dirStatBuf.SetUsedSize(curDirStatSize);	return	ret && !isAbort;}BOOL FastCopy::GetDirExtData(ReqBuf *req_buf, FileStat *stat){	HANDLE	fh;	WIN32_STREAM_ID	sid;	DWORD	size, lowSeek, highSeek;	void	*context = NULL;	int		altdata_cnt = 0;	BYTE	streamName[MAX_PATH * sizeof(WCHAR)];	BOOL	ret = TRUE;	BOOL	is_reparse = IsReparse(stat->dwFileAttributes) && (info.flags & DIR_REPARSE) == 0;	int		used_size_save = dirStatBuf.UsedSize();	if ((fh = CreateFileV(src, GENERIC_READ|READ_CONTROL, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | (is_reparse ? FILE_FLAG_OPEN_REPARSE_POINT : 0), 0)) == INVALID_HANDLE_VALUE)		return	FALSE;	if (is_reparse) {		size = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;		if (dirStatBuf.RemainSize() <= (int)size + maxStatSize && dirStatBuf.Grow(ALIGN_SIZE(size + maxStatSize, MIN_ATTR_BUF)) == FALSE) {			ret = FALSE;			ConfirmErr("Can't alloc memory(dirStatBuf)", NULL, FALSE);		}		else if ((size = ReadReparsePoint(fh, dirStatBuf.Buf() + dirStatBuf.UsedSize(), size)) <= 0) {			ret = FALSE;			total.errDirs++;			ConfirmErr("ReadReparsePoint(Dir)", MakeAddr(src, srcPrefixLen));		}		else {			stat->rep = dirStatBuf.Buf() + dirStatBuf.UsedSize();			stat->repSize = size;			dirStatBuf.AddUsedSize(size);		}	}	while (ret) {		size = 0;		::SetLastError(0);		if (!::BackupRead(fh, (LPBYTE)&sid, STRMID_OFFSET, &size, FALSE, TRUE, &context) || size != STRMID_OFFSET) {			DWORD	errCode = ::GetLastError();			if (errCode != 0 && errCode != ERROR_INVALID_HANDLE && (info.flags & REPORT_ACL_ERROR))				ConfirmErr("BackupRead(DIR)", MakeAddr(src, srcPrefixLen));			break;		}		if (sid.dwStreamNameSize && !::BackupRead(fh, streamName, sid.dwStreamNameSize, &size, FALSE, TRUE, &context)) {			break;		}		if (sid.dwStreamId == BACKUP_SECURITY_DATA || sid.dwStreamId == BACKUP_EA_DATA) {			BYTE	*&data		= sid.dwStreamId == BACKUP_SECURITY_DATA ? stat->acl     : stat->ead;			int		&data_size	= sid.dwStreamId == BACKUP_SECURITY_DATA ? stat->aclSize : stat->eadSize;			if (data || sid.Size.HighPart) {	// 偡偱偵奿擺嵪傒				if (info.flags & REPORT_ACL_ERROR)					ConfirmErr("Duplicate or Too big ACL/EADATA(dir)", MakeAddr(src, srcPrefixLen));				break;			}			data = dirStatBuf.Buf() + dirStatBuf.UsedSize();			data_size = sid.Size.LowPart + STRMID_OFFSET;			dirStatBuf.AddUsedSize(data_size);			if (dirStatBuf.RemainSize() <= maxStatSize && !dirStatBuf.Grow(ALIGN_SIZE(maxStatSize + data_size, MIN_ATTR_BUF))) {				if (info.flags & REPORT_ACL_ERROR)					ConfirmErr("Can't alloc memory(dirStat(ACL/EADATA))", MakeAddr(src, srcPrefixLen), FALSE);				break;			}			memcpy(data, &sid, STRMID_OFFSET);			if (!::BackupRead(stat->hFile, data + STRMID_OFFSET, sid.Size.LowPart, &size, FALSE, TRUE, &context) || size <= 0) {				if (info.flags & REPORT_ACL_ERROR)					ConfirmErr("BackupRead(DirACL/EADATA)", MakeAddr(src, srcPrefixLen));				break;			}			sid.Size.LowPart = 0;		}		if ((sid.Size.LowPart || sid.Size.HighPart) && !::BackupSeek(fh, sid.Size.LowPart, sid.Size.HighPart, &lowSeek, &highSeek, &context)) {			if (info.flags & REPORT_ACL_ERROR)				ConfirmErr("BackupSeek(DIR)", MakeAddr(src, srcPrefixLen));			break;		}	}	::BackupRead(fh, NULL, NULL, NULL, TRUE, TRUE, &context);	::CloseHandle(fh);	if (ret && (size = stat->aclSize + stat->eadSize + stat->repSize) > 0) {		if ((ret = PrepareReqBuf(offsetof(ReqHeader, stat) + stat->minSize, size, stat->fileID, req_buf))) {			BYTE	*data = req_buf->buf;			if (stat->acl) {				memcpy(data, stat->acl, stat->aclSize);				stat->acl = data;				data += stat->aclSize;			}			if (stat->ead) {				memcpy(data, stat->ead, stat->eadSize);				stat->ead = data;				data += stat->eadSize;			}			if (stat->rep) {				memcpy(data, stat->rep, stat->repSize);				stat->rep = data;				data += stat->repSize;			}		}	}	dirStatBuf.SetUsedSize(used_size_save);	return	ret && !isAbort;}int FastCopy::MakeRenameName(void *buf, int count, void *fname){	void	*ext = strrchrV(fname, '.');	int		body_limit = ext ? DiffLen(ext, fname) : MAX_PATH;	return	sprintfV(buf, FMT_RENAME_V, body_limit, fname, count, ext ? ext : EMPTY_STR_V);}BOOL FastCopy::SetRenameCount(FileStat *stat){	while (1) {		WCHAR	new_name[MAX_PATH];		int		len = MakeRenameName(new_name, ++stat->renameCount, stat->upperName) + 1;		DWORD	hash_val = hashVal.MakeHash(new_name, len * CHAR_LEN_V);		if (hash.Search(new_name, hash_val) == NULL)			break;	}	return	TRUE;}/*	忋彂偒敾掕*/BOOL FastCopy::IsOverWriteFile(FileStat *srcStat, FileStat *dstStat){	if (info.overWrite == BY_NAME)		return	FALSE;// time stamp monitor#if 0	_int64	st = *(_int64 *)&srcStat->ftLastWriteTime;	_int64	dt = *(_int64 *)&dstStat->ftLastWriteTime;	if (st != dt && (info.flags & LISTING_ONLY)) {		::EnterCriticalSection(&listCs);		int len = sprintfV(listBuf.Buf() + listBuf.UsedSize(), L" src/dst: %I64d / %I64d", st, dt);		listBuf.AddUsedSize(len * CHAR_LEN_V);		::LeaveCriticalSection(&listCs);	}#endif	if (info.overWrite == BY_ATTR) {		// 僒僀僘偑摍偟偔丄偐偮...		if (dstStat->FileSize() == srcStat->FileSize()) {			if (*(_int64 *)&dstStat->ftLastWriteTime == *(_int64 *)&srcStat->ftLastWriteTime) {	// 峏怴擔晅偑姰慡偵摍偟偄				return	FALSE;			}			if (srcFsType != FSTYPE_NTFS || dstFsType != FSTYPE_NTFS) {	// 偳偪傜偐偑 NTFS 偱側偄応崌乮僱僢僩儚乕僋僪儔僀僽傪娷傓乯				// 曅曽偑 NTFS 偱側偄応崌丄1msec 枹枮偺岆嵎偼嫋梕偟偨忋偱丄斾妑乮UDF 懳嶔乯				if (*(_int64 *)&dstStat->ftLastWriteTime + 10000 >= *(_int64 *)&srcStat->ftLastWriteTime &&					*(_int64 *)&dstStat->ftLastWriteTime - 10000 <= *(_int64 *)&srcStat->ftLastWriteTime) {					return	FALSE;				}				// src 偐 dst 偺僞僀儉僗僞儞僾偺嵟彫扨埵偑 1 昩埲忋乮FAT or SAMBA 摍偺壜擻惈乯偱偐偮...				if ((*(_int64 *)&srcStat->ftLastWriteTime % 10000000) == 0 || (*(_int64 *)&dstStat->ftLastWriteTime % 10000000) == 0) {					// 僞僀儉僗僞儞僾偺嵎偑 2 昩埲撪側傜丄摨堦僞僀儉僗僞儞僾偲傒側偟偰丄忋彂偒偟側偄					if (*(_int64 *)&dstStat->ftLastWriteTime + 20000000 >= *(_int64 *)&srcStat->ftLastWriteTime &&						*(_int64 *)&dstStat->ftLastWriteTime - 20000000 <= *(_int64 *)&srcStat->ftLastWriteTime)						return	FALSE;				}			}		}		return	TRUE;	}	if (info.overWrite == BY_LASTEST) {		// 峏怴擔晅偑 dst 偲摨偠偐屆偄応崌偼峏怴偟側偄		if (*(_int64 *)&dstStat->ftLastWriteTime >= *(_int64 *)&srcStat->ftLastWriteTime) {			return	FALSE;		}		if (srcFsType != FSTYPE_NTFS || dstFsType != FSTYPE_NTFS) {	// 偳偪傜偐偑 NTFS 偱側偄応崌乮僱僢僩儚乕僋僪儔僀僽傪娷傓乯			// 曅曽偑 NTFS 偱側偄応崌丄1msec 枹枮偺岆嵎偼嫋梕偟偨忋偱丄斾妑乮UDF 懳嶔乯			if (*(_int64 *)&dstStat->ftLastWriteTime + 10000 >= *(_int64 *)&srcStat->ftLastWriteTime) {				return	FALSE;			}			// src 偐 dst 偺僞僀儉僗僞儞僾偺嵟彫扨埵偑 1 昩埲忋乮FAT or SAMBA 摍偺壜擻惈乯偱偐偮...			if ((*(_int64 *)&srcStat->ftLastWriteTime % 10000000) == 0 || (*(_int64 *)&dstStat->ftLastWriteTime % 10000000) == 0) {				// 僞僀儉僗僞儞僾偺嵎偵 2 昩偺儅乕僕儞傪晅偗偨忋偱丄 峏怴擔晅偑 dst 偲摨偠偐屆偄応崌偼丄忋彂偒偟側偄				if (*(_int64 *)&dstStat->ftLastWriteTime + 20000000 >= *(_int64 *)&srcStat->ftLastWriteTime)					return	FALSE;			}		}		return	TRUE;	}	if (info.overWrite == BY_ALWAYS)		return	TRUE;	return	ConfirmErr("Illegal overwrite mode", 0, FALSE), FALSE;}BOOL FastCopy::ReadDirEntry(int dir_len, BOOL confirm_dir){	HANDLE	fh;	BOOL	ret = TRUE;	int		len;	WIN32_FIND_DATAW fdat;	fileStatBuf.SetUsedSize(0);	if ((fh = FindFirstFileV(src, &fdat)) == INVALID_HANDLE_VALUE) {		total.errDirs++;		return	ConfirmErr("FindFirstFile", MakeAddr(src, srcPrefixLen)), FALSE;	}	do {		if (IsParentOrSelfDirs(fdat.cFileName))			continue;		// src 僨傿儗僋僩儕帺懱偵懳偟偰偼丄僼傿儖僞懳徾偵偟側偄		if (isFilter && (dir_len != srcBaseLen || isMetaSrc) && !FilterCheck(src, fdat.cFileName, fdat.dwFileAttributes))			continue;		// 僨傿儗僋僩儕仌僼傽僀儖忣曬偺拁愊		if (IsDir(fdat.dwFileAttributes)) {			len = FdatToFileStat(&fdat, (FileStat *)(dirStatBuf.Buf() + dirStatBuf.UsedSize()), confirm_dir);			dirStatBuf.AddUsedSize(len);			if (dirStatBuf.RemainSize() <= maxStatSize && dirStatBuf.Grow(MIN_ATTR_BUF) == FALSE) {				ConfirmErr("Can't alloc memory(dirStatBuf)", NULL, FALSE);				break;			}		}		else {			len = FdatToFileStat(&fdat, (FileStat *)(fileStatBuf.Buf() + fileStatBuf.UsedSize()), confirm_dir);			fileStatBuf.AddUsedSize(len);			if (fileStatBuf.RemainSize() <= maxStatSize && fileStatBuf.Grow(MIN_ATTR_BUF) == FALSE) {				ConfirmErr("Can't alloc memory(fileStatBuf)", NULL, FALSE);				break;			}		}	}	while (!isAbort && FindNextFileV(fh, &fdat));	if (!isAbort && ::GetLastError() != ERROR_NO_MORE_FILES) {		total.errFiles++;		ret = FALSE;		ConfirmErr("FindNextFile", MakeAddr(src, srcPrefixLen));	}	::FindClose(fh);	return	ret && !isAbort;}BOOL FastCopy::OpenFileProc(FileStat *stat, int dir_len){	DWORD	name_len = strlenV(stat->cFileName);	memcpy(MakeAddr(src, dir_len), stat->cFileName, ((name_len + 1) * CHAR_LEN_V));	stat->fileID = nextFileID++;	openFiles[openFilesCnt++] = stat;	if (waitTick) Wait((waitTick + 9) / 10);	BOOL	is_backup = enableAcl || enableStream;	BOOL	is_reparse = IsReparse(stat->dwFileAttributes) && (info.flags & FILE_REPARSE) == 0;	if (!is_backup && !is_reparse && stat->FileSize() == 0 || (info.flags & LISTING_ONLY))		return	TRUE;	DWORD	mode = GENERIC_READ;	DWORD	flg = ((info.flags & USE_OSCACHE_READ) ? 0 : FILE_FLAG_SEQUENTIAL_SCAN) | FILE_FLAG_NO_BUFFERING;	if (is_backup) {		mode |= READ_CONTROL;		flg  |= FILE_FLAG_BACKUP_SEMANTICS;	}	if (is_reparse) {		flg  |= FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT;	}	if ((stat->hFile = CreateFileV(src, mode, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, flg, 0)) == INVALID_HANDLE_VALUE) {		stat->lastError = ::GetLastError();		return	FALSE;	}	return	is_backup ? OpenFileBackupProc(stat, dir_len + name_len) : TRUE;}BOOL FastCopy::OpenFileBackupProc(FileStat *stat, int src_len){	WIN32_STREAM_ID	sid;	BOOL	ret = FALSE;	DWORD	size = 0;	DWORD	lowSeek, highSeek;	void	*context = NULL;	int		altdata_cnt = 0;	BYTE	streamName[MAX_PATH * sizeof(WCHAR)];	DWORD	flg = ((info.flags & USE_OSCACHE_READ) ? 0 : FILE_FLAG_NO_BUFFERING) | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_BACKUP_SEMANTICS;	while (1) {		::SetLastError(0);		if (!::BackupRead(stat->hFile, (LPBYTE)&sid, STRMID_OFFSET, &size, FALSE, TRUE, &context) || size != STRMID_OFFSET) {			DWORD	errCode = ::GetLastError();			if (errCode == 0 || errCode == ERROR_INVALID_HANDLE)				ret = TRUE;			else if (info.flags & (REPORT_ACL_ERROR|REPORT_STREAM_ERROR))				ConfirmErr("BackupRead(head)", MakeAddr(src, srcPrefixLen));			break;		}		if (sid.dwStreamNameSize) {			if (!::BackupRead(stat->hFile, streamName, sid.dwStreamNameSize, &size, FALSE, TRUE, &context)) {				if (info.flags & REPORT_STREAM_ERROR)					ConfirmErr("BackupRead(name)", MakeAddr(src, srcPrefixLen));				break;			}			lSetCharV((LPBYTE)streamName + sid.dwStreamNameSize, 0, 0);	// terminate 偝傟側偄偨傔乮dwStreamNameSize 偼僶僀僩悢乯		}		if (sid.dwStreamId == BACKUP_ALTERNATE_DATA && enableStream) {			FileStat *subStat = (FileStat *)(fileStatBuf.Buf() + fileStatBuf.UsedSize());			if (++altdata_cnt >= MAX_ALTSTREAM) {				if (info.flags & REPORT_STREAM_ERROR)					ConfirmErr("Too Many AltStream", MakeAddr(src, srcPrefixLen));				break;			}			openFiles[openFilesCnt++] = subStat;			subStat->fileID = nextFileID++;			subStat->hFile = INVALID_HANDLE_VALUE;			subStat->nFileSizeLow = sid.Size.LowPart;			subStat->nFileSizeHigh = sid.Size.HighPart;			subStat->dwFileAttributes = 0;	// ALTSTREAM			subStat->renameCount = 0;			subStat->lastError = 0;			subStat->size = sid.dwStreamNameSize + offsetof(FileStat, cFileName);			subStat->minSize = ALIGN_SIZE(subStat->size, 8);			fileStatBuf.AddUsedSize(subStat->minSize);			if (fileStatBuf.RemainSize() <= maxStatSize && fileStatBuf.Grow(MIN_ATTR_BUF) == FALSE) {				ConfirmErr("Can't alloc memory(fileStatBuf2)", NULL, FALSE);				break;			}			memcpy(subStat->cFileName, streamName, size + CHAR_LEN_V);			memcpy(MakeAddr(src, src_len), subStat->cFileName, size + CHAR_LEN_V);			if ((subStat->hFile = CreateFileV(src, GENERIC_READ|READ_CONTROL, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, flg, 0)) == INVALID_HANDLE_VALUE) {				if (info.flags & REPORT_STREAM_ERROR)					ConfirmErr("OpenFile(Stream)", MakeAddr(src, srcPrefixLen));				subStat->lastError = ::GetLastError();				break;			}		}		else if ((sid.dwStreamId == BACKUP_SECURITY_DATA || sid.dwStreamId == BACKUP_EA_DATA) && enableAcl) {			BYTE	*&data		= sid.dwStreamId == BACKUP_SECURITY_DATA ? stat->acl     : stat->ead;			int		&data_size	= sid.dwStreamId == BACKUP_SECURITY_DATA ? stat->aclSize : stat->eadSize;			if (data || sid.Size.HighPart) {	// 偡偱偵奿擺嵪傒				if (info.flags & REPORT_ACL_ERROR)					ConfirmErr("Duplicate or Too big ACL/EADATA", MakeAddr(src, srcPrefixLen));				break;

⌨️ 快捷键说明

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