Fix: Expand env vars in V2 file receive path
V2 upload to a remote directory picked via the quick-icon shortcuts (Desktop / Downloads / Home) landed files in a literal "%USERPROFILE%" folder instead of the real profile. The shortcuts set m_Remote_Path to an unexpanded "%USERPROFILE%\..." template (FileManagerDlg.cpp OnRemoteDesktop/Downloads/Home), and the V2 receive path handed that filename straight to RecvFileChunkV2 (prebuilt FileUpload lib), which writes it verbatim. V1 upload already expanded env vars in COMMAND_FILE_SIZE (client/FileManager.cpp ExpandPath), so this is a V2-only regression. Expand the filename's environment variables in CKernelManager::OnReceive's COMMAND_SEND_FILE_V2 branch before RecvFileChunkV2, rebuilding the packet only when the expanded length differs; other packet types pass through unchanged. Co-Authored-By: deepseek-v4-pro
This commit is contained in:
1 parent
59fead7b5f
commit
c7f7b7b29b
1 file changed
+35
-1
@@ -1488,7 +1488,41 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
s_v2RecvInited = true;
|
||||
}
|
||||
// C2C/V2 文件接收(RecvFileChunkV2 内部会打印进度)
|
||||
int n = RecvFileChunkV2((char*)szBuffer, ulLength, m_conn,
|
||||
// 展开文件名中的环境变量(如 %USERPROFILE%),与 V1 的 COMMAND_FILE_SIZE 保持一致。
|
||||
// 快捷图标定位远程目录时,主控端下发的 targetDir 仍含未展开的 %USERPROFILE%
|
||||
// (server/2015Remote/FileManagerDlg.cpp OnRemoteDesktop/Downloads/Home),
|
||||
// 若不在接收端展开,RecvFileChunkV2 会按字面量建目录(如 CWD\%%USERPROFILE%%\...)。
|
||||
char* recvBuf = (char*)szBuffer;
|
||||
size_t recvLen = ulLength;
|
||||
std::vector<uint8_t> rebuilt;
|
||||
if (ulLength >= sizeof(FileChunkPacketV2) && szBuffer[0] == COMMAND_SEND_FILE_V2) {
|
||||
const FileChunkPacketV2* pkt = (const FileChunkPacketV2*)szBuffer;
|
||||
if (ulLength >= sizeof(FileChunkPacketV2) + pkt->nameLength + pkt->dataLength) {
|
||||
// 文件名未必以 '\0' 结尾,先构造出以 '\0' 结尾的副本
|
||||
std::string name((const char*)szBuffer + sizeof(FileChunkPacketV2), (size_t)pkt->nameLength);
|
||||
char expanded[MAX_PATH * 2] = { 0 };
|
||||
DWORD n = ExpandEnvironmentStringsA(name.c_str(), expanded, (DWORD)sizeof(expanded));
|
||||
if (n > 0 && n < (DWORD)sizeof(expanded)) {
|
||||
std::string newName(expanded, n - 1); // n 含末尾 '\0'
|
||||
if (newName.size() != pkt->nameLength) {
|
||||
// 展开后长度变化,重建包:[header][展开后的 name][data]
|
||||
size_t newLen = sizeof(FileChunkPacketV2) + newName.size() + pkt->dataLength;
|
||||
rebuilt.resize(newLen);
|
||||
memcpy(rebuilt.data(), szBuffer, sizeof(FileChunkPacketV2));
|
||||
FileChunkPacketV2* newPkt = (FileChunkPacketV2*)rebuilt.data();
|
||||
newPkt->nameLength = newName.size();
|
||||
memcpy(rebuilt.data() + sizeof(FileChunkPacketV2), newName.data(), newName.size());
|
||||
memcpy(rebuilt.data() + sizeof(FileChunkPacketV2) + newName.size(),
|
||||
(const char*)szBuffer + sizeof(FileChunkPacketV2) + pkt->nameLength,
|
||||
(size_t)pkt->dataLength);
|
||||
recvBuf = (char*)rebuilt.data();
|
||||
recvLen = newLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int n = RecvFileChunkV2(recvBuf, recvLen, m_conn,
|
||||
nullptr, m_hash, m_hmac, m_MyClientID);
|
||||
if (n) {
|
||||
Mprintf("[C2C] RecvFileChunkV2 failed: %d\n", n);
|
||||
|
||||
Reference in new issue
Block a user