Fix: Decode remote file-list names/paths from GBK/UTF-8 on non-Chinese systems
The Windows ghost client lists directories with FindFirstFileA, so remote file names arrive as GBK/936 bytes. Both file-manager dialogs wrote them back through ANSI InsertItem/SetItemText, which re-converts through CP_ACP and garbles Chinese names when the operator machine runs a non-Chinese ACP. Decode the name/path from the client encoding (GBK for Windows, UTF-8 for LNX/MAC, chosen by RES_CLIENT_TYPE) and write the text via LVM_SETITEMTEXTW, keeping the icon through an empty InsertItem - the same pattern used for the process list, window list and client-list path. Co-Authored-By: deepseek-v4-pro
This commit is contained in:
1 parent
f3a8406050
commit
1a9312d2d1
2 files changed
+71
-9
No files matched your search
@@ -223,6 +223,27 @@ int GetIconIndex(LPCTSTR lpFileName, DWORD dwFileAttributes)
|
||||
return index;
|
||||
}
|
||||
|
||||
// 远程文件名/路径编码按 clientType 判定:Windows 走 A 接口(FindFirstFileA)=GBK/936,
|
||||
// LNX/MAC 文件系统天然 UTF-8(同 McpServer.cpp::BuildListFiles)。这里用 LVM_SETITEMTEXTW
|
||||
// 直接写宽字符串,绕开 ANSI→CP_ACP 回转,即使服务端运行在非中文 ACP 上中文名也能正常显示。
|
||||
static void SetFileTextItem(CListCtrl& list, int iItem, int iSubItem, const char* sz, UINT cp)
|
||||
{
|
||||
std::wstring w;
|
||||
if (sz && sz[0]) {
|
||||
int wlen = MultiByteToWideChar(cp, 0, sz, -1, NULL, 0);
|
||||
if (wlen > 1) {
|
||||
w.resize(wlen - 1);
|
||||
MultiByteToWideChar(cp, 0, sz, -1, &w[0], wlen);
|
||||
}
|
||||
}
|
||||
LVITEMW lv = {};
|
||||
lv.mask = LVIF_TEXT;
|
||||
lv.iItem = iItem;
|
||||
lv.iSubItem = iSubItem;
|
||||
lv.pszText = w.empty() ? const_cast<LPWSTR>(L"") : &w[0];
|
||||
::SendMessageW(list.GetSafeHwnd(), LVM_SETITEMTEXTW, (WPARAM)iItem, (LPARAM)&lv);
|
||||
}
|
||||
|
||||
BOOL CFileManagerDlg::OnInitDialog()
|
||||
{
|
||||
__super::OnInitDialog();
|
||||
@@ -1104,6 +1125,9 @@ void CFileManagerDlg::OnDblclkListRemote(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
|
||||
void CFileManagerDlg::FixedRemoteFileList(BYTE *pbBuffer, DWORD dwBufferLen)
|
||||
{
|
||||
CString clientType = m_ContextObject->GetAdditionalData(RES_CLIENT_TYPE);
|
||||
UINT cp = (clientType == _T("LNX") || clientType == _T("MAC")) ? CP_UTF8 : 936;
|
||||
|
||||
// 重新设置ImageList
|
||||
SHFILEINFO sfi = {};
|
||||
HIMAGELIST hImageListLarge = (HIMAGELIST)SHGetFileInfo(NULL, 0, &sfi,sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
|
||||
@@ -1151,7 +1175,8 @@ void CFileManagerDlg::FixedRemoteFileList(BYTE *pbBuffer, DWORD dwBufferLen)
|
||||
pszFileName = ++pList;
|
||||
|
||||
if (bIsInsert) {
|
||||
nItem = m_list_remote.InsertItem(nItemIndex++, pszFileName, GetIconIndex(pszFileName, nType));
|
||||
nItem = m_list_remote.InsertItem(nItemIndex++, "", GetIconIndex(pszFileName, nType));
|
||||
SetFileTextItem(m_list_remote, nItem, 0, pszFileName, cp);
|
||||
m_list_remote.SetItemData(nItem, nType == FILE_ATTRIBUTE_DIRECTORY);
|
||||
SHFILEINFO sfi = {};
|
||||
SHGetFileInfo(pszFileName, FILE_ATTRIBUTE_NORMAL | nType, &sfi,sizeof(SHFILEINFO), SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES);
|
||||
@@ -1184,6 +1209,9 @@ void CFileManagerDlg::FixedRemoteFileList(BYTE *pbBuffer, DWORD dwBufferLen)
|
||||
|
||||
void CFileManagerDlg::FixedRemoteSearchFileList(BYTE *pbBuffer, DWORD dwBufferLen)
|
||||
{
|
||||
CString clientType = m_ContextObject->GetAdditionalData(RES_CLIENT_TYPE);
|
||||
UINT cp = (clientType == _T("LNX") || clientType == _T("MAC")) ? CP_UTF8 : 936;
|
||||
|
||||
// 第一批结果到达时,初始化搜索列表
|
||||
if (!m_bSearching) {
|
||||
m_bSearching = true;
|
||||
@@ -1241,7 +1269,8 @@ void CFileManagerDlg::FixedRemoteSearchFileList(BYTE *pbBuffer, DWORD dwBufferLe
|
||||
}
|
||||
}
|
||||
|
||||
int nItem = m_list_remote.InsertItem(m_nSearchResultCount, csFileName, nIcon);
|
||||
int nItem = m_list_remote.InsertItem(m_nSearchResultCount, "", nIcon);
|
||||
SetFileTextItem(m_list_remote, nItem, 0, csFileName, cp);
|
||||
m_list_remote.SetItemData(nItem, nType == FILE_ATTRIBUTE_DIRECTORY);
|
||||
|
||||
pList += lstrlen(pszFullPath) + 1;
|
||||
@@ -1261,7 +1290,7 @@ void CFileManagerDlg::FixedRemoteSearchFileList(BYTE *pbBuffer, DWORD dwBufferLe
|
||||
m_list_remote.SetItemText(nItem, 2, time.FormatL("%Y-%m-%d %H:%M"));
|
||||
|
||||
// 路径
|
||||
m_list_remote.SetItemText(nItem, 3, csDir);
|
||||
SetFileTextItem(m_list_remote, nItem, 3, csDir, cp);
|
||||
|
||||
pList += 16;
|
||||
m_nSearchResultCount++;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "InputDlg.h"
|
||||
#include <windows.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
@@ -818,8 +819,32 @@ void CFileManagerDlg::OnclickListSearch(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
|
||||
int GetIconIndex(LPCTSTR lpFileName, DWORD dwFileAttributes);
|
||||
|
||||
// 远程文件名/路径编码按 clientType 判定:Windows 走 A 接口(FindFirstFileA)=GBK/936,
|
||||
// LNX/MAC 文件系统天然 UTF-8(同 McpServer.cpp::BuildListFiles)。这里用 LVM_SETITEMTEXTW
|
||||
// 直接写宽字符串,绕开 ANSI→CP_ACP 回转,即使服务端运行在非中文 ACP 上中文名也能正常显示。
|
||||
static void SetFileTextItem(CListCtrl& list, int iItem, int iSubItem, const char* sz, UINT cp)
|
||||
{
|
||||
std::wstring w;
|
||||
if (sz && sz[0]) {
|
||||
int wlen = MultiByteToWideChar(cp, 0, sz, -1, NULL, 0);
|
||||
if (wlen > 1) {
|
||||
w.resize(wlen - 1);
|
||||
MultiByteToWideChar(cp, 0, sz, -1, &w[0], wlen);
|
||||
}
|
||||
}
|
||||
LVITEMW lv = {};
|
||||
lv.mask = LVIF_TEXT;
|
||||
lv.iItem = iItem;
|
||||
lv.iSubItem = iSubItem;
|
||||
lv.pszText = w.empty() ? const_cast<LPWSTR>(L"") : &w[0];
|
||||
::SendMessageW(list.GetSafeHwnd(), LVM_SETITEMTEXTW, (WPARAM)iItem, (LPARAM)&lv);
|
||||
}
|
||||
|
||||
void CFileManagerDlg::FixedRemoteFileList(BYTE* pbBuffer, DWORD dwBufferLen)
|
||||
{
|
||||
CString clientType = m_ContextObject->GetAdditionalData(RES_CLIENT_TYPE);
|
||||
UINT cp = (clientType == _T("LNX") || clientType == _T("MAC")) ? CP_UTF8 : 936;
|
||||
|
||||
// 重建标题
|
||||
m_list_remote.DeleteAllItems();
|
||||
int nItemIndex = 0;
|
||||
@@ -855,7 +880,8 @@ void CFileManagerDlg::FixedRemoteFileList(BYTE* pbBuffer, DWORD dwBufferLen)
|
||||
|
||||
if (bIsInsert) {
|
||||
int iicon = GetIconIndex(pszFileName, nType);
|
||||
nItem = m_list_remote.InsertItem(nItemIndex++, pszFileName, iicon);
|
||||
nItem = m_list_remote.InsertItem(nItemIndex++, _T(""), iicon);
|
||||
SetFileTextItem(m_list_remote, nItem, 0, pszFileName, cp);
|
||||
m_list_remote.SetItemData(nItem, nType == FILE_ATTRIBUTE_DIRECTORY);
|
||||
SHFILEINFO sfi = {};
|
||||
SHGetFileInfo(pszFileName, FILE_ATTRIBUTE_NORMAL | nType, &sfi, sizeof(SHFILEINFO), SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES);
|
||||
@@ -2421,6 +2447,9 @@ void CFileManagerDlg::SearchEnd()
|
||||
|
||||
void CFileManagerDlg::FixedRemoteSearchFileList(BYTE* pbBuffer, DWORD dwBufferLen)
|
||||
{
|
||||
CString clientType = m_ContextObject->GetAdditionalData(RES_CLIENT_TYPE);
|
||||
UINT cp = (clientType == _T("LNX") || clientType == _T("MAC")) ? CP_UTF8 : 936;
|
||||
|
||||
byte* pList = pbBuffer + 1;
|
||||
int nItemIndex = 0;
|
||||
for (byte* pBase = pList; (int)(pList - pBase) < (int)(dwBufferLen - 1);) {
|
||||
@@ -2439,7 +2468,8 @@ void CFileManagerDlg::FixedRemoteSearchFileList(BYTE* pbBuffer, DWORD dwBufferLe
|
||||
int nPos = csFilePath.ReverseFind(_T('\\'));
|
||||
csFileFullName = csFilePath.Right(csFilePath.GetLength() - nPos - 1);// 获取文件全名,包括文件名和扩展名
|
||||
|
||||
nItem = m_list_remote_search.InsertItem(nItemIndex++, csFileFullName, GetIconIndex(pszFileName, nType));
|
||||
nItem = m_list_remote_search.InsertItem(nItemIndex++, _T(""), GetIconIndex(pszFileName, nType));
|
||||
SetFileTextItem(m_list_remote_search, nItem, 0, csFileFullName, cp);
|
||||
m_list_remote_search.SetItemData(nItem, nType == FILE_ATTRIBUTE_DIRECTORY);
|
||||
|
||||
pList += (lstrlen(pszFileName) + 1) * sizeof(TCHAR);
|
||||
@@ -2455,7 +2485,7 @@ void CFileManagerDlg::FixedRemoteSearchFileList(BYTE* pbBuffer, DWORD dwBufferLe
|
||||
m_list_remote_search.SetItemText(nItem, 2, time.FormatL(_T("%Y-%m-%d %H:%M")));
|
||||
|
||||
PathRemoveFileSpec(pszFileName); //去除文件名获取文件路径
|
||||
m_list_remote_search.SetItemText(nItem, 3, pszFileName);
|
||||
SetFileTextItem(m_list_remote_search, nItem, 3, pszFileName, cp);
|
||||
|
||||
pList += 16;
|
||||
}
|
||||
@@ -2491,6 +2521,9 @@ void CFileManagerDlg::ShowSearchPlugList()
|
||||
char* Filename;
|
||||
char* Pathname;
|
||||
|
||||
CString clientType = m_ContextObject->GetAdditionalData(RES_CLIENT_TYPE);
|
||||
UINT cp = (clientType == _T("LNX") || clientType == _T("MAC")) ? CP_UTF8 : 936;
|
||||
|
||||
DWORD dwOffset = 0;
|
||||
m_list_remote_search.DeleteAllItems();
|
||||
int i = 0;
|
||||
@@ -2498,13 +2531,13 @@ void CFileManagerDlg::ShowSearchPlugList()
|
||||
Filename = lpBuffer + dwOffset;
|
||||
Pathname = Filename + strlen(Filename) + 1;
|
||||
CString CS_tem;
|
||||
CS_tem = Filename;
|
||||
m_list_remote_search.InsertItem(i, CS_tem, 0);
|
||||
m_list_remote_search.InsertItem(i, _T(""), 0);
|
||||
SetFileTextItem(m_list_remote_search, i, 0, Filename, cp);
|
||||
CS_tem = Pathname;
|
||||
int index = CS_tem.ReverseFind('\\');
|
||||
if (index >= 0)
|
||||
CS_tem = CS_tem.Left(index);
|
||||
m_list_remote_search.SetItemText(i,3, CS_tem);
|
||||
SetFileTextItem(m_list_remote_search, i, 3, CS_tem, cp);
|
||||
dwOffset += strlen(Filename) + strlen(Pathname) + 2;
|
||||
}
|
||||
m_list_remote_search.EnableWindow(TRUE);
|
||||
|
||||
Reference in new issue
Block a user