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

📄 fastcopy.h

📁 FastCopy 利用缓冲技术加快文件拷贝
💻 H
字号:
/* static char *fastcopy_id = 
	"@(#)Copyright (C) H.Shirouzu 2004-2007   fastcopy.h	Ver1.52"; */
/* ========================================================================
	Project  Name			: Fast Copy file and directory
	Create					: 2004-09-15(Wed)
	Update					: 2007-02-06(Tue)
	Copyright				: H.Shirouzu
	Reference				: 
	======================================================================== */

#include "tlib.h"
#include "resource.h"
#include "utility.h"
#include "regexp.h"

#define ALIGN_SIZE(all_size, block_size) (((all_size) + (block_size) -1) / (block_size) * (block_size))

#define MIN_SECTOR_SIZE		(512)
#define OPT_SECTOR_SIZE		(2048)
#define MAX_BUF				(1024 * 1024 * 1024)
#define MIN_BUF				(1024 * 1024)
#define BIGTRANS_ALIGN		(32 * 1024)
#define APP_MEMSIZE			(6 * 1024 * 1024)
#define PATH_LOCAL_PREFIX	L"\\\\?\\"
#define PATH_UNC_PREFIX		L"\\\\?\\UNC"
#define PATH_LOCAL_PREFIX_LEN	4
#define PATH_UNC_PREFIX_LEN		7
#define MIN_ATTR_BUF		(256 * 1024)
//#define MAX_ATTR_BUF		(128 * 1024 * 1024)
#define MIN_ATTRIDX_BUF		ALIGN_SIZE((MIN_ATTR_BUF / 4), PAGE_SIZE)
#define MAX_ATTRIDX_BUF(x)	ALIGN_SIZE(((x) / 4), PAGE_SIZE)
#define MIN_MKDIRQUEUE_BUF	(8 * 1024)
#define MAX_MKDIRQUEUE_BUF	(64 * 1024)
#define MIN_ERR_BUF			(32 * 1024)
#define MAX_ERR_BUF			(64 * 1024)
#define MAX_LIST_BUF		(128 * 1024)
#define MAX_PUTLIST_BUF		(128 * 1024 * 1024)
#define MIN_PUTLIST_BUF		(1024 * 1024)

#define FASTCOPY_MUTEX		"FastCopyMutex"
#define FASTCOPY_EVENT		"FastCopyEvent"

struct TotalTrans {
	BOOL	isPreSearch;
	int		preDirs;
	int		preFiles;
	_int64	preTrans;
	int		readDirs;
	int		readFiles;
	_int64	readTrans;
	int		writeDirs;
	int		writeFiles;
	_int64	writeTrans;
	int		deleteDirs;
	int		deleteFiles;
	_int64	deleteTrans;
	int		skipDirs;
	int		skipFiles;
	_int64	skipTrans;
	int		filterSkips;
	int		errFiles;
	int		errDirs;
	_int64	errTrans;
	int		openRetry;
};

struct TransInfo {
	TotalTrans			total;
	DWORD				tickCount;
	BOOL				isSameDrv;
	BOOL				ignoreErr;
	DWORD				autoSlow;

	VBuf				*errBuf;
	CRITICAL_SECTION	*errCs;

	VBuf				*listBuf;
	CRITICAL_SECTION	*listCs;

	WCHAR				curPath[MAX_PATH_EX];
};

struct FileStat {
	_int64		fileID;
	FILETIME	ftCreationTime;
	FILETIME	ftLastAccessTime;
	FILETIME	ftLastWriteTime;
	DWORD		nFileSizeLow;	// WIN32_FIND_DATA 偺 nFileSizeLow/High
	DWORD		nFileSizeHigh;	// 偲偼媡弴乮_int64 梡乯
	DWORD		dwFileAttributes;
	HANDLE		hFile;
	DWORD		lastError;
	int			renameCount;
	BOOL		isExists;
	int			size;
	int			minSize;		// upperName 暘傪娷傔側偄
	BYTE		*upperName;		// cFileName 廔抂+1傪巜偡
	DWORD		hashVal;		// upperName 偺 hash抣
	FileStat	*next;			// for hashTable
	BYTE		cFileName[4];	// 4 == dummy

	_int64	FileSize() { return *(_int64 *)&nFileSizeLow; }
	void	SetFileSize(_int64 file_size) { *(_int64 *)&nFileSizeLow = file_size; }
};

class StatHash {
	FileStat	**hashTbl;
	int			hashNum;
	int			HashNum(int data_num);

public:
	StatHash() {}
	int		RequireSize(int data_num) { return	sizeof(FileStat *) * HashNum(data_num); }
	BOOL	Init(FileStat **data, int _data_num, void *tbl_buf);
	FileStat *Search(void *upperName, DWORD hash_val);
};

struct DirStatTag {
	int			statNum;
	int			oldStatSize;
	FileStat	*statBuf;
	FileStat	**statIndex;
};

class FastCopy {
public:
	enum Mode { DIFFCP_MODE, SYNCCP_MODE, MOVE_MODE, DELETE_MODE };
	enum OverWrite { BY_NAME, BY_ATTR, BY_LASTEST, BY_CONTENTS, BY_ALWAYS };
	enum FsType { FSTYPE_NONE, FSTYPE_NTFS, FSTYPE_FAT, FSTYPE_NETWORK };
	enum Flags { CREATE_OPENERR_FILE=1, USE_OSCACHE_READ=2, USE_OSCACHE_WRITE=4, PRE_SEARCH=8, SAMEDIR_RENAME=0x10, SKIP_EMPTYDIR=0x20, FIX_SAMEDISK=0x40, FIX_DIFFDISK=0x80, AUTOSLOW_IOLIMIT=0x100, LISTING_ONLY=0x10000000 };

	struct Info {
		BOOL	ignoreErr;		// (I/ )
		Mode	mode;			// (I/ )
		OverWrite overWrite;	// (I/ )
		BOOL	isPhysLock;		// (I/ )
		int		flags;			// (I/ )
		int		bufSize;		// (I/ )
		int		maxOpenFiles;	// (I/ )
		int		maxTransSize;	// (I/ )
		int		maxAttrSize;	// (I/ )
		int		maxDirSize;		// (I/ )
		int		nbMinSizeNtfs;	// (I/ ) FILE_FLAG_NO_BUFFERING 偱僆乕僾儞偡傞嵟彫僼傽僀儖僒僀僘
		int		nbMinSizeFat;	// (I/ ) FILE_FLAG_NO_BUFFERING 偱僆乕僾儞偡傞嵟彫僼傽僀儖僒僀僘 (FAT梡)
		TWin	*notifyWnd;		// (I/ )
		UINT	uNotifyMsg;		// (I/ )
		int		lcid;			// (I/ )

		BOOL	isRenameMode;	// ( /O) ...乽暋惢偟傑偡乿僟僀傾儘僌僞僀僩儖梡忣曬乮巄掕乯
	};							//			 彨棃揑偵丄忣曬偑憹偊傟偽丄儊儞僶偐傜愗傝棧偟

	enum Notify { END_NOTIFY, CONFIRM_NOTIFY, RENAME_NOTIFY };
	struct Confirm {
		enum Result { CANCEL_RESULT, IGNORE_RESULT, CONTINUE_RESULT };
		const char	*message;		// (I/ )
		BOOL		allow_continue;	// (I/ )
		const void	*path;			// (I/ )
		Result		result;			// ( /O)
	};
//	struct Rename {
//		enum Result { CANCEL_RENAME, AUTO_RENAME, AUTOALL_RENAME, MANUAL_RENAME };
//		char	*message;		// (I/ )
//		void	*path;			// (I/ )
//		void	*rename;		// (I/O)
//		Result	result;			// ( /O)
//	};

	int	maxStatSize;		// max size of FileStat
	int	nbMinSize;			// struct Info 嶲徠

protected:
	enum Command { WRITE_FILE, WRITE_FILE_CONT, WRITE_ABORT, REMOVE_FILES, MKDIR, INTODIR, DELETE_FILES, RETURN_PARENT, REQ_EOF /*, READDIR*/ };
	enum PutListOpt { PL_NORMAL, PL_DIRECTORY, PL_DELETE };
	struct ReqHeader : public TListObj {	// request header
		Command		command;
		BYTE		*buf;
		int			bufSize;
		int			reqSize;
		FileStat	stat;	// 壜曄挿
	};
	struct ReqBuf {
		BYTE		*buf;
		int			bufSize;
		ReqHeader	*req;
		int			reqSize;
	};

	// 婎杮忣曬
	DriveMng	driveMng;	// Drive 忣曬
	Info		info;		// 僆僾僔儑儞巜掕摍
	StatHash	hash;
	HashVal		hashVal;
	PathArray	srcArray;
	PathArray	dstArray;
	void	*src;			// src 僷僗奿擺梡
	void	*dst;			// dst 僷僗奿擺梡
	void	*confirmDst;	// 忋彂偒妋擣挷嵏梡
	int		srcBaseLen;		// src 僷僗偺屌掕晹暘偺挿偝
	int		dstBaseLen;		// dst 僷僗偺屌掕晹暘偺挿偝
	int		srcPrefixLen;	// \\?\ or \\?\UNC\ 偺挿偝
	int		dstPrefixLen;
	BOOL	isExtendDir;
	BOOL	isMetaSrc;

	// filter
	BOOL	isFilter;
	enum	{ FILE_EXP, DIR_EXP, MAX_FTYPE_EXP };
	enum	{ INC_EXP, EXC_EXP, MAX_KIND_EXP };
	RegExp	regExp[MAX_FTYPE_EXP][MAX_KIND_EXP];

	// 僶僢僼傽
	VBuf	mainBuf;		// Read/Write 梡 buffer
	VBuf	fileStatBuf;	// src file stat 梡 buffer
	VBuf	dirStatBuf;		// src dir stat 梡 buffer
	VBuf	dstStatBuf;		// dst dir/file stat 梡 buffer
	VBuf	dstStatIdxBuf;	// dstStatBuf 撪 entry 偺 index sort 梡
	VBuf	mkdirQueueBuf;
	VBuf	errBuf;
	VBuf	listBuf;

	// 僙僋僞忣曬側偳
	int		srcSectorSize;
	int		dstSectorSize;
	int		sectorSize;
	int		maxTransSize;
	FsType	srcFsType;
	FsType	dstFsType;
	BYTE	src_root[MAX_PATH];

	TotalTrans	total;		// 僼傽僀儖僐僺乕摑寁忣曬

	DWORD	startTick;
	DWORD	suspendTick;
	DWORD	autoSlow;

	BOOL	isAbort;
	BOOL	isSuspend;
	BOOL	isSameDrv;
	BOOL	isSameVol;
	BOOL	isRename;
	BOOL	readDestStatQueue;
	BOOL	readDestStatResult;

	HANDLE	hReadThread;
	HANDLE	hWriteThread;

	class TReqList : public TList {
	public:
		TReqList(void) {}
		ReqHeader *TopObj(void) { return (ReqHeader *)TList::TopObj(); }
		ReqHeader *NextObj(ReqHeader *obj) { return (ReqHeader *)TList::NextObj(obj); }
	};

	HANDLE		hRunMutex;
	Condition	cv;

	CRITICAL_SECTION errCs;
	CRITICAL_SECTION listCs;

	TReqList	readReqList;
	TReqList	writeReqList;
	BYTE		*usedOffset;
	BYTE		*freeOffset;
	ReqHeader	*writeReq;
	_int64		nextFileID;
	_int64		errFileID;

	FileStat	**openFiles;
	int			openFilesCnt;

	static unsigned WINAPI ReadThread(void *fastCopyObj);
	static unsigned WINAPI WriteThread(void *fastCopyObj);
	static unsigned WINAPI DeleteThread(void *fastCopyObj);

	BOOL ReadThreadCore(void);
	BOOL DeleteThreadCore(void);
	BOOL WriteThreadCore(void);
	BOOL PreSearch(void);
	BOOL PreSearchProc(void *path, int prefix_len, int dir_len);
	BOOL ReadProc(int dir_len, BOOL confirm_dir=TRUE);
	BOOL IsOverWriteFile(FileStat *srcStat, FileStat *dstStat);
	int  MakeRenameName(void *new_fname, int count, void *org_fname);
	BOOL SetRenameCount(FileStat *stat);
	BOOL FilterCheck(const void *path, const void *fname, DWORD attr);
	BOOL ReadDirEntry(int dir_len, BOOL confirm_dir);
	BOOL OpenFileProc(FileStat *stat, int dir_len);
	BOOL ReadMultiFilesProc(void);
	BOOL CloseMultiFilesProc(void);
	BOOL ReadFileProc(FileStat *stat);
	BOOL DeleteProc(void *path, int dir_len);
	BOOL DeleteDirProc(void *path, int dir_len, void *fname, FileStat *stat);
	BOOL DeleteFileProc(void *path, int dir_len, void *fname, FileStat *stat);
	void ReadDestStatRequest(void);
	BOOL WaitReadDestStat(void);
	BOOL ReadDestStat(void);
	BOOL MakeHashTable(void);
	void FreeDestStat(void);
	static int SortStatFunc(const void *stat1, const void *stat2);
	BOOL ExecDirQueue(void);
	BOOL WriteProc(int dir_len);
	BOOL WriteFileProc(void);
	BOOL ChangeToWriteModeCore(void);
	BOOL ChangeToWriteMode(void);
	BOOL AllocReqBuf(int req_size, _int64 _data_size, ReqBuf *buf);
	BOOL PrepareReqBuf(int req_size, _int64 data_size, _int64 file_id, ReqBuf *buf);
	BOOL SendRequest(Command command, ReqBuf *buf=NULL, FileStat *stat=NULL);
	BOOL RecvRequest(void);
	void WriteReqDone(void);
	void SetErrFileID(_int64 file_id);

	BOOL InitSrcPath(int idx);
	BOOL InitDeletePath(int idx);
	BOOL InitDstPath(void);
	BOOL GetRootDir(const void *path, void *root_dir);
	FsType GetFsType(const void *root_dir);
	int GetSectorSize(const void *root_dir);
	BOOL IsSameDrive(const void *root1, const void *root2);
	int MakeUnlimitedPath(WCHAR *buf);
	BOOL PutList(void *path, DWORD opt);

	inline BOOL IsParentOrSelfDirs(void *name) { return *(BYTE *)name == '.' && (!strcmpV(name, DOT_V) || !strcmpV(name, DOTDOT_V)); }
	int FdatToFileStat(WIN32_FIND_DATAW *fdat, FileStat *stat, BOOL is_usehash);
	Confirm::Result ConfirmErr(const char *message, const void *path=NULL, BOOL allow_continue=TRUE);
	BOOL ConvertExternalPath(const void *path, void *buf, int buf_len, BOOL to_ansi=FALSE);

public:
	FastCopy(void);
	virtual ~FastCopy();

	BOOL RegisterInfo(const PathArray *_srcArray, const PathArray *_dstArray, Info *_info, const PathArray *_includeArray=NULL, const PathArray *_excludeArray=NULL);
	BOOL TakeExclusivePriv(void);
	BOOL Start(void);
	BOOL End(void);
	BOOL IsStarting(void) { return hReadThread || hWriteThread; }
	BOOL Suspend(void);
	BOOL Resume(void);
	void Aborting(void) { isAbort = TRUE; WriteErrLog(" Aborted by User"); }
	BOOL FastCopy::WriteErrLog(char *message, int len=-1);
	BOOL IsAborting(void) { return isAbort; }
	void SetAutoSlow(DWORD wait) { autoSlow = wait; }
	DWORD GetAutoSlow() { return autoSlow; }
	BOOL GetTransInfo(TransInfo *ti, BOOL fullInfo=TRUE);
};

⌨️ 快捷键说明

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