Feature: Add list_files and get_screenshot MCP tools
Add the two P2c MCP tools on top of the P2b protocol. list_files lists drives (COMMAND_LIST_DRIVE -> TOKEN_DRIVE_LIST) or a directory (follow-up COMMAND_LIST_FILES -> TOKEN_FILE_LIST on the same one-shot sub-link); get_screenshot reuses the screen-preview RPC with a per-host reqId correlation so stale or MFC-preview responses fall through to the MFC path untouched. Both share the P2b single-flight pending registry. Fix file/process name encoding: the client reads process names, paths and file names via the ANSI (A) APIs, so they are GBK on Windows regardless of the CLIENT_CAP_UTF8 capability bit (which governs window titles only). Decode by clientType (LNX/MAC = UTF-8, Windows = 936) rather than GetClientEncoding, and convert the list_files path to the client ANSI code page before sending. Sync Mcp_Phase2_Design.md with the P2c design and the encoding correction. Co-Authored-By: deepseek-v4-pro
This commit is contained in:
@@ -6190,6 +6190,12 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
|
||||
// (IO 线程不接触 UI;clientId 用于循环快照路由到对应窗口)。
|
||||
// 不用 WPARAM 携带 ID:32 位 Windows 上 WPARAM 是 32 位,会截 64 位 clientID。
|
||||
if (len < sizeof(ScreenPreviewRspHeader)) break;
|
||||
// P2c:MCP 挂起时接管(屏幕预览 = 主连接 RPC,不能 CancelIO)。
|
||||
// reqId 关联:命中 MCP 的 expectedReqId 才取走,避免误吞 MFC 预览在途响应。
|
||||
uint64_t previewDevId = ContextObject->GetClientID();
|
||||
const ScreenPreviewRspHeader* previewHdr = reinterpret_cast<const ScreenPreviewRspHeader*>(szBuffer);
|
||||
if (McpServer().TakePreviewResponse(previewDevId, previewHdr->reqId, szBuffer, len))
|
||||
break;
|
||||
auto* msg = new CMy2015RemoteDlg::PreviewRspMsg{
|
||||
ContextObject->GetClientID(),
|
||||
std::vector<BYTE>(szBuffer, szBuffer + len)
|
||||
@@ -6316,10 +6322,29 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
|
||||
break;
|
||||
}
|
||||
case TOKEN_DRIVE_LIST: { // 文件管理【x】
|
||||
// P2c:MCP 挂起时接管。列盘 = 取走数据后用完即关;列目录 = 转向下发
|
||||
// COMMAND_LIST_FILES、等 TOKEN_FILE_LIST(此时不关子链接,交给 TOKEN_FILE_LIST 分支收尾)。
|
||||
uint64_t devId = ContextObject->GetClientID();
|
||||
if (McpServer().IsPending(devId)) {
|
||||
if (McpServer().OnDriveList(devId, ContextObject, szBuffer, len))
|
||||
ContextObject->CancelIO(); // 只列盘 → 用完即关一次性子链接
|
||||
break;
|
||||
}
|
||||
ContextObject->EnableZstdContext(6);
|
||||
g_2015RemoteDlg->SendMessage(WM_OPENFILEMANAGERDIALOG, 0, (LPARAM)ContextObject);
|
||||
break;
|
||||
}
|
||||
case TOKEN_FILE_LIST: { // 文件列表【P2c:仅 MCP 无头路径会到达】
|
||||
// 正常文件管理由 FileManagerDlg 的 hDlg 接管,TOKEN_FILE_LIST 不进此分派;
|
||||
// 到达此处只有 MCP 无头列目录这一种情形。挂起命中则取数据,否则(超时迟到)
|
||||
// 直接关掉孤儿子链接,避免泄漏。
|
||||
uint64_t devId = ContextObject->GetClientID();
|
||||
if (McpServer().IsPending(devId)) {
|
||||
McpServer().TakeMainResponse(devId, ContextObject->GetBuffer(0), ContextObject->GetBufferLength());
|
||||
}
|
||||
ContextObject->CancelIO(); // 无论是否命中,用完即关(无 MFC 对话框接管此子链接)
|
||||
break;
|
||||
}
|
||||
case TOKEN_TALK_START: { // 发送消息【x】
|
||||
g_2015RemoteDlg->SendMessage(WM_OPENTALKDIALOG, 0, (LPARAM)ContextObject);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user