📄 shellext.cpp
字号:
}
/*=========================================================================
娭 悢 丗
奣 梫 丗 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 + -