1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "client_trans_proxy_file_helper.h"
17 
18 #include <limits.h>
19 #include <securec.h>
20 #include <stdbool.h>
21 
22 #include "client_trans_proxy_file_manager.h"
23 #include "client_trans_proxy_manager.h"
24 #include "client_trans_session_manager.h"
25 #include "client_trans_socket_manager.h"
26 #include "softbus_adapter_errcode.h"
27 #include "softbus_adapter_file.h"
28 #include "softbus_adapter_mem.h"
29 #include "softbus_adapter_socket.h"
30 #include "softbus_app_info.h"
31 #include "softbus_def.h"
32 #include "softbus_errcode.h"
33 #include "softbus_utils.h"
34 #include "trans_log.h"
35 
ProxyChannelSendFileStream(int32_t channelId,const char * data,uint32_t len,int32_t type)36 int32_t ProxyChannelSendFileStream(int32_t channelId, const char *data, uint32_t len, int32_t type)
37 {
38     if (data == NULL) {
39         TRANS_LOGI(TRANS_FILE, "data is null");
40         return SOFTBUS_INVALID_PARAM;
41     }
42     ProxyChannelInfoDetail info;
43     (void)memset_s(&info, sizeof(ProxyChannelInfoDetail), 0, sizeof(ProxyChannelInfoDetail));
44     int32_t ret = ClientTransProxyGetInfoByChannelId(channelId, &info);
45     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret,
46         TRANS_FILE, "client trans proxy get info by ChannelId fail");
47     return TransProxyPackAndSendData(channelId, data, len, &info, (SessionPktType)type);
48 }
49 
SendFileTransResult(int32_t channelId,uint32_t seq,int32_t result,uint32_t side)50 int32_t SendFileTransResult(int32_t channelId, uint32_t seq, int32_t result, uint32_t side)
51 {
52     TRANS_LOGI(TRANS_FILE, "send file result seq=%{public}u, side=%{public}u, result=%{public}d", seq, side, result);
53     uint32_t len = FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + sizeof(uint32_t) + sizeof(int32_t);
54     char *data = (char *)SoftBusCalloc(len);
55     if (data == NULL) {
56         TRANS_LOGE(TRANS_FILE, "malloc failedLen=%{public}d.", len);
57         return SOFTBUS_MALLOC_ERR;
58     }
59     *(uint32_t *)data = SoftBusHtoLl(FILE_MAGIC_NUMBER);
60     *(uint64_t *)(data + FRAME_MAGIC_OFFSET) =
61         SoftBusHtoLll((FRAME_DATA_SEQ_OFFSET + sizeof(uint32_t) + sizeof(int32_t)));
62     *(uint32_t *)(data + FRAME_HEAD_LEN) = SoftBusHtoLl(seq);
63     *(uint32_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET) = SoftBusHtoLl(side);
64     *(int32_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + sizeof(uint32_t)) = SoftBusHtoLl((uint32_t)result);
65 
66     int32_t ret = ProxyChannelSendFileStream(channelId, data, len, TRANS_SESSION_FILE_RESULT_FRAME);
67     if (ret != SOFTBUS_OK) {
68         TRANS_LOGE(TRANS_FILE, "conn send file fail ret=%{public}d", ret);
69     }
70     SoftBusFree(data);
71     return ret;
72 }
73 
UnpackFileTransResultFrame(const uint8_t * data,uint32_t len,uint32_t * seq,int32_t * result,uint32_t * side)74 int32_t UnpackFileTransResultFrame(
75     const uint8_t *data, uint32_t len, uint32_t *seq, int32_t *result, uint32_t *side)
76 {
77     if (seq == NULL || result == NULL || side == NULL) {
78         TRANS_LOGE(TRANS_FILE, "param invalid");
79         return SOFTBUS_INVALID_PARAM;
80     }
81     if (data == NULL || len < FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + FRAME_DATA_SEQ_OFFSET) {
82         TRANS_LOGE(TRANS_FILE, "recv ack fail. responseLen=%{public}u", len);
83         return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
84     }
85     uint32_t magic = SoftBusLtoHl(*(uint32_t *)data);
86     uint64_t dataLen = SoftBusLtoHll(*(uint64_t *)(data + FRAME_MAGIC_OFFSET));
87     if (magic != FILE_MAGIC_NUMBER || dataLen != (FRAME_DATA_SEQ_OFFSET + sizeof(uint32_t) + sizeof(int32_t))) {
88         TRANS_LOGE(
89             TRANS_FILE, "recv ack response head fail. magic=%{public}u, dataLen=%{public}" PRIu64, magic, dataLen);
90         return SOFTBUS_INVALID_DATA_HEAD;
91     }
92     (*seq) = SoftBusLtoHl((*(uint32_t *)(data + FRAME_HEAD_LEN)));
93     (*side) = SoftBusLtoHl((*(uint32_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET)));
94     (*result) = (int32_t)SoftBusLtoHl(
95         (uint32_t)(*(int32_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + sizeof(uint32_t))));
96     TRANS_LOGI(TRANS_FILE, "seq=%{public}u, side=%{public}u, result=%{public}d", *seq, *side, *result);
97     return SOFTBUS_OK;
98 }
99 
SendFileAckReqAndResData(int32_t channelId,uint32_t startSeq,uint32_t value,int32_t type)100 int32_t SendFileAckReqAndResData(int32_t channelId, uint32_t startSeq, uint32_t value, int32_t type)
101 {
102     uint32_t len = FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + FRAME_DATA_SEQ_OFFSET;
103     char *data = (char *)SoftBusCalloc(len);
104     if (data == NULL) {
105         TRANS_LOGE(TRANS_FILE, "calloc fail! len=%{public}d.", len);
106         return SOFTBUS_MALLOC_ERR;
107     }
108     *(uint32_t *)data = SoftBusHtoLl(FILE_MAGIC_NUMBER);
109     *(int64_t *)(data + FRAME_MAGIC_OFFSET) = SoftBusHtoLll((uint64_t)(FRAME_DATA_SEQ_OFFSET + FRAME_DATA_SEQ_OFFSET));
110     *(uint32_t *)(data + FRAME_HEAD_LEN) = SoftBusHtoLl(startSeq);
111     *(uint32_t *)(data + FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET) = SoftBusHtoLl(value);
112     int32_t ret = ProxyChannelSendFileStream(channelId, data, len, type);
113     if (ret != SOFTBUS_OK) {
114         TRANS_LOGE(TRANS_FILE, "conn send ack buf fail ret=%{public}d.", ret);
115     }
116     SoftBusFree(data);
117     return ret;
118 }
119 
UnpackAckReqAndResData(FileFrame * frame,uint32_t * startSeq,uint32_t * value)120 int32_t UnpackAckReqAndResData(FileFrame *frame, uint32_t *startSeq, uint32_t *value)
121 {
122     if (frame == NULL || startSeq == NULL || value == NULL || frame->data == NULL) {
123         return SOFTBUS_INVALID_PARAM;
124     }
125     if (frame->frameLength < FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + FRAME_DATA_SEQ_OFFSET) {
126         TRANS_LOGE(TRANS_FILE, "unpack ack data fail. frameLen=%{public}d", frame->frameLength);
127         return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
128     }
129     frame->magic = SoftBusLtoHl((*(uint32_t *)(frame->data)));
130     uint64_t dataLen = SoftBusLtoHll((*(uint64_t *)(frame->data + FRAME_MAGIC_OFFSET)));
131     if (frame->magic != FILE_MAGIC_NUMBER || dataLen < FRAME_DATA_SEQ_OFFSET + FRAME_DATA_SEQ_OFFSET) {
132         TRANS_LOGE(
133             TRANS_FILE, "unpack ack head fail. magic=%{public}u, dataLen=%{public}" PRIu64, frame->magic, dataLen);
134         return SOFTBUS_INVALID_DATA_HEAD;
135     }
136     frame->fileData = frame->data + FRAME_HEAD_LEN;
137     (*startSeq) = SoftBusLtoHl((*(uint32_t *)(frame->fileData)));
138     (*value) = SoftBusLtoHl((*(uint32_t *)(frame->fileData + FRAME_DATA_SEQ_OFFSET)));
139     return SOFTBUS_OK;
140 }
141 
PackReadFileData(FileFrame * fileFrame,uint64_t readLength,uint64_t fileOffset,SendListenerInfo * info)142 int64_t PackReadFileData(FileFrame *fileFrame, uint64_t readLength, uint64_t fileOffset, SendListenerInfo *info)
143 {
144     if (fileFrame == NULL || info == NULL) {
145         TRANS_LOGE(TRANS_FILE, "param invalid");
146         return SOFTBUS_INVALID_PARAM;
147     }
148     int64_t len = SoftBusPreadFile(info->fd, fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, readLength, fileOffset);
149     if (len <= 0) {
150         TRANS_LOGE(TRANS_FILE, "pread src file failed. ret=%{public}" PRId64, len);
151         return len;
152     }
153     if (info->crc == APP_INFO_FILE_FEATURES_SUPPORT && info->osType == OH_TYPE) {
154         uint64_t dataLen = (uint64_t)len + FRAME_DATA_SEQ_OFFSET;
155         fileFrame->frameLength = FRAME_HEAD_LEN + dataLen + FRAME_CRC_LEN;
156         if (fileFrame->frameLength > info->packetSize) {
157             TRANS_LOGE(TRANS_FILE, "frameLength invalid. frameLength=%{public}u", fileFrame->frameLength);
158             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
159         }
160         uint16_t crc = RTU_CRC(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, len);
161         (*(uint32_t *)(fileFrame->data)) = SoftBusHtoLl(fileFrame->magic);
162         (*(uint64_t *)(fileFrame->data + FRAME_MAGIC_OFFSET)) = SoftBusHtoLll(dataLen);
163         info->seq++;
164         (*(uint32_t *)(fileFrame->fileData)) = SoftBusHtoLl(info->seq);
165         (*(uint16_t *)(fileFrame->fileData + dataLen)) = SoftBusHtoLs(crc);
166         info->checkSumCRC += crc;
167     } else {
168         uint64_t tmp = FRAME_DATA_SEQ_OFFSET + (uint64_t)len;
169         if (tmp > UINT32_MAX) {
170             TRANS_LOGE(TRANS_FILE, "Overflow error");
171             return SOFTBUS_INVALID_NUM;
172         }
173         fileFrame->frameLength = (uint32_t)tmp;
174         if (fileFrame->frameLength > info->packetSize) {
175             TRANS_LOGE(TRANS_FILE, "frameLength invalid. frameLength=%{public}u", fileFrame->frameLength);
176             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
177         }
178         (*(int32_t *)(fileFrame->fileData)) = SoftBusHtoLl((uint32_t)info->channelId);
179     }
180     return len;
181 }
182 
PackReadFileRetransData(FileFrame * fileFrame,uint32_t seq,uint64_t readLength,uint64_t fileOffset,const SendListenerInfo * info)183 static int64_t PackReadFileRetransData(
184     FileFrame *fileFrame, uint32_t seq, uint64_t readLength, uint64_t fileOffset, const SendListenerInfo *info)
185 {
186     if (fileFrame == NULL || info == NULL) {
187         TRANS_LOGE(TRANS_FILE, "param invalid");
188         return SOFTBUS_INVALID_PARAM;
189     }
190     int64_t len = SoftBusPreadFile(info->fd, fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, readLength, fileOffset);
191     if (len <= 0) {
192         TRANS_LOGE(TRANS_FILE, "pread src file failed. ret=%{public}" PRId64, len);
193         return len;
194     }
195     uint64_t dataLen = (uint64_t)len + FRAME_DATA_SEQ_OFFSET;
196     fileFrame->frameLength = FRAME_HEAD_LEN + dataLen + FRAME_CRC_LEN;
197     if (fileFrame->frameLength > info->packetSize) {
198         TRANS_LOGE(TRANS_FILE, "frameLength invalid. frameLength=%{public}u", fileFrame->frameLength);
199         return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
200     }
201     uint16_t crc = RTU_CRC(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, len);
202     (*(uint32_t *)(fileFrame->data)) = SoftBusHtoLl(fileFrame->magic);
203     (*(uint64_t *)(fileFrame->data + FRAME_MAGIC_OFFSET)) = SoftBusHtoLll(dataLen);
204     (*(uint32_t *)(fileFrame->fileData)) = SoftBusHtoLl(seq);
205     (*(uint16_t *)(fileFrame->fileData + dataLen)) = SoftBusHtoLs(crc);
206 
207     int32_t ret = ProxyChannelSendFileStream(info->channelId, (char *)fileFrame->data, fileFrame->frameLength,
208         FrameIndexToType((uint64_t)seq, info->frameNum));
209     if (ret != SOFTBUS_OK) {
210         TRANS_LOGE(TRANS_FILE, "conn send buf fail ret=%{public}d", ret);
211         return ret;
212     }
213     return len;
214 }
215 
UnpackFileDataFrame(FileRecipientInfo * info,FileFrame * fileFrame,uint32_t * fileDataLen)216 int32_t UnpackFileDataFrame(FileRecipientInfo *info, FileFrame *fileFrame, uint32_t *fileDataLen)
217 {
218     if (info == NULL || fileFrame == NULL || fileDataLen == NULL) {
219         TRANS_LOGE(TRANS_FILE, "param invalid");
220         return SOFTBUS_INVALID_PARAM;
221     }
222     if (info->crc == APP_INFO_FILE_FEATURES_SUPPORT && info->osType == OH_TYPE) {
223         if (fileFrame->frameLength <= FRAME_HEAD_LEN + FRAME_DATA_SEQ_OFFSET + FRAME_CRC_LEN) {
224             TRANS_LOGE(TRANS_FILE, "frameLength invalid. frameLength=%{public}u", fileFrame->frameLength);
225             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
226         }
227         fileFrame->magic = SoftBusLtoHl((*(uint32_t *)(fileFrame->data)));
228         uint64_t dataLen = SoftBusLtoHll((*(uint64_t *)(fileFrame->data + FRAME_MAGIC_OFFSET)));
229         if (fileFrame->magic != FILE_MAGIC_NUMBER ||
230             dataLen != fileFrame->frameLength - (FRAME_HEAD_LEN + FRAME_CRC_LEN)) {
231             TRANS_LOGE(TRANS_FILE, "unpack data frame failed. magic=%{public}u, dataLen=%{public}" PRIu64,
232                 fileFrame->magic, dataLen);
233             return SOFTBUS_INVALID_DATA_HEAD;
234         }
235         fileFrame->fileData = fileFrame->data + FRAME_HEAD_LEN;
236         fileFrame->seq = SoftBusLtoHl((*(uint32_t *)(fileFrame->fileData)));
237         uint16_t recvCRC = SoftBusLtoHs((*(uint16_t *)(fileFrame->fileData + dataLen)));
238         uint16_t crc = RTU_CRC(fileFrame->fileData + FRAME_DATA_SEQ_OFFSET, dataLen - FRAME_DATA_SEQ_OFFSET);
239         if (crc != recvCRC) {
240             TRANS_LOGE(
241                 TRANS_FILE, "crc check fail recvCrc=%{public}u, crc=%{public}u", (uint32_t)recvCRC, (uint32_t)crc);
242             return SOFTBUS_FILE_ERR;
243         }
244         *fileDataLen = dataLen;
245         fileFrame->crc = crc;
246     } else {
247         fileFrame->fileData = fileFrame->data;
248         if (fileFrame->frameLength <= FRAME_DATA_SEQ_OFFSET) {
249             TRANS_LOGE(TRANS_FILE, "frameLength invalid. frameLength=%{public}u", fileFrame->frameLength);
250             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
251         }
252         fileFrame->seq = SoftBusLtoHl((*(uint32_t *)(fileFrame->fileData)));
253         *fileDataLen = fileFrame->frameLength;
254     }
255     return SOFTBUS_OK;
256 }
257 
RetransFileFrameBySeq(const SendListenerInfo * info,int32_t seq)258 static int32_t RetransFileFrameBySeq(const SendListenerInfo *info, int32_t seq)
259 {
260     if ((info != NULL) && (info->crc != APP_INFO_FILE_FEATURES_SUPPORT)) {
261         return SOFTBUS_OK;
262     }
263     if ((info == NULL) || (seq <= 0)) {
264         TRANS_LOGE(TRANS_FILE, "param invalid");
265         return SOFTBUS_INVALID_PARAM;
266     }
267     FileFrame fileFrame = { 0 };
268     fileFrame.data = (uint8_t *)SoftBusCalloc(info->packetSize);
269     if (fileFrame.data == NULL) {
270         TRANS_LOGE(TRANS_FILE, "data calloc fail");
271         return SOFTBUS_MALLOC_ERR;
272     }
273     fileFrame.magic = FILE_MAGIC_NUMBER;
274     fileFrame.fileData = fileFrame.data + FRAME_HEAD_LEN;
275     uint64_t frameDataSize = info->packetSize - FRAME_HEAD_LEN - FRAME_DATA_SEQ_OFFSET - FRAME_CRC_LEN;
276     uint64_t fileOffset = frameDataSize * ((uint32_t)seq - 1);
277     if (fileOffset >= info->fileSize) {
278         TRANS_LOGE(TRANS_FILE, "retrans file frame failed, seq=%{public}d", seq);
279         SoftBusFree(fileFrame.data);
280         return SOFTBUS_INVALID_PARAM;
281     }
282     uint64_t remainedSize = info->fileSize - fileOffset;
283     uint64_t readLength = (remainedSize < frameDataSize) ? remainedSize : frameDataSize;
284     int64_t len = PackReadFileRetransData(&fileFrame, seq, readLength, fileOffset, info);
285     if (len <= 0) {
286         TRANS_LOGE(TRANS_FILE, "retrans file frame failed");
287         SoftBusFree(fileFrame.data);
288         return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
289     }
290     SoftBusFree(fileFrame.data);
291     return SOFTBUS_OK;
292 }
293 
AckResponseDataHandle(const SendListenerInfo * info,const char * data,uint32_t len)294 int32_t AckResponseDataHandle(const SendListenerInfo *info, const char *data, uint32_t len)
295 {
296     if (info == NULL || data == NULL || len != sizeof(AckResponseData)) {
297         TRANS_LOGE(TRANS_FILE, "data or len invalid");
298         return SOFTBUS_OK;
299     }
300     AckResponseData *resData = (AckResponseData *)data;
301     uint32_t startSeq = resData->startSeq;
302     uint32_t seqResult = resData->seqResult;
303     if (seqResult != FILE_SEND_ACK_RESULT_SUCCESS) {
304         for (int32_t i = 0; i < FILE_SEND_ACK_INTERVAL; i++) {
305             if (((seqResult >> i) & 0x01) == 0x01) {
306                 continue;
307             }
308             uint32_t failSeq = startSeq + (uint32_t)i;
309             int32_t ret = RetransFileFrameBySeq(info, (int32_t)failSeq);
310             TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_FILE, "retrans file fail!");
311         }
312     }
313     return SOFTBUS_OK;
314 }
315 
GetFullRecvPath(const char * filePath,const char * recvRootDir)316 char *GetFullRecvPath(const char *filePath, const char *recvRootDir)
317 {
318     if ((filePath == NULL) || (recvRootDir == NULL)) {
319         TRANS_LOGE(TRANS_FILE, "filePath or rootDir is null");
320         return NULL;
321     }
322     int32_t rootDirLength = (int32_t)strlen(recvRootDir);
323     int32_t filePathLength = (int32_t)strlen(filePath);
324     bool isNeedAddSep = true;
325     if (((filePathLength > 0) && (filePath[0] == PATH_SEPARATOR)) ||
326         ((rootDirLength > 0) && (recvRootDir[rootDirLength - 1] == PATH_SEPARATOR))) {
327         isNeedAddSep = false;
328     }
329     int32_t destFullPathLength =
330         (int32_t)((isNeedAddSep) ? (rootDirLength + sizeof('/') + filePathLength) : (rootDirLength + filePathLength));
331     char *recvFullPath = (char *)SoftBusCalloc(destFullPathLength + 1);
332     if (recvFullPath == NULL) {
333         TRANS_LOGE(TRANS_FILE, "recvFullPath is null");
334         return NULL;
335     }
336     int32_t ret;
337     if (isNeedAddSep) {
338         ret = sprintf_s(recvFullPath, destFullPathLength + 1, "%s/%s", recvRootDir, filePath);
339     } else {
340         ret = sprintf_s(recvFullPath, destFullPathLength + 1, "%s%s", recvRootDir, filePath);
341     }
342     if (ret < 0) {
343         TRANS_LOGE(TRANS_FILE, "create fullPath fail");
344         SoftBusFree(recvFullPath);
345         return NULL;
346     }
347     return recvFullPath;
348 }
349 
GetDirPath(const char * fullPath,char * dirPath,int32_t dirPathLen)350 static int32_t GetDirPath(const char *fullPath, char *dirPath, int32_t dirPathLen)
351 {
352     if ((fullPath == NULL) || (strlen(fullPath) < 1) || (fullPath[strlen(fullPath) - 1] == PATH_SEPARATOR)) {
353         TRANS_LOGE(TRANS_FILE, "invalid input param");
354         return SOFTBUS_INVALID_PARAM;
355     }
356     int32_t i = 0;
357     int32_t dirFullLen = (int32_t)strlen(fullPath);
358     for (i = dirFullLen - 1; i >= 0; i--) {
359         if (fullPath[i] == PATH_SEPARATOR) {
360             i++;
361             break;
362         }
363         if (i == 0) {
364             break;
365         }
366     }
367     int32_t dirLen = i;
368     if (dirLen >= dirPathLen) {
369         TRANS_LOGE(TRANS_FILE, "dirLen >= dirPathLen. dirLen=%{public}d, dirPathLen=%{public}d", dirLen, dirPathLen);
370         return SOFTBUS_INVALID_PARAM;
371     }
372     if (strncpy_s(dirPath, dirPathLen, fullPath, dirLen) != EOK) {
373         TRANS_LOGE(TRANS_FILE, "strcpy_s dir path error, dirLen=%{public}d", dirLen);
374         return SOFTBUS_MEM_ERR;
375     }
376     return SOFTBUS_OK;
377 }
378 
GetAbsFullPath(const char * fullPath,char * recvAbsPath,int32_t pathSize)379 static int32_t GetAbsFullPath(const char *fullPath, char *recvAbsPath, int32_t pathSize)
380 {
381     char *dirPath = (char *)SoftBusCalloc(MAX_FILE_PATH_NAME_LEN);
382     if (dirPath == NULL) {
383         return SOFTBUS_MALLOC_ERR;
384     }
385     if (GetDirPath(fullPath, dirPath, MAX_FILE_PATH_NAME_LEN) != SOFTBUS_OK) {
386         TRANS_LOGE(TRANS_FILE, "get dir path failed");
387         SoftBusFree(dirPath);
388         return SOFTBUS_INVALID_PARAM;
389     }
390     char *absFullDir = (char *)SoftBusCalloc(PATH_MAX + 1);
391     if (absFullDir == NULL) {
392         TRANS_LOGE(TRANS_FILE, "calloc absFullDir failed");
393         SoftBusFree(dirPath);
394         return SOFTBUS_MALLOC_ERR;
395     }
396     int32_t fileNameLength = -1;
397     int32_t dirPathLength = -1;
398     const char *fileName = TransGetFileName(fullPath);
399     if (fileName == NULL) {
400         TRANS_LOGE(TRANS_FILE, "get file name failed");
401         goto EXIT_ERR;
402     }
403     if (GetAndCheckRealPath(dirPath, absFullDir) != SOFTBUS_OK) {
404         TRANS_LOGE(TRANS_FILE, "get full abs file failed");
405         goto EXIT_ERR;
406     }
407     TRANS_LOGI(TRANS_FILE, "dirPath=%{private}s, absFullDir=%{private}s", dirPath, absFullDir);
408     fileNameLength = (int32_t)strlen(fileName);
409     dirPathLength = (int32_t)strlen(absFullDir);
410     if (pathSize < (fileNameLength + dirPathLength + 1)) {
411         TRANS_LOGE(TRANS_FILE, "copy name is too large, dirLen=%{public}d, fileNameLen=%{public}d",
412             dirPathLength, fileNameLength);
413         goto EXIT_ERR;
414     }
415     TRANS_LOGI(TRANS_FILE, "fileName=%{private}s, fileNameLen=%{public}d", fileName, fileNameLength);
416     if (sprintf_s(recvAbsPath, pathSize, "%s/%s", absFullDir, fileName) < 0) {
417         TRANS_LOGE(TRANS_FILE, "sprintf_s filename error");
418         goto EXIT_ERR;
419     }
420     TRANS_LOGI(TRANS_FILE, "recvAbsPath=%{private}s", recvAbsPath);
421     SoftBusFree(absFullDir);
422     SoftBusFree(dirPath);
423     return SOFTBUS_OK;
424 
425 EXIT_ERR:
426     SoftBusFree(dirPath);
427     SoftBusFree(absFullDir);
428     return SOFTBUS_FILE_ERR;
429 }
430 
CreateDirAndGetAbsPath(const char * filePath,char * recvAbsPath,int32_t pathSize)431 int32_t CreateDirAndGetAbsPath(const char *filePath, char *recvAbsPath, int32_t pathSize)
432 {
433     if ((filePath == NULL) || (recvAbsPath == NULL)) {
434         TRANS_LOGE(TRANS_FILE, "invalid input");
435         return SOFTBUS_INVALID_PARAM;
436     }
437     uint32_t len = (uint32_t)strlen(filePath);
438     int32_t ret;
439     char *tempPath = (char *)SoftBusCalloc(len + 1);
440     if (tempPath == NULL) {
441         TRANS_LOGE(TRANS_FILE, "calloc tempPath failed");
442         return SOFTBUS_MALLOC_ERR;
443     }
444     for (uint32_t i = 0; i < len; i++) {
445         tempPath[i] = filePath[i];
446         if (tempPath[i] != PATH_SEPARATOR) {
447             continue;
448         }
449         if (SoftBusAccessFile(tempPath, SOFTBUS_F_OK) != SOFTBUS_OK) {
450             ret = SoftBusMakeDir(tempPath, DEFAULT_NEW_PATH_AUTHORITY);
451             if (ret == SOFTBUS_ADAPTER_ERR) {
452                 TRANS_LOGE(TRANS_FILE, "mkdir failed errno=%{public}d", errno);
453                 SoftBusFree(tempPath);
454                 return SOFTBUS_FILE_ERR;
455             }
456         }
457     }
458 
459     SoftBusFree(tempPath);
460     ret = GetAbsFullPath(filePath, recvAbsPath, pathSize);
461     if (ret != SOFTBUS_OK) {
462         TRANS_LOGI(TRANS_FILE, "dest dir is invalid");
463         return ret;
464     }
465     return SOFTBUS_OK;
466 }
467