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

📄 fastcopy.cpp

📁 fastcopy是一个非常快速的数据拷贝软件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			int		len = lstrlenV(path = pathArray[kind].Path(idx)), targ = FILE_EXP;			if (lGetCharV(path, len -1) == '\\') {				lSetCharV(path, len -1, 0);				targ = DIR_EXP;			}			if (!regExp[kind][targ].RegisterWildCard(path, RegExp::CASE_INSENSE))				return	ConfirmErr("Bad or Too long windcard string", path, FALSE), FALSE;		}	}	if (path)		isFilter = TRUE;	if ((info.flags & LISTING_ONLY) == 0 &&		(info.mode != DELETE_MODE || (info.flags & (OVERWRITE_DELETE|OVERWRITE_DELETE_NSA))) &&		(info.bufSize > MAX_BUF || info.bufSize < MIN_BUF * 2))		return	ConfirmErr("Too large or small Main Buffer.", NULL, FALSE), FALSE;	if ((info.flags & (DIR_REPARSE|FILE_REPARSE)) && (info.mode == MOVE_MODE || info.mode == DELETE_MODE)) {		return	ConfirmErr("Illega Flags (junction/symlink)", NULL, FALSE), FALSE;	}	// command	if (info.mode == DELETE_MODE) {		srcArray = *_srcArray;		if (InitDeletePath(0) == FALSE)			return	FALSE;	}	else {		srcArray = *_srcArray;		dstArray = *_dstArray;		if (InitDstPath() == FALSE)			return	FALSE;		if (InitSrcPath(0) == FALSE)			return	FALSE;	}	_info->isRenameMode = isRename;	return	!isAbort;}BOOL FastCopy::TakeExclusivePriv(void){	return	::WaitForSingleObject(hRunMutex, 0) == WAIT_OBJECT_0 ? TRUE : FALSE;}BOOL FastCopy::Start(void){	u_int	id;	int		allocSize = (info.flags & LISTING_ONLY) ? MAX_LIST_BUF : info.bufSize+PAGE_SIZE;	memset(&total, 0, sizeof(total));	if (info.flags & PRE_SEARCH)		total.isPreSearch = TRUE;	isAbort = FALSE;	writeReq = NULL;	isSuspend = FALSE;	dstAsyncRequest = DSTREQ_NONE;	nextFileID = 1;	errFileID = 0;	openFiles = NULL;	cv.Initialize(2);	// using condition valiable by 2 threads	readReqList.Init();	writeReqList.Init();	errBuf.AllocBuf(MIN_ERR_BUF, MAX_ERR_BUF);	if (info.flags & LISTING_ONLY)		listBuf.AllocBuf(MIN_PUTLIST_BUF, MAX_PUTLIST_BUF);	if (info.mode == DELETE_MODE) {		if ((info.flags & (OVERWRITE_DELETE|OVERWRITE_DELETE_NSA)) && (info.flags & LISTING_ONLY) == 0) {			if (mainBuf.AllocBuf(allocSize) == FALSE) {				ConfirmErr("Can't alloc memory(delBuf)", NULL, FALSE);				goto ERR;			}			SetupRandomDataBuf();		}		startTick = ::GetTickCount();		if (!(hReadThread = (HANDLE)_beginthreadex(0, 0, FastCopy::DeleteThread, this, 0, &id)))			goto ERR;		return	TRUE;	}	openFiles = new FileStat *[info.maxOpenFiles + MAX_ALTSTREAM]; /* for Alternate Stream */	openFilesCnt = 0;	// src/dst dir-entry/attr 梡僶僢僼傽妋曐	fileStatBuf.AllocBuf(MIN_ATTR_BUF, info.maxAttrSize);	dirStatBuf.AllocBuf(MIN_ATTR_BUF, info.maxDirSize);	dstStatBuf.AllocBuf(MIN_ATTR_BUF, info.maxAttrSize);	dstStatIdxBuf.AllocBuf(MIN_ATTRIDX_BUF, MAX_ATTRIDX_BUF(info.maxAttrSize));	if (info.flags & SKIP_EMPTYDIR)		mkdirQueueBuf.AllocBuf(MIN_MKDIRQUEUE_BUF, MAX_MKDIRQUEUE_BUF);	dstDirExtBuf.AllocBuf(MIN_DSTDIREXT_BUF, MAX_DSTDIREXT_BUF);	// 儊僀儞儕儞僌僶僢僼傽妋曐	if (mainBuf.AllocBuf(allocSize) == FALSE && (info.flags & LISTING_ONLY) == 0) {		ConfirmErr("Can't alloc memory(mainBuf)", NULL, FALSE);		goto ERR;	}	// 儕儞僌僶僢僼傽梡僆僼僙僢僩弶婜壔	usedOffset = freeOffset = mainBuf.Buf();	if (IS_WINNT_V && info.isPhysLock) {		::SetProcessWorkingSetSize(::GetCurrentProcess(), mainBuf.Size() + APP_MEMSIZE, mainBuf.Size() + APP_MEMSIZE);		mainBuf.LockBuf();		fileStatBuf.LockBuf();		dirStatBuf.LockBuf();		dstStatBuf.LockBuf();		dstStatIdxBuf.LockBuf();	}	startTick = ::GetTickCount();	if (!(hReadThread = (HANDLE)_beginthreadex(0, 0, FastCopy::ReadThread, this, 0, &id))	|| !(hWriteThread = (HANDLE)_beginthreadex(0, 0, FastCopy::WriteThread, this, 0, &id)))		goto ERR;	return	TRUE;ERR:	End();	return	FALSE;}/*=========================================================================  娭  悢 丗 ReadThread  奣  梫 丗 Read 張棟  愢  柧 丗   拲  堄 丗 =========================================================================*/unsigned WINAPI FastCopy::ReadThread(void *fastCopyObj){	return	((FastCopy *)fastCopyObj)->ReadThreadCore();}BOOL FastCopy::ReadThreadCore(void){	BOOL	isSameDrvOld;	int		done_cnt = 0;	if (info.flags & PRE_SEARCH)		PreSearch();	for (int i=0; i < srcArray.Num(); i++) {		if (InitSrcPath(i)) {			if (done_cnt >= 1 && isSameDrvOld != isSameDrv)				ChangeToWriteMode();			ReadProc(srcBaseLen, info.overWrite == BY_ALWAYS ? FALSE : TRUE);			isSameDrvOld = isSameDrv;			done_cnt++;		}		if (isAbort)			break;	}	SendRequest(REQ_EOF);	ChangeToWriteMode();	return	TRUE;}BOOL FastCopy::PreSearch(void){	BOOL	is_delete = info.mode == DELETE_MODE;	BOOL	(FastCopy::*InitPath)(int) = is_delete ? &FastCopy::InitDeletePath : &FastCopy::InitSrcPath;	void	*&path = is_delete ? dst : src;	int		&prefix_len = is_delete ? dstPrefixLen : srcPrefixLen;	int		&base_len = is_delete ? dstBaseLen : srcBaseLen;	BOOL	ret = TRUE;	for (int i=0; i < srcArray.Num(); i++) {		if ((this->*InitPath)(i)) {			if (!PreSearchProc(path, prefix_len, base_len))				ret = FALSE;		}		if (isAbort)			break;	}	total.isPreSearch = FALSE;	startTick = ::GetTickCount();	return	ret && !isAbort;}BOOL FastCopy::FilterCheck(const void *path, const void *fname, DWORD attr){	int	targ = IsDir(attr) ? DIR_EXP : FILE_EXP;	if (regExp[EXC_EXP][targ].IsMatch(fname))		return	FALSE;	if (!regExp[INC_EXP][targ].IsRegistered())		return	TRUE;	if (regExp[INC_EXP][targ].IsMatch(fname))		return	TRUE;	return	FALSE;}BOOL FastCopy::PreSearchProc(void *path, int prefix_len, int dir_len){	HANDLE		hDir;	BOOL		ret = TRUE;	WIN32_FIND_DATAW fdat;	if (waitTick) Wait(1);	if ((hDir = FindFirstFileV(path, &fdat)) == INVALID_HANDLE_VALUE) {		return	ConfirmErr("FindFirstFile(pre)", MakeAddr(path, prefix_len)), FALSE;	}	do {		if (IsParentOrSelfDirs(fdat.cFileName))			continue;		// src 僨傿儗僋僩儕帺懱偵懳偟偰偼丄僼傿儖僞懳徾偵偟側偄		if (isFilter && (dir_len != srcBaseLen || isMetaSrc) && !FilterCheck(path, fdat.cFileName, fdat.dwFileAttributes))			continue;		if (IsDir(fdat.dwFileAttributes)) {			total.preDirs++;			if (!IsReparse(fdat.dwFileAttributes) || (info.flags & DIR_REPARSE)) {				int len = sprintfV(MakeAddr(path, dir_len), FMT_CAT_ASTER_V, fdat.cFileName) -1;				ret = PreSearchProc(path, prefix_len, dir_len + len);			}		}		else {			total.preFiles++;			total.preTrans += (((_int64)fdat.nFileSizeHigh << 32) + fdat.nFileSizeLow);		}	}	while (!isAbort && FindNextFileV(hDir, &fdat));	if (!isAbort && ret && ::GetLastError() != ERROR_NO_MORE_FILES) {		ret = FALSE;		ConfirmErr("FindNextFile(pre)", MakeAddr(path, prefix_len));	}	::FindClose(hDir);	return	ret && !isAbort;}BOOL FastCopy::PutList(void *path, DWORD opt){	BOOL	add_backslash = GetChar(path, 0) == '\\' && GetChar(path, 1) != '\\';	::EnterCriticalSection(&listCs);	if (listBuf.RemainSize() >= MAX_PATHLEN_V || listBuf.Grow(MIN_PUTLIST_BUF)) {		int len = sprintfV(listBuf.Buf() + listBuf.UsedSize(), listBuf.UsedSize() ? FMT_LIST2_V : FMT_LIST1_V, (opt & PL_DELETE) ? '-' : '+', add_backslash ? BACK_SLASH_V : EMPTY_STR_V, path, (opt & PL_DIRECTORY) ? L"\\" : (opt & PL_COMPARE) ? L" !!" : L"");		listBuf.AddUsedSize(len * CHAR_LEN_V);	}	::LeaveCriticalSection(&listCs);	return	TRUE;}BOOL FastCopy::MakeDigest(void *path, VBuf *vbuf, TDigest *digest, BYTE *val){	DWORD	mode = GENERIC_READ;	DWORD	flg = ((info.flags & USE_OSCACHE_READ) ? 0 : FILE_FLAG_NO_BUFFERING) | FILE_FLAG_SEQUENTIAL_SCAN;	if (enableAcl || enableStream) {		mode |= READ_CONTROL;		flg  |= FILE_FLAG_BACKUP_SEMANTICS;	}	HANDLE	hFile = CreateFileV(path, mode, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, flg, 0);	BOOL	ret = FALSE;	memset(val, 0, SHA1_SIZE);	digest->Reset();	if (hFile == INVALID_HANDLE_VALUE)		return	FALSE;	if (vbuf->MaxSize() >= maxTransSize || vbuf->AllocBuf(maxTransSize, maxTransSize)) {		BY_HANDLE_FILE_INFORMATION	bhi;		if (::GetFileInformationByHandle(hFile, &bhi)) {			_int64	remain_size = ((_int64)bhi.nFileSizeHigh << 32) + bhi.nFileSizeLow;			while (remain_size > 0 && !isAbort) {				DWORD	trans_size = 0;				if (::ReadFile(hFile, vbuf->Buf(), maxTransSize, &trans_size, NULL) && trans_size > 0) {					digest->Update(vbuf->Buf(), trans_size);					remain_size -= trans_size;				}				else {					break;				}			}			if (remain_size == 0) {				ret = digest->GetVal(val);			}		}	}	::CloseHandle(hFile);	return	ret;}BOOL FastCopy::IsSameContents(){	if (!isSameDrv) {		DstRequest(DSTREQ_DIGEST);	}	BOOL	src_ret = MakeDigest(src, &srcDigestBuf, &srcDigest, srcDigestVal);	BOOL	dst_ret = isSameDrv ? MakeDigest(confirmDst, &dstDigestBuf, &dstDigest, dstDigestVal) : WaitDstRequest();	return	src_ret && dst_ret && memcmp(srcDigestVal, dstDigestVal, SHA1_SIZE) == 0 ? TRUE : FALSE;}BOOL FastCopy::ReadProc(int dir_len, BOOL confirm_dir){	BOOL		ret = TRUE;	FileStat	*srcStat, *statEnd;	FileStat	*dstStat = NULL;	int			new_dir_len, curDirStatSize;	int			confirm_len = dir_len + (dstBaseLen - srcBaseLen);	BOOL		is_rename_local = isRename;	BOOL		confirm_dir_local = confirm_dir || is_rename_local;	isRename = FALSE;	// top level 偺傒岠壥傪弌偡	if (waitTick) Wait(1);	// 僇儗儞僩偺僒僀僘傪曐懚	curDirStatSize = dirStatBuf.UsedSize();	if (confirm_dir_local && !isSameDrv)		DstRequest(DSTREQ_READSTAT);	// 僨傿儗僋僩儕僄儞僩儕傪愭偵偡傋偰撉傒庢傞	ret = ReadDirEntry(dir_len, confirm_dir_local);	if (confirm_dir_local && (isSameDrv ? ReadDstStat() : WaitDstRequest()) == FALSE || isAbort || !ret)		return	FALSE;	// 僼傽僀儖傪愭偵張棟	statEnd = (FileStat *)(fileStatBuf.Buf() + fileStatBuf.UsedSize());	for (srcStat = (FileStat *)fileStatBuf.Buf(); srcStat < statEnd; srcStat = (FileStat *)((BYTE *)srcStat + srcStat->size)) {		if (confirm_dir_local)			dstStat = hash.Search(srcStat->upperName, srcStat->hashVal);		if (dstStat) {			if (is_rename_local) {				SetRenameCount(srcStat);			}			else {				dstStat->isExists = TRUE;				if (!IsOverWriteFile(srcStat, dstStat) && (IsReparse(srcStat->dwFileAttributes) == IsReparse(dstStat->dwFileAttributes) || (info.flags & FILE_REPARSE))) {					if ((info.flags & LISTING_ONLY) && (info.flags & VERIFY_FILE)) {						strcpyV(MakeAddr(confirmDst, confirm_len), srcStat->cFileName);						strcpyV(MakeAddr(src, dir_len), srcStat->cFileName);						if (!IsSameContents() && !isAbort) {							PutList(MakeAddr(src, srcPrefixLen), PL_COMPARE|PL_NORMAL);						}					}					total.skipFiles++;					total.skipTrans += dstStat->FileSize();					continue;				}			}		}		total.readFiles++;		if (OpenFileProc(srcStat, dir_len) == FALSE || srcFsType == FSTYPE_NETWORK || waitTick && openFilesCnt >= 10 || openFilesCnt >= info.maxOpenFiles) {			ReadMultiFilesProc(dir_len);			CloseMultiFilesProc();		}		if (isAbort)			goto END;	}	ReadMultiFilesProc(dir_len);	CloseMultiFilesProc();	if (isAbort)		goto END;	statEnd = (FileStat *)(dirStatBuf.Buf() + dirStatBuf.UsedSize());	// 僨傿儗僋僩儕偺懚嵼妋擣	if (confirm_dir_local) {		for (srcStat = (FileStat *)(dirStatBuf.Buf() + curDirStatSize); srcStat < statEnd; srcStat = (FileStat *)((BYTE *)srcStat + srcStat->size)) {			if ((dstStat = hash.Search(srcStat->upperName, srcStat->hashVal)) != NULL) {				if (is_rename_local)					SetRenameCount(srcStat);				else					srcStat->isExists = dstStat->isExists = TRUE;			}			else				srcStat->isExists = FALSE;		}	}	// SYNC儌乕僪偺応崌丄僐僺乕尦偵柍偄僼傽僀儖傪嶍彍	if (confirm_dir_local && info.mode == SYNCCP_MODE) {		int		max = dstStatIdxBuf.UsedSize() / sizeof(FileStat *);		for (int i=0; i < max; i++) {			if ((dstStat = ((FileStat **)dstStatIdxBuf.Buf())[i])->isExists)				continue;			if (isFilter && !FilterCheck(confirmDst, dstStat->cFileName, dstStat->dwFileAttributes))				continue;

⌨️ 快捷键说明

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