Fix: Linux client UTF-8 path/active-window garbled on server
This commit is contained in:
@@ -178,15 +178,25 @@ bool SupportsFileTransferV2(context* ctx) {
|
||||
}
|
||||
|
||||
// 获取客户端协议字符串编码:优先看自身能力位,若是子连接(CAPABILITIES 为空)
|
||||
// 则通过 peer IP 查主连接。找不到则默认 CP936。
|
||||
// 则通过 peer IP 查主连接。Linux/macOS 客户端文件系统路径与 locale 现代发行版
|
||||
// 默认就是 UTF-8——即便客户端二进制是早于 CLIENT_CAP_UTF8 引入(commit 0aa7588)
|
||||
// 之前编译的,没声明 cap 位,事实上仍发 UTF-8 字节,按 client type 兜底走 UTF-8。
|
||||
// 找不到则默认 CP936。
|
||||
UINT GetClientEncoding(context* ctx) {
|
||||
if (!ctx) return 936;
|
||||
// 主连接情形:CAPABILITIES 已由 LOGIN_INFOR 处理流程填好
|
||||
if (ctx->SupportsUtf8()) return CP_UTF8;
|
||||
// 客户端类型兜底:LNX / MAC 默认 UTF-8(兼容老二进制无 UTF-8 cap 位的情形)
|
||||
CString clientType = ctx->GetAdditionalData(RES_CLIENT_TYPE);
|
||||
if (clientType == "LNX" || clientType == "MAC") return CP_UTF8;
|
||||
// 子连接情形:CAPABILITIES 为空 -> 通过 IP 找主连接
|
||||
if (g_2015RemoteDlg) {
|
||||
context* mainCtx = g_2015RemoteDlg->FindHostByIP(ctx->GetPeerName());
|
||||
if (mainCtx && mainCtx->SupportsUtf8()) return CP_UTF8;
|
||||
if (mainCtx) {
|
||||
if (mainCtx->SupportsUtf8()) return CP_UTF8;
|
||||
CString mainType = mainCtx->GetAdditionalData(RES_CLIENT_TYPE);
|
||||
if (mainType == "LNX" || mainType == "MAC") return CP_UTF8;
|
||||
}
|
||||
}
|
||||
return 936;
|
||||
}
|
||||
@@ -7550,6 +7560,28 @@ void CMy2015RemoteDlg::OnListClick(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
CString res[RES_MAX];
|
||||
CString startTime = ctx->GetClientData(ONLINELIST_STARTTIME);
|
||||
ctx->GetAdditionalData(res);
|
||||
// 客户端 RES_* 字符串编码取决于客户端能力位:UTF-8 客户端(Linux/macOS/新 Win)
|
||||
// 发的是 UTF-8 字节,老客户端是 CP_ACP。这里统一规整到 CP_ACP,让下游 FormatL
|
||||
// 与既有 ANSI 字符串拼接以及最终 CP_ACP→wide 的浮窗渲染都能正确识别。
|
||||
// 若服务端运行系统的 ANSI 代码页不能容纳客户端字符(如德语服务端遇到中文路径),
|
||||
// 不可表示的字符会变 '?' —— 与项目其它路径的既有限制一致,不在本次修复范围。
|
||||
UINT cp = GetClientEncoding(ctx);
|
||||
if (cp != CP_ACP) {
|
||||
for (int i = 0; i < RES_MAX; i++) {
|
||||
if (res[i].IsEmpty()) continue;
|
||||
int wlen = MultiByteToWideChar(cp, 0, res[i].GetString(), -1, NULL, 0);
|
||||
if (wlen <= 1) continue;
|
||||
std::wstring wbuf(wlen - 1, L'\0');
|
||||
MultiByteToWideChar(cp, 0, res[i].GetString(), -1, &wbuf[0], wlen);
|
||||
int alen = WideCharToMultiByte(CP_ACP, 0, wbuf.c_str(), -1, NULL, 0, NULL, NULL);
|
||||
if (alen <= 1) continue;
|
||||
CString out;
|
||||
WideCharToMultiByte(CP_ACP, 0, wbuf.c_str(), -1,
|
||||
out.GetBufferSetLength(alen - 1), alen, NULL, NULL);
|
||||
out.ReleaseBuffer(alen - 1);
|
||||
res[i] = out;
|
||||
}
|
||||
}
|
||||
FlagType type = ctx->GetFlagType();
|
||||
static std::map<FlagType, std::string> typMap = {
|
||||
{FLAG_WINOS, "WinOS"}, {FLAG_UNKNOWN, "Unknown"}, {FLAG_SHINE, "Shine"},
|
||||
|
||||
Reference in New Issue
Block a user