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

📄 fastcopy.cpp

📁 fastcopy是一个非常快速的数据拷贝软件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
static char *fastcopy_id = 	"@(#)Copyright (C) H.Shirouzu 2004-2008   fastcopy.cpp	Ver1.70";/* ========================================================================	Project  Name			: Fast Copy file and directory	Create					: 2004-09-15(Wed)	Update					: 2008-02-02(Sat)	Copyright				: H.Shirouzu	Reference				: 	======================================================================== */#include "fastcopy.h"#include <stdarg.h>#include <stddef.h>#include <process.h>#include <stdio.h>void *NTFS_STR_V;		// "NTFS"void *FMT_RENAME_V;		// ".%03d"void *FMT_LIST1_V;		//void *FMT_LIST2_V;		//#define STRMID_OFFSET offsetof(WIN32_STREAM_ID, cStreamName)#define MAX_ALTSTREAM 1000#define IsDir(attr) (attr & FILE_ATTRIBUTE_DIRECTORY)#define IsReparse(attr) (attr & FILE_ATTRIBUTE_REPARSE_POINT)#define IsNoReparseDir(attr) (IsDir(attr) && !IsReparse(attr))BOOL SetPrivilege(LPTSTR pszPrivilege, BOOL bEnable){    HANDLE           hToken;    TOKEN_PRIVILEGES tp;    if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))        return FALSE;    if (!::LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid))        return FALSE;    tp.PrivilegeCount = 1;    if (bEnable)         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;    else         tp.Privileges[0].Attributes = 0;    if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))         return FALSE;    if (!::CloseHandle(hToken))         return FALSE;    return TRUE;}/*=========================================================================  僋儔僗 丗 FastCopy  奣  梫 丗 儅儖僠僗儗僢僪側僼傽僀儖僐僺乕娗棟僋儔僗  愢  柧 丗   拲  堄 丗 =========================================================================*/FastCopy::FastCopy(){	hReadThread = hWriteThread = NULL;	SetPrivilege(SE_BACKUP_NAME, TRUE);	SetPrivilege(SE_RESTORE_NAME, TRUE);	SetPrivilege(SE_CREATE_SYMBOLIC_LINK_NAME, TRUE);	::InitializeCriticalSection(&errCs);	::InitializeCriticalSection(&listCs);	hRunMutex = ::CreateMutex(NULL, FALSE, FASTCOPY_MUTEX);	if (IS_WINNT_V) {		src = new WCHAR [MAX_PATHLEN_V + MAX_PATH];		dst = new WCHAR [MAX_PATHLEN_V + MAX_PATH];		confirmDst = new WCHAR [MAX_PATHLEN_V + MAX_PATH];		NTFS_STR_V		= L"NTFS";		FMT_INT_STR_V	= L"%d";		FMT_RENAME_V	= L"%.*s(%d)%s";		FMT_LIST1_V		= L"%c %s%s%s";		FMT_LIST2_V		= L"\r\n%c %s%s%s";	}	else {		src = new char [MAX_PATHLEN_V + MAX_PATH_EX];		dst = new char [MAX_PATHLEN_V + MAX_PATH_EX];		confirmDst = new char [MAX_PATHLEN_V + MAX_PATH_EX];		NTFS_STR_V		= "NTFS";		FMT_INT_STR_V	= "%d";		FMT_RENAME_V	= "%.*s(%d)%s";		FMT_LIST1_V		= "%c %s%s%s";		FMT_LIST2_V		= "\r\n%c %s%s%s";	}	maxStatSize = (MAX_PATH * CHAR_LEN_V) * 2 + offsetof(FileStat, cFileName) + 8;	hashVal.Init(MAX_PATH * CHAR_LEN_V);	waitTick = 0;}FastCopy::~FastCopy(){	delete [] confirmDst;	delete [] dst;	delete [] src;	::CloseHandle(hRunMutex);	::DeleteCriticalSection(&listCs);	::DeleteCriticalSection(&errCs);}BOOL FastCopy::GetRootDir(const void *path, void *root_dir){	if (GetChar(path, 0) == '\\') {	// "\\server\volname\" 4偮栚偺 \ 傪尒偮偗傞		DWORD	ch;		int		backslash_cnt = 0, offset;		for (offset=0; (ch = GetChar(path, offset)) != 0 && backslash_cnt < 4; offset++) {			if (ch == '\\')				backslash_cnt++;		}		memcpy(root_dir, path, offset * CHAR_LEN_V);		if (backslash_cnt < 4)					// 4偮偺 \ 偑側偄応崌偼丄枛旜偵 \ 傪晅梌			SetChar(root_dir, offset++, '\\');	// 乮\\server\volume 側偳乯		SetChar(root_dir, offset, 0);	// NULL terminate	}	else {	// "C:\" 摍		memcpy(root_dir, path, 3 * CHAR_LEN_V);		SetChar(root_dir, 3, 0);	// NULL terminate	}	return	TRUE;}FastCopy::FsType FastCopy::GetFsType(const void *root_dir){	if (GetDriveTypeV(root_dir) == DRIVE_REMOTE)		return	FSTYPE_NETWORK;	DWORD	serial, max_fname, fs_flags;	WCHAR	vol[MAX_PATH], fs[MAX_PATH];	if (GetVolumeInformationV(root_dir, vol, MAX_PATH, &serial, &max_fname, &fs_flags, fs, MAX_PATH) == FALSE)		return	ConfirmErr("GetVolumeInformation", root_dir, FALSE), FSTYPE_NONE;	return	lstrcmpiV(fs, NTFS_STR_V) == 0 ? FSTYPE_NTFS : FSTYPE_FAT;}int FastCopy::GetSectorSize(const void *root_dir){	DWORD	spc, bps, fc, cl;	if (GetDiskFreeSpaceV(root_dir, &spc, &bps, &fc, &cl) == FALSE) {//		if (IS_WINNT_V)//			ConfirmErr("GetDiskFreeSpace", root_dir, FALSE);		return	OPT_SECTOR_SIZE;	}	return	bps;}BOOL FastCopy::IsSameDrive(const void *root1, const void *root2){	if (GetChar(root1, 1) == ':' && GetChar(root2, 1) == ':')		return	driveMng.IsSameDrive(GetChar(root1, 0), GetChar(root2, 0));	if (GetChar(root1, 1) != GetChar(root2, 1) || GetDriveTypeV(root1) != GetDriveTypeV(root2))		return	FALSE;	return	lstrcmpiV(root1, root2) == 0 ? TRUE : FALSE;}int FastCopy::MakeUnlimitedPath(WCHAR *buf){	int		prefix_len;	WCHAR	*prefix;	BOOL	isUNC = (*buf == '\\') ? TRUE : FALSE;	prefix		= isUNC ? PATH_UNC_PREFIX : PATH_LOCAL_PREFIX;	prefix_len	= isUNC ? PATH_UNC_PREFIX_LEN : PATH_LOCAL_PREFIX_LEN;	// (isUNC ? 1 : 0) ... PATH_UNC_PREFIX 偺応崌丄\\server -> \\?\UNC\server 	//  偵偡傞偨傔丄\\server 偺摢偺 \ 傪堦偮捵偡丅	memmove(buf + prefix_len - (isUNC ? 1 : 0), buf, (strlenV(buf) + 1) * CHAR_LEN_V);	memcpy(buf, prefix, prefix_len * CHAR_LEN_V);	return	prefix_len;}BOOL FastCopy::InitDstPath(void){	DWORD	attr;	WCHAR	wbuf[MAX_PATH_EX];	void	*buf = wbuf, *fname = NULL;	const void	*org_path = dstArray.Path(0), *dst_root;	// dst 偺妋擣/壛岺	if (GetChar(org_path, 1) == ':' && GetChar(org_path, 2) != '\\')		return	ConfirmErr(GetLoadStr(IDS_BACKSLASHERR), org_path, FALSE), FALSE;	if (GetFullPathNameV(org_path, MAX_PATHLEN_V, dst, &fname) == 0)		return	ConfirmErr("GetFullPathName", org_path, FALSE), FALSE;	GetRootDir(dst, buf);	dstArray.RegisterPath(buf);	dst_root = dstArray.Path(dstArray.Num() -1);	attr = GetFileAttributesV(dst);	if ((attr = GetFileAttributesV(dst)) == 0xffffffff) {		if (info.flags & LISTING_ONLY)			info.overWrite = BY_ALWAYS;	// dst 偑懚嵼偟側偄偨傔丄挷嵏偺昁梫偑側偄		else {			CreateDirectoryV(dst, NULL);			if ((attr = GetFileAttributesV(dst)) == 0xffffffff)				return	ConfirmErr("CreateDirectory", dst, FALSE), FALSE;		}	}	if (!IsDir(attr))	// 椺奜揑偵 reparse point 傕 dir 埖偄		return	ConfirmErr("Not a directory", dst, FALSE), FALSE;	strcpyV(buf, dst);	MakePathV(dst, buf, EMPTY_STR_V);	// src帺懱傪僐僺乕偡傞偐乮dst枛旜偵 \ 偑偮偄偰偄傞 or 暋悢巜掕乯	isExtendDir = strcmpV(buf, dst) == 0 || srcArray.Num() > 1 ? TRUE : FALSE;	dstPrefixLen = IS_WINNT_V ? MakeUnlimitedPath((WCHAR *)dst) : 0;	dstBaseLen = strlenV(dst);	// dst 僼傽僀儖僔僗僥儉忣曬庢摼	dstSectorSize = GetSectorSize(dst_root);	dstFsType = GetFsType(dst_root);	nbMinSize = dstFsType == FSTYPE_NTFS ? info.nbMinSizeNtfs : info.nbMinSizeFat;	// 嵟戝揮憲僒僀僘	maxTransSize = isSameDrv ? info.bufSize : info.bufSize / 2;	maxTransSize = min(info.maxTransSize, maxTransSize);	// 嵎暘僐僺乕梡dst愭僼傽僀儖妋擣	strcpyV(confirmDst, dst);	return	TRUE;}BOOL FastCopy::InitSrcPath(int idx){	DWORD		attr;	BYTE		src_root_cur[MAX_PATH];	WCHAR		wbuf[MAX_PATH_EX];	void		*buf = wbuf, *fname = NULL;	const void	*dst_root = dstArray.Path(dstArray.Num() -1);	const void	*org_path = srcArray.Path(idx);	// src 偺妋擣/壛岺	if (GetChar(org_path, 1) == ':' && GetChar(org_path, 2) != '\\')		return	ConfirmErr(GetLoadStr(IDS_BACKSLASHERR), org_path), FALSE;	if (GetFullPathNameV(org_path, MAX_PATHLEN_V, src, &fname) == 0)		return	ConfirmErr("GetFullPathName", org_path), FALSE;	GetRootDir(src, src_root_cur);	isMetaSrc = FALSE;	if ((attr = GetFileAttributesV(src)) == 0xffffffff) {		isMetaSrc = TRUE;	}	else if (IsDir(attr)) {		// 恊僨傿儗僋僩儕帺懱傪僐僺乕偟側偄応崌丄\* 傪晅梌		strcpyV(buf, src);		MakePathV(src, buf, ASTERISK_V);		if (lstrcmpiV(buf, src_root_cur) && (isExtendDir || ((info.flags & DIR_REPARSE) == 0 && IsReparse(attr))))			SetChar(src, strlenV(src) - 2, 0);	// 枛旜偵 \* 傪晅偗側偄		else			isMetaSrc = TRUE;	}	srcPrefixLen = IS_WINNT_V ? MakeUnlimitedPath((WCHAR *)src) : 0;	if (GetFullPathNameV(src, MAX_PATH_EX, buf, &fname) == 0 || fname == NULL)		return	ConfirmErr("GetFullPathName2", MakeAddr(src, srcPrefixLen)), FALSE;	// 妋擣梡dst惗惉	strcpyV(MakeAddr(confirmDst, dstBaseLen), fname);	// 摨堦僷僗偱側偄偙偲偺妋擣	if (lstrcmpiV(buf, confirmDst) == 0) {		if (info.mode != DIFFCP_MODE || (info.flags & SAMEDIR_RENAME) == 0)			return	ConfirmErr(GetLoadStr(IDS_SAMEPATHERR), MakeAddr(confirmDst, dstBaseLen), FALSE), FALSE;		strcpyV(MakeAddr(confirmDst, dstBaseLen), ASTERISK_V);		isRename = TRUE;	}	else		isRename = FALSE;	if (info.mode == MOVE_MODE && IsNoReparseDir(attr)) {	// 恊偐傜巕傊偺堏摦偼擣傔側偄		int	end_offset = 0;		if (GetChar(fname, 0) == '*' || attr == 0xffffffff) {			SetChar(fname, 0, 0);			end_offset = 1;		}		int		len = IS_WINNT_V ? strlenV(buf) : ::lstrlenA((char *)buf);		if (srcBaseLen <= dstBaseLen && strnicmpV(buf, confirmDst, len) == 0) {			DWORD ch = GetChar(confirmDst, len - end_offset);			if (ch == 0 || ch == '\\') {				return	ConfirmErr(GetLoadStr(IDS_PARENTPATHERR), MakeAddr(buf, srcPrefixLen), FALSE), FALSE;			}		}	}	SetChar(fname, 0, 0);	srcBaseLen = strlenV(buf);	// src 僼傽僀儖僔僗僥儉忣曬庢摼	if (lstrcmpiV(src_root_cur, src_root)) {		srcSectorSize = GetSectorSize(src_root_cur);		srcFsType = GetFsType(src_root_cur);		sectorSize = max(srcSectorSize, dstSectorSize);		// 戝偒偄傎偆偵崌傢偣傞		sectorSize = max(sectorSize, MIN_SECTOR_SIZE);		// 摨堦暔棟僪儔僀僽偐偳偆偐偺挷嵏		if (info.flags & FIX_SAMEDISK)			isSameDrv = TRUE;		else if (info.flags & FIX_DIFFDISK)			isSameDrv = FALSE;		else			isSameDrv = IsSameDrive(src_root_cur, dst_root);		if (info.mode == MOVE_MODE)			isSameVol = strcmpV(src_root_cur, dst_root);	}	enableAcl = (info.flags & WITH_ACL) && srcFsType != FSTYPE_FAT && dstFsType != FSTYPE_FAT;	enableStream = (info.flags & WITH_ALTSTREAM) && srcFsType != FSTYPE_FAT && dstFsType != FSTYPE_FAT;	strcpyV(src_root, src_root_cur);	return	TRUE;}BOOL FastCopy::InitDeletePath(int idx){	DWORD		attr;	WCHAR		wbuf[MAX_PATH_EX];	void		*buf = wbuf, *fname = NULL;	const void	*org_path = srcArray.Path(idx);	BYTE		dst_root[MAX_PATH];	// delete 梡 path 偺妋擣/壛岺	if (GetChar(org_path, 1) == ':' && GetChar(org_path, 2) != '\\')		return	ConfirmErr(GetLoadStr(IDS_BACKSLASHERR), org_path), FALSE;	if (GetFullPathNameV(org_path, MAX_PATHLEN_V, dst, &fname) == 0)		return	ConfirmErr("GetFullPathName", org_path), FALSE;	attr = GetFileAttributesV(dst);	if (attr != 0xffffffff && IsNoReparseDir(attr) || (info.flags & (OVERWRITE_DELETE|OVERWRITE_DELETE_NSA))) {		GetRootDir(dst, dst_root);		if (info.flags & (OVERWRITE_DELETE|OVERWRITE_DELETE_NSA)) {			dstSectorSize = GetSectorSize(dst_root);			dstFsType = GetFsType(dst_root);			nbMinSize = dstFsType == FSTYPE_NTFS ? info.nbMinSizeNtfs : info.nbMinSizeFat;		}	}	isMetaSrc = FALSE;	if (attr == 0xffffffff) {		isMetaSrc = TRUE;	}	else if (IsDir(attr)) {		strcpyV(buf, dst);		// root_dir 偼枛旜偵 "\*" 傪晅梌丄偦傟埲奜偼枛旜偺 "\"傪嶍彍		MakePathV(dst, buf, ASTERISK_V);		if (!IsReparse(attr) && lstrcmpiV(buf, dst_root) == 0)			isMetaSrc = TRUE;		else			SetChar(dst, strlenV(dst) - 2, 0);	}	dstPrefixLen = IS_WINNT_V ? MakeUnlimitedPath((WCHAR *)dst) : 0;	if (GetFullPathNameV(dst, MAX_PATH_EX, buf, &fname) == 0 || fname == NULL)		return	ConfirmErr("GetFullPathName2", MakeAddr(dst, dstPrefixLen)), FALSE;	SetChar(fname, 0, 0);	dstBaseLen = strlenV(buf);	if (info.flags & (OVERWRITE_DELETE|OVERWRITE_DELETE_NSA)) {		strcpyV(confirmDst, dst);	// for renaming before deleting	}	return	TRUE;}BOOL FastCopy::RegisterInfo(const PathArray *_srcArray, const PathArray *_dstArray, Info *_info, const PathArray *_includeArray, const PathArray *_excludeArray){	isAbort = FALSE;	isRename = FALSE;	isMetaSrc = FALSE;	isFilter = FALSE;	endTick = 0;	info = *_info;	SetChar(src_root, 0, 0);	if (info.flags & LISTING_ONLY)		info.flags &= ~PRE_SEARCH;	// filter	PathArray	pathArray[] = { *_includeArray, *_excludeArray };	void		*path = NULL;	for (int kind=0; kind < MAX_KIND_EXP; kind++) {		for (int ftype=0; ftype < MAX_FTYPE_EXP; ftype++)			regExp[kind][ftype].Init();		for (int idx=0; idx < pathArray[kind].Num(); idx++) {

⌨️ 快捷键说明

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