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;
|
s_v2RecvInited = true;
|
||||||
}
|
}
|
||||||
// C2C/V2 文件接收(RecvFileChunkV2 内部会打印进度)
|
// 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);
|
nullptr, m_hash, m_hmac, m_MyClientID);
|
||||||
if (n) {
|
if (n) {
|
||||||
Mprintf("[C2C] RecvFileChunkV2 failed: %d\n", n);
|
Mprintf("[C2C] RecvFileChunkV2 failed: %d\n", n);
|
||||||
|
|||||||
Reference in new issue
Block a user