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

📄 fastcopy.cpp

📁 fastcopy是一个非常快速的数据拷贝软件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{	int		new_dir_len = dir_len + sprintfV(MakeAddr(path, dir_len), FMT_CAT_ASTER_V, fname) -1;	BOOL	ret;	int		cur_skips = total.filterSkips;	if (info.mode == DELETE_MODE && (info.flags & (OVERWRITE_DELETE|OVERWRITE_DELETE_NSA))) {		memcpy(MakeAddr(confirmDst, dir_len), MakeAddr(path, dir_len), (new_dir_len - dir_len + 2) * CHAR_LEN_V);	}	if (!IsReparse(stat->dwFileAttributes)) {		if ((ret = DeleteProc(path, new_dir_len)), isAbort)			return	ret;	}	if (isFilter && (cur_skips != total.filterSkips || regExp[INC_EXP][FILE_EXP].IsRegistered()))		return	ret;	SetChar(path, new_dir_len - 1, 0);	if (info.flags & LISTING_ONLY) {		PutList(MakeAddr(path, dstPrefixLen), PL_DIRECTORY|PL_DELETE);	}	else {		if (!IsReparse(stat->dwFileAttributes))			SetFileAttributesV(path, stat->dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);		if (info.mode == DELETE_MODE && (info.flags & (OVERWRITE_DELETE|OVERWRITE_DELETE_NSA))) {			if (RenameRandomFname(dst, confirmDst, dir_len, new_dir_len-dir_len-1)) {				path = confirmDst;			}		}		if ((ret = RemoveDirectoryV(path)) == FALSE) {			total.errDirs++;			return	ConfirmErr("RemoveDirectory", MakeAddr(path, dstPrefixLen)), FALSE;		}	}	total.deleteDirs++;	return	ret;}BOOL FastCopy::DeleteFileProc(void *path, int dir_len, void *fname, FileStat *stat){	int	len = sprintfV(MakeAddr(path, dir_len), FMT_STR_V, fname);	if (info.flags & LISTING_ONLY) {		PutList(MakeAddr(path, dstPrefixLen), PL_DELETE);	}	else {		if (stat->dwFileAttributes & FILE_ATTRIBUTE_READONLY)			SetFileAttributesV(path, FILE_ATTRIBUTE_NORMAL);		if (info.mode == DELETE_MODE && (info.flags & (OVERWRITE_DELETE|OVERWRITE_DELETE_NSA)) && !IsReparse(stat->dwFileAttributes)) {			if (RenameRandomFname(dst, confirmDst, dir_len, len)) {				path = confirmDst;			}			if (stat->FileSize()) {				if (WriteRandomData(path, stat, TRUE) == FALSE) {					total.errFiles++;					return	ConfirmErr("OverWrite", MakeAddr(path, dstPrefixLen)), FALSE;				}				total.writeFiles++;			}		}		if (DeleteFileV(path) == FALSE) {			total.errFiles++;			return	ConfirmErr("DeleteFile", MakeAddr(path, dstPrefixLen)), FALSE;		}	}	total.deleteFiles++;	total.deleteTrans += stat->FileSize();	return	TRUE;}/*=========================================================================  奣  梫 丗 忋彂偒嶍彍梡儖乕僠儞=========================================================================*/void FastCopy::SetupRandomDataBuf(void){	RandomDataBuf	*data = (RandomDataBuf *)mainBuf.Buf();	data->is_nsa = (info.flags & OVERWRITE_DELETE_NSA) ? TRUE : FALSE;	data->base_size = max(PAGE_SIZE, dstSectorSize);	data->buf_size = mainBuf.Size() - data->base_size;	data->buf[0] = mainBuf.Buf() + data->base_size;	if (data->is_nsa) {		data->buf_size /= 3;		data->buf_size = (data->buf_size / data->base_size) * data->base_size;		data->buf_size = min(info.maxTransSize, data->buf_size);		data->buf[1] = data->buf[0] + data->buf_size;		data->buf[2] = data->buf[1] + data->buf_size;		if (info.flags & OVERWRITE_PARANOIA) {			TGenRandom(data->buf[0], data->buf_size);	// CryptAPI偺rand偼抶偄...			TGenRandom(data->buf[1], data->buf_size);		}		else {			for (int i=0, max=data->buf_size / sizeof(int) * 2; i < max; i++) {				*((int *)data->buf[0] + i) = rand();			}		}		memset(data->buf[2], 0, data->buf_size);	}	else {		data->buf_size = min(info.maxTransSize, data->buf_size);		if (info.flags & OVERWRITE_PARANOIA) {			TGenRandom(data->buf[0], data->buf_size);	// CryptAPI偺rand偼抶偄...		}		else {			for (int i=0, max=data->buf_size / sizeof(int); i < max; i++) {				*((int *)data->buf[0] + i) = rand();			}		}	}}void FastCopy::GenRandomName(void *path, int fname_len, int ext_len){	static char *char_dict = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";	for (int i=0; i < fname_len; i++) {		SetChar(path, i, char_dict[(rand() >> 4) % 62]);	}	if (ext_len) {		SetChar(path, fname_len - ext_len, '.');	}	SetChar(path, fname_len, 0);}BOOL FastCopy::RenameRandomFname(void *org_path, void *rename_path, int dir_len, int fname_len){	void	*fname = MakeAddr(org_path, dir_len);	void	*rename_fname = MakeAddr(rename_path, dir_len);	void	*dot = strrchrV(fname, '.');	int		ext_len = dot ? fname_len - DiffLen(dot, fname) : 0;	for (int i=fname_len; i <= MAX_FNAME_LEN; i++) {		for (int j=0; j < 128; j++) {			GenRandomName(rename_fname, i, ext_len);			if (MoveFileV(org_path, rename_path)) {				return	TRUE;			}			else if (::GetLastError() != ERROR_ALREADY_EXISTS) {				return	FALSE;			}		}	}	return	FALSE;}BOOL FastCopy::WriteRandomData(void *path, FileStat *stat, BOOL skip_hardlink){	BOOL	isNonBuf = dstFsType != FSTYPE_NETWORK && (stat->FileSize() >= max(nbMinSize, PAGE_SIZE) || (stat->FileSize() % dstSectorSize) == 0) && (info.flags & USE_OSCACHE_WRITE) == 0 ? TRUE : FALSE;	DWORD	flg = (isNonBuf ? FILE_FLAG_NO_BUFFERING : 0) | FILE_FLAG_SEQUENTIAL_SCAN;	DWORD	trans_size;	HANDLE	hFile = CreateFileV(path, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, flg, 0);	BOOL	ret = TRUE;	if (hFile == INVALID_HANDLE_VALUE) {		return	ConfirmErr("Write by Random Data(open)", MakeAddr(path, dstPrefixLen)), FALSE;	}	BY_HANDLE_FILE_INFORMATION	bhi;	if (!skip_hardlink || !::GetFileInformationByHandle(hFile, &bhi) || bhi.nNumberOfLinks <= 1) {		RandomDataBuf	*data = (RandomDataBuf *)mainBuf.Buf();		_int64			file_size = isNonBuf ? ALIGN_SIZE(stat->FileSize(), dstSectorSize) : stat->FileSize();		for (int i=0, end=data->is_nsa ? 3 : 1; i < end && ret; i++) {			::SetFilePointer(hFile, 0, NULL, FILE_BEGIN);			for (_int64 remain_size=file_size; remain_size > 0; remain_size -= trans_size) {				if (!(ret = ::WriteFile(hFile, data->buf[i], (DWORD)(remain_size > data->buf_size ? data->buf_size : remain_size), &trans_size, NULL))) {					break;				}				total.writeTrans += trans_size;			}			total.writeTrans -= file_size - stat->FileSize();			::FlushFileBuffers(hFile);		}		::SetFilePointer(hFile, 0, NULL, FILE_BEGIN);		::SetEndOfFile(hFile);	}	::CloseHandle(hFile);	return	ret;}/*=========================================================================  娭  悢 丗 WriteThread  奣  梫 丗 Write 張棟  愢  柧 丗   拲  堄 丗 =========================================================================*/unsigned WINAPI FastCopy::WriteThread(void *fastCopyObj){	return	((FastCopy *)fastCopyObj)->WriteThreadCore();}BOOL FastCopy::WriteThreadCore(void){	BOOL	ret = WriteProc(dstBaseLen);	if (info.mode == MOVE_MODE && !isAbort && errBuf.UsedSize() == 0 && total.errFiles == 0 && total.errDirs == 0)		DeleteThreadCore();	// 僄儔乕偑側偄側傜丄僜乕僗偺嶍彍	else		FinishNotify();	return	ret;}BOOL FastCopy::FinishNotify(void){	endTick = ::GetTickCount();	return	::PostMessage(info.hNotifyWnd, info.uNotifyMsg, END_NOTIFY, 0);}BOOL FastCopy::WriteProc(int dir_len){	BOOL		ret = TRUE;	int			new_dir_len;	FileStat	sv_stat;	while (!isAbort) {		if ((ret = RecvRequest()) == FALSE || writeReq->command == REQ_EOF) {			break;		}		if (writeReq->command == WRITE_FILE || writeReq->command == WRITE_BACKUP_FILE) {			if (writeReq->stat.renameCount == 0)				new_dir_len = dir_len + sprintfV(MakeAddr(dst, dir_len), FMT_STR_V, writeReq->stat.cFileName);			else				new_dir_len = dir_len + MakeRenameName(MakeAddr(dst, dir_len), writeReq->stat.renameCount, writeReq->stat.cFileName);			if (mkdirQueueBuf.UsedSize())				ExecDirQueue();			if (info.flags & LISTING_ONLY) {				PutList(MakeAddr(dst, dstPrefixLen), PL_NORMAL);				total.writeFiles++;				total.writeTrans += writeReq->stat.FileSize();			}			else if ((ret = WriteFileProc(new_dir_len)), isAbort)				break;		}		else if (writeReq->command == MKDIR || writeReq->command == INTODIR) {			BOOL	is_mkdir = writeReq->command == MKDIR;			BOOL	is_reparse = IsReparse(writeReq->stat.dwFileAttributes) && (info.flags & DIR_REPARSE) == 0;			int		buf_size = writeReq->bufSize;			memcpy(&sv_stat, &writeReq->stat, offsetof(FileStat, cFileName));			if (writeReq->stat.renameCount == 0)				new_dir_len = dir_len + sprintfV(MakeAddr(dst, dir_len), FMT_STR_V, writeReq->stat.cFileName);			else				new_dir_len = dir_len + MakeRenameName(MakeAddr(dst, dir_len), writeReq->stat.renameCount, writeReq->stat.cFileName);			if (buf_size) {				dstDirExtBuf.AddUsedSize(buf_size);				if (dstDirExtBuf.RemainSize() < MIN_DSTDIREXT_BUF && !dstDirExtBuf.Grow(MIN_DSTDIREXT_BUF)) {					ConfirmErr("Can't alloc memory(dstDirExtBuf)", NULL, FALSE);					break;				}				memcpy(dstDirExtBuf.Buf() + dstDirExtBuf.UsedSize(), writeReq->buf, buf_size);				sv_stat.acl = dstDirExtBuf.Buf() + dstDirExtBuf.UsedSize();				sv_stat.ead = sv_stat.acl + sv_stat.aclSize;				sv_stat.rep = sv_stat.ead + sv_stat.eadSize;			}			if (is_mkdir) {				if (is_reparse || (info.flags & SKIP_EMPTYDIR) == 0) {					if (info.flags & LISTING_ONLY) {						PutList(MakeAddr(dst, dstPrefixLen), PL_DIRECTORY);					}					else {						if (mkdirQueueBuf.UsedSize()) {							ExecDirQueue();						}						CreateDirectoryV(dst, NULL);					}					total.writeDirs++;				}				else {					if (mkdirQueueBuf.RemainSize() < sizeof(int) && mkdirQueueBuf.Grow(MIN_MKDIRQUEUE_BUF) == FALSE) {						ConfirmErr("Can't alloc memory(mkdirQueueBuf)", NULL, FALSE);						break;					}					*(int *)(mkdirQueueBuf.Buf() + mkdirQueueBuf.UsedSize()) = new_dir_len;					mkdirQueueBuf.AddUsedSize(sizeof(int));				}			}			strcpyV(MakeAddr(dst, new_dir_len), BACK_SLASH_V);			if (!is_reparse) {				if ((ret = WriteProc(new_dir_len + 1)), isAbort)	// 嵞婣					break;			}			SetChar(dst, new_dir_len, 0);	// 枛旜偺 '\\' 傪庢傞			if ((info.flags & LISTING_ONLY) == 0) {				if (!is_mkdir || (info.flags & SKIP_EMPTYDIR) == 0 || mkdirQueueBuf.UsedSize() == 0 || is_reparse) {					// 僞僀儉僗僞儞僾/ACL/懏惈/儕僷乕僗億僀儞僩偺僙僢僩					if ((ret = SetDirExtData(&sv_stat)) == FALSE && is_reparse && is_mkdir) {						RemoveDirectoryV(dst);	// 怴婯嶌惉僼僅儖僟偺儕僷乕僗億僀儞僩壔偵幐攕偟偨応崌偼丄僼僅儖僟嶍彍					}				}			}			if (buf_size) {				dstDirExtBuf.AddUsedSize(-buf_size);			}			if (mkdirQueueBuf.UsedSize()) {				mkdirQueueBuf.AddUsedSize(-(int)sizeof(int));			}		}		else if (writeReq->command == DELETE_FILES) {			if (IsDir(writeReq->stat.dwFileAttributes))				ret = DeleteDirProc(dst, dir_len, writeReq->stat.cFileName, &writeReq->stat);			else				ret = DeleteFileProc(dst, dir_len, writeReq->stat.cFileName, &writeReq->stat);		}		else if (writeReq->command == RETURN_PARENT) {			break;		}		else {			switch (writeReq->command) {			case WRITE_ABORT: case WRITE_FILE_CONT:			case WRITE_BACKUP_ACL: case WRITE_BACKUP_EADATA: case WRITE_BACKUP_ALTSTREAM: case WRITE_BACKUP_END:				break;			default:				ret = FALSE;				WCHAR cmd[2] = { writeReq->command + '0', 0 };				ConfirmErr("Illegal Request (internal error)", cmd, FALSE);				break;			}		}	}	return	ret && !isAbort;}BOOL FastCopy::ExecDirQueue(void){	for (int offset=0; offset < mkdirQueueBuf.UsedSize(); offset += sizeof(int)) {		int dir_len = *(int *)(mkdirQueueBuf.Buf() + offset);		SetChar(dst, dir_len, 0);		if (info.flags & LISTING_ONLY)			PutList(MakeAddr(dst, dstPrefixLen), PL_DIRECTORY);		else			CreateDirectoryV(dst, NULL);		SetChar(dst, dir_len, '\\');		total.writeDirs++;	}	mkdirQueueBuf.SetUsedSize(0);	return	TRUE;}BOOL FastCopy::SetDirExtData(FileStat *stat){	if (stat->dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM))		SetFileAttributesV(dst, stat->dwFileAttributes);	HANDLE	fh;	DWORD	mode = GENERIC_WRITE | (stat->acl && enableAcl ? (WRITE_OWNER|WRITE_DAC) : 0);	BOOL	is_reparse = IsReparse(stat->dwFileAttributes) && (info.flags & DIR_REPARSE) == 0;	BOOL	ret = TRUE;	if (!IS_WINNT_V || (fh = CreateFileV(dst, mode, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|(is_reparse ? FILE_FLAG_OPEN_REPARSE_POINT : 0), 0)) == INVALID_HANDLE_VALUE) {		if (is_reparse) {			total.errDirs++;		}		return	FALSE;	}	if (is_reparse) {		char	rp[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];		BOOL	is_set = TRUE;		if (ReadReparsePoint(fh, rp, sizeof(rp)) > 0) {			if (IsReparseDataSame(rp, stat->rep)) {				is_set = FALSE;			} else {				DeleteReparsePoint(fh, rp);			}		}		if (is_set) {			if (WriteReparsePoint(fh, stat->rep, stat->repSize) <= 0) {				ret = FALSE;				total.errDirs++;				ConfirmErr("WriteReparsePoint(dir)", MakeAddr(dst, dstPrefixLen));			}		}	}	if (stat->acl) {		void	*backupContent = NULL;		DWORD	size;		if (!::BackupWrite(fh, stat->acl, stat->aclSize, &size, FALSE, TRUE, &backupContent)) {			if (info.flags & REPORT_ACL_ERROR)				ConfirmErr("BackupWrite(DIRACL)", MakeAddr(dst, dstPrefixLen));		}		::BackupWrite(fh, NULL, NULL, NULL, TRUE, TRUE, &backupContent);	}	::SetFileTime(fh, &stat->ftCreationTime, &stat->ftLastAccessTime, &stat->ftLastWriteTime);	SYSTEMTIME	st;	FileTimeToSystemTime(&stat->ftLastWrit

⌨️ 快捷键说明

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