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

📄 shellext.cpp

📁 FastCopy 利用缓冲技术加快文件拷贝
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

/*=========================================================================
  娭  悢 丗 
  奣  梫 丗 DLL Export 娭悢孮
  愢  柧 丗 
  拲  堄 丗 
=========================================================================*/
STDAPI DllCanUnloadNow(void)
{
	return SysObj && SysObj->DllRefCnt == 0 ? S_OK : S_FALSE;
}

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
{
	*ppvOut = NULL;

	if (IsEqualIID(rclsid, CURRENT_SHEXT_CLSID) || IsEqualIID(rclsid, CURRENT_SHEXTLNK_CLSID)) {
		ShellExtClassFactory	*cf = new ShellExtClassFactory;
		return cf->QueryInterface(riid, ppvOut);
	}
	return CLASS_E_CLASSNOTAVAILABLE;
}

BOOL GetClsId(REFIID cls_name, char *cls_id, int size)
{
	WCHAR		*w_cls_id;
	IMalloc		*im = NULL;

	::StringFromIID(cls_name, &w_cls_id);

	if (w_cls_id)
		::WideCharToMultiByte(CP_ACP, 0, w_cls_id, -1, cls_id, size, NULL, NULL);

	::CoGetMalloc(1, &im);
	im->Free(w_cls_id);
	im->Release();
	return	TRUE;
}

STDAPI DllRegisterServer(void)
{
	if (SHGetPathFromIDListV == NULL)
		return	E_FAIL;

	TShellExtRegistry	reg;

// CLASSKEY 搊榐
	if (reg.CreateClsKey()) {
		reg.SetStr(NULL, FASTCOPY);
		if (reg.CreateKey("InProcServer32")) {
			reg.SetStr(NULL, SysObj->DllName);
			reg.SetStr("ThreadingModel", "Apartment");
			reg.CloseKey();
		}
	}

// 娭楢晅偗
	reg.ChangeTopKey(HKEY_CLASSES_ROOT);
	for (int i=0; DllRegKeys[i]; i++) {
		if (reg.CreateKey(DllRegKeys[i])) {
			if (reg.CreateKey(FASTCOPY)) {
				reg.SetStr(NULL, reg.clsId);
				reg.CloseKey();
			}
			reg.CloseKey();
		}
	}

// NT宯偺捛壛
	if (IsWinNT())  {
		reg.ChangeTopKey(HKEY_LOCAL_MACHINE);
		if (reg.OpenKey("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved")) {
			reg.SetStr(reg.clsId, FASTCOPY);
			reg.CloseKey();
		}
	}
	return S_OK;
}

STDAPI DllUnregisterServer(void)
{
	TShellExtRegistry	reg;

// CLASS_KEY 嶍彍
	reg.DeleteChildTree(reg.clsId);

// 娭楢晅偗 嶍彍
	reg.ChangeTopKey(HKEY_CLASSES_ROOT);
	for (int i=0; DllRegKeys[i]; i++) {
		if (reg.OpenKey(DllRegKeys[i])) {
			reg.DeleteChildTree(FASTCOPY);
			reg.CloseKey();
		}
	}

// 媽僶乕僕儑儞梡 (.lnk 愱梡)
	TShellExtRegistry	linkreg(CURRENT_SHEXTLNK_CLSID);
	linkreg.DeleteChildTree(linkreg.clsId);

// NT宯偺捛壛
	if (IsWinNT())  {
		reg.ChangeTopKey(HKEY_LOCAL_MACHINE);
		if (reg.OpenKey("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved")) {
			reg.DeleteValue(reg.clsId);
			reg.DeleteValue(linkreg.clsId);	// 媽僶乕僕儑儞梡 (.lnk 愱梡)
			reg.CloseKey();
		}
	}

	return S_OK;
}

/*=========================================================================
  娭  悢 丗 FastCopy 梡 export 娭悢
  奣  梫 丗 
  愢  柧 丗 
  拲  堄 丗 
=========================================================================*/
BOOL WINAPI SetMenuFlags(int flags)
{
	TRegistry	reg(HKEY_CLASSES_ROOT);

	return	reg.OpenKey(SysObj->MenuFlgRegKey) && reg.SetInt(MENU_FLAGS, flags);
}

int WINAPI GetMenuFlags(void)
{
	TRegistry	reg(HKEY_CLASSES_ROOT);
	int			val = -1;

	if (reg.OpenKey(SysObj->MenuFlgRegKey))
		reg.GetInt(MENU_FLAGS, &val);

	return	val;
}

BOOL WINAPI UpdateDll(void)
{
	int		val = GetMenuFlags();

	const GUID *oldiids[] = {
		&CLSID_ShellExtID1, // ID1 偵偼 lnkid 偼側偄
		&CLSID_ShellExtID2, &CLSID_ShellExtLinkID2,
		&CLSID_ShellExtID3, &CLSID_ShellExtLinkID3,
		&CLSID_ShellExtID4, &CLSID_ShellExtLinkID4,
		NULL };

	for (int i=0; oldiids[i]; i++) {
		TShellExtRegistry	oldReg(*oldiids[i]);
		oldReg.DeleteChildTree(oldReg.clsId);
	}

	if (val != -1) {
		DllRegisterServer();
		SetMenuFlags(val);
	}
	return	TRUE;
}

BOOL WINAPI IsRegistServer(void)
{
	return	TShellExtRegistry().OpenClsKey();
}

/*=========================================================================
	PathArray
=========================================================================*/
PathArray::PathArray(void)
{
	totalLen = num = 0;
	pathArray = NULL;
}

PathArray::~PathArray()
{
	Init();
}

void PathArray::Init(void)
{
	if (pathArray) {
		while (--num >= 0)
			free(pathArray[num]);
		free(pathArray);
		pathArray = NULL;
		totalLen = num = 0;
	}
}

int PathArray::GetMultiPath(void *multi_path, int max_len)
{
	int		total_len = 0;
	void	*FMT_STR	= IS_WINNT_V ? (void *)L"%s\"%s\"" : (void *)"%s\"%s\"";
	void	*SPACE_STR	= IS_WINNT_V ? (void *)L" " : (void *)" ";

	for (int i=0; i < num; i++) {
		if (total_len + strlenV(pathArray[i]) + 4 >= max_len)
			break;
		total_len += wsprintfV((char *)multi_path + total_len * CHAR_LEN_V, FMT_STR, i ? SPACE_STR : "\0", pathArray[i]);
	}
	return	total_len;
}

int PathArray::GetMultiPathLen(void)
{
	return	totalLen + 3 * num + 10;
}

BOOL PathArray::RegisterPath(const void *path)
{
#define MAX_ALLOC	100
	if ((num % MAX_ALLOC) == 0)
		pathArray = (void **)realloc(pathArray, (num + MAX_ALLOC) * sizeof(void *));

	int		len = strlenV(path) + 1;
	pathArray[num] = malloc(len * CHAR_LEN_V);
	memcpy(pathArray[num++], path, len * CHAR_LEN_V);
	totalLen += len;

	return	TRUE;
}

TShellExtRegistry::TShellExtRegistry(REFIID cls_name) : TRegistry(HKEY_CLASSES_ROOT)
{
	GetClsId(cls_name, clsId, sizeof(clsId));
	OpenKey("CLSID");
}

ShellExtSystem::ShellExtSystem(HINSTANCE hI)
{
	if (IS_WINNT_V = IsWinNT()) {
		DragQueryFileV = (UINT (WINAPI *)(HDROP, UINT, void *, UINT))DragQueryFileW;
		SHGetPathFromIDListV = (BOOL (WINAPI *)(LPCITEMIDLIST, void *))::GetProcAddress(::GetModuleHandle("shell32.dll"), "SHGetPathFromIDListW");
		strlenV = (int (*)(const void *))wcslen;
		wsprintfV = (int (WINAPI *)(void *, const void *,...))wsprintfW;
		MakePathV = (int (*)(void *, const void *, const void *))MakePathW;
		EMPTY_STR_V = L"";
		FMT_TOSTR_V = L" /to=\"%s\"";
		CHAR_LEN_V = sizeof(WCHAR);
	}
	else {
		DragQueryFileV = (UINT (WINAPI *)(HDROP, UINT, void *, UINT))DragQueryFileA;
		SHGetPathFromIDListV = (BOOL (WINAPI *)(LPCITEMIDLIST, void *))SHGetPathFromIDList;
		strlenV = (int (*)(const void *))strlen;
		wsprintfV = (int (WINAPI *)(void *, const void *,...))wsprintfA;
		MakePathV = (int (*)(void *, const void *, const void *))MakePath;
		EMPTY_STR_V = "";
		FMT_TOSTR_V = " /to=\"%s\"";
		CHAR_LEN_V = sizeof(char);
	}

	HInstance = hI;
	DllRefCnt = 0;

// GetSystemDefaultLCID() 偵婎偯偄偨儕僜乕僗暥帤楍傪帠慜偵儘乕僪偟偰偍偔
	LCID	curLcid = ::GetThreadLocale();
	LCID	newLcid = ::GetSystemDefaultLCID();

	if (curLcid != newLcid)
		::SetThreadLocale(newLcid);

	InitInstanceForLoadStr(hI);
	for (UINT id=IDS_RIGHTCOPY; id <= IDS_DDMOVE; id++)
		GetLoadStr(id);

	if (curLcid != newLcid)
		::SetThreadLocale(curLcid);

	char	path[MAX_PATH], *fname = NULL;
	::GetModuleFileName(hI, path, MAX_PATH);
	DllName = strdup(path);
	::GetFullPathName(DllName, MAX_PATH, path, &fname);
	if (fname)
		strcpy(fname, FASTCOPY_EXE);
	ExeName = strdup(path);

	wsprintf(path, "%s\\" FASTCOPY, DllRegKeys[0]);
	MenuFlgRegKey = strdup(path);
}

/*=========================================================================
  娭  悢 丗 DllMain
  奣  梫 丗 
  愢  柧 丗 
  拲  堄 丗 
=========================================================================*/
int APIENTRY DllMain(HINSTANCE hI, DWORD reason, PVOID)
{
	switch (reason) {
	case DLL_PROCESS_ATTACH:
		if (SysObj == NULL)
			SysObj = new ShellExtSystem(hI);
		return	TRUE;

	case DLL_THREAD_ATTACH:
		return	TRUE;

	case DLL_THREAD_DETACH:
		return	TRUE;

	case DLL_PROCESS_DETACH:
		if (SysObj) {
			delete [] SysObj->ExeName;
			delete SysObj;
			SysObj = NULL;
		}
		return	TRUE;
	}
	return	TRUE;
}


⌨️ 快捷键说明

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