Feature: Add list_registry MCP tool

Add a read-only list_registry MCP tool for querying a remote Windows
host's registry. An empty path returns the five root keys; a path such as
HKEY_LOCAL_MACHINE plus subkeys returns that key's immediate subkeys and
values (name, type, and formatted data).

Client side: enumerate with KEY_READ instead of KEY_ALL_ACCESS and map the
full value-type set (REG_SZ, REG_DWORD, REG_BINARY, REG_EXPAND_SZ,
REG_MULTI_SZ, REG_QWORD, REG_NONE) so unknown types are no longer
mis-reported as REG_SZ. The registry manager now always sends both the
TOKEN_REG_PATH and TOKEN_REG_KEY packets (an empty packet when a part is
empty), making the two-packet reply deterministic for the server.

Server side: add the three-phase flow (COMMAND_REGEDIT, COMMAND_REG_FIND,
then PATH plus KEY) with per-host pending state, parse the fixed-width
wire format with bounds checks, format value data for JSON, and guard
registry paths against exceeding MAX_PATH to protect the client stack.

Co-Authored-By: deepseek-v4-pro
This commit is contained in:
yuanyuanxianganddeepseek-v4-pro committed 2026-08-23 10:37:55 +02:00
1 parent 8815c4f896
commit 8bd6f3b60a
5 files changed
+508 -19

No files matched your search

+20 -1
View File
@@ -83,6 +83,21 @@ public:
// 等 TOKEN_FILE_LIST(调用方不关子链接)。
bool OnDriveList(uint64_t device_id, context* subCtx, const BYTE* buf, ULONG len);
// ===== P3:list_registry(注册表查询,三阶段:COMMAND_REGEDIT → TOKEN_REGEDIT →
// COMMAND_REG_FIND → TOKEN_REG_PATH + TOKEN_REG_KEY)=====
// MessageHandle(TOKEN_REGEDIT) 调用:挂起命中且为 list_registry 则下发 COMMAND_REG_FIND
// 并返回 true(接管子链接,不打开 MFC 对话框);否则 false(回落 MFC)。
bool OnRegeditReady(uint64_t device_id, context* subCtx);
// MessageHandle(TOKEN_REG_PATH / TOKEN_REG_KEY) 调用:两包都到齐后置 done 并唤醒等待者。
void TakeRegPath(uint64_t device_id, const BYTE* data, ULONG len);
void TakeRegKey(uint64_t device_id, const BYTE* data, ULONG len);
// 工具线程:等待注册表两包(子键 + 值);成功返回 true 并把两包分别写入 out,超时返回 false。
bool WaitPendingRegistry(uint64_t device_id, std::vector<BYTE>& subkeys,
std::vector<BYTE>& values, int timeoutMs);
private:
CMcpServer();
~CMcpServer();
@@ -101,9 +116,13 @@ private:
// 挂起请求注册表(受 m_PendingMutex 保护,键 = device_id)。
struct PendingRequest {
std::string tool;
std::string path; // list_files:目录路径;空 = 只列盘
std::string path; // list_files:目录路径;list_registry:rootToken(1B)+相对子键路径
uint16_t expectedReqId = 0; // get_screenshot:期望的预览 reqId(0 = 未设置)
std::vector<BYTE> data;
std::vector<BYTE> regPath; // list_registry:TOKEN_REG_PATH 子键包(含 token 字节)
std::vector<BYTE> regKey; // list_registry:TOKEN_REG_KEY 值包(含 token 字节)
bool pathDone = false; // list_registry:已收到 TOKEN_REG_PATH
bool keyDone = false; // list_registry:已收到 TOKEN_REG_KEY
bool done = false;
};
std::mutex m_PendingMutex;