]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - VtoyTool/BabyISO/biso_util.c
keep up with 1.0.67 (#1464)
[Ventoy.git] / VtoyTool / BabyISO / biso_util.c
1 /******************************************************************************
2 * biso_util.c
3 *
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21
22 #include "biso.h"
23 #include "biso_list.h"
24 #include "biso_util.h"
25 #include "biso_9660.h"
26
27 VOID *zalloc(size_t size)
28 {
29 void *p = malloc(size);
30 if (NULL != p)
31 {
32 memset(p, 0, size);
33 }
34 return p;
35 }
36
37
38 #if (1 == MEMORY_DEBUG)
39 STATIC UINT g_uiBISOTotMalloc = 0;
40 STATIC UINT g_uiBISOPeekMalloc = 0;
41 STATIC UINT g_uiBISOMallocTime = 0;
42 STATIC UINT g_uiBISOFreeTime = 0;
43
44 VOID *g_apstBISOMalloc[7000];
45 VOID *g_apstBISOFree[7000];
46
47 VOID * BISO_UTIL_Malloc(IN size_t ulSize)
48 {
49 VOID *pData = malloc(ulSize + 4);
50
51 #if (1 == MEMORY_DEBUG_DUMP)
52 printf("ID %u Malloc %p %lu\n", g_uiBISOMallocTime, (UCHAR *)pData + 4, ulSize);
53 g_apstBISOMalloc[g_uiBISOMallocTime] = (UCHAR *)pData + 4;
54 #endif
55
56 *(UINT32 *)pData = (UINT32)ulSize;
57 g_uiBISOMallocTime++;
58 g_uiBISOTotMalloc += (UINT32)ulSize;
59 if (g_uiBISOTotMalloc > g_uiBISOPeekMalloc)
60 {
61 g_uiBISOPeekMalloc = g_uiBISOTotMalloc;
62 }
63
64 return (UCHAR *)pData + 4;
65 }
66
67 VOID *BISO_UTIL_Zalloc(IN size_t ulSize)
68 {
69 VOID *pData = zalloc(ulSize + 4);
70
71 #if (1 == MEMORY_DEBUG_DUMP)
72 printf("ID %u Zalloc %p %lu\n", g_uiBISOMallocTime, (UCHAR *)pData + 4, ulSize);
73 g_apstBISOMalloc[g_uiBISOMallocTime] = (UCHAR *)pData + 4;
74 #endif
75
76 *(UINT32 *)pData = (UINT32)ulSize;
77 g_uiBISOMallocTime++;
78 g_uiBISOTotMalloc += (UINT32)ulSize;
79 if (g_uiBISOTotMalloc > g_uiBISOPeekMalloc)
80 {
81 g_uiBISOPeekMalloc = g_uiBISOTotMalloc;
82 }
83
84 return (UCHAR *)pData + 4;
85 }
86
87 VOID BISO_UTIL_Free(IN VOID *pData)
88 {
89 #if (1 == MEMORY_DEBUG_DUMP)
90 printf("ID %u Free %p %u\n", g_uiBISOFreeTime, pData, *(UINT32 *)((UCHAR *)pData - 4));
91 g_apstBISOFree[g_uiBISOFreeTime] = pData;
92 #endif
93
94 g_uiBISOFreeTime++;
95 g_uiBISOTotMalloc -= *(UINT32 *)((UCHAR *)pData - 4);
96 if (g_uiBISOTotMalloc > g_uiBISOPeekMalloc)
97 {
98 g_uiBISOPeekMalloc = g_uiBISOTotMalloc;
99 }
100
101 free((UCHAR *)pData - 4);
102 }
103
104 VOID BISO_UTIL_DumpMemOp(VOID)
105 {
106 BISO_DUMP("\n Memory Operation: Malloc(%u) Free(%u) \nTotal current use %u, Peek memory use %u.\n",
107 g_uiBISOMallocTime, g_uiBISOFreeTime, g_uiBISOTotMalloc, g_uiBISOPeekMalloc);
108
109 #if (1 == MEMORY_DEBUG_DUMP)
110 {
111 UINT i, j;
112 for (i = 0; i < g_uiBISOMallocTime; i++)
113 {
114 for (j = 0; j < g_uiBISOFreeTime; j++)
115 {
116 if (g_apstBISOMalloc[i] == g_apstBISOFree[j])
117 {
118 break;
119 }
120 }
121
122 if (j >= g_uiBISOFreeTime)
123 {
124 printf("ID %u ptr %p is not freed.\n", i, g_apstBISOMalloc[i]);
125 }
126 }
127 }
128 #endif
129
130 }
131 #endif
132
133 INT BISO_UTIL_GetTimeZone(VOID)
134 {
135 INT iTimeZone;
136 INT iLocalHour;
137 INT iGMTHour;
138 time_t ulTime;
139 struct tm *pstLocalTM = NULL;
140 struct tm *pstGMTM = NULL;
141
142 time(&ulTime);
143 pstGMTM = gmtime(&ulTime);
144 iGMTHour = pstGMTM->tm_hour;
145
146 pstLocalTM = localtime(&ulTime);
147 iLocalHour = pstLocalTM->tm_hour;
148
149 iTimeZone = iLocalHour - iGMTHour;
150 if (iTimeZone < -12)
151 {
152 iTimeZone += 24;
153 }
154 else if (iTimeZone > 12)
155 {
156 iTimeZone -= 24;
157 }
158
159 return iTimeZone;
160 }
161
162 ULONG BISO_UTIL_ReadFile
163 (
164 IN CONST CHAR *pcFileName,
165 IN UINT64 ui64Seek,
166 IN UINT uiDataLen,
167 OUT VOID *pDataBuf
168 )
169 {
170 UINT uiReadLen = 0;
171 BISO_FILE_S *pstFile = NULL;
172
173 if ((NULL == pcFileName) || (NULL == pDataBuf))
174 {
175 return BISO_ERR_NULL_PTR;
176 }
177
178 pstFile = BISO_PLAT_OpenExistFile(pcFileName);
179 if (NULL == pstFile)
180 {
181 return BISO_ERR_OPEN_FILE;
182 }
183
184 BISO_PLAT_SeekFile(pstFile, ui64Seek, SEEK_SET);
185 uiReadLen = (UINT)BISO_PLAT_ReadFile(pstFile, 1, uiDataLen, pDataBuf);
186 if (uiReadLen != uiDataLen)
187 {
188 BISO_DIAG("Read Len %u, data len %u.", uiReadLen, uiDataLen);
189 BISO_PLAT_CloseFile(pstFile);
190 return BISO_ERR_READ_FILE;
191 }
192
193 BISO_PLAT_CloseFile(pstFile);
194 return BISO_SUCCESS;
195 }
196
197
198 CHAR * BISO_UTIL_CopyStr
199 (
200 IN CONST CHAR *szSrc,
201 IN UINT uiSrcSize,
202 OUT CHAR *szDest
203 )
204 {
205 UINT i;
206 UINT uiAllSpace = 1;
207
208 for (i = uiSrcSize; i > 0; i--)
209 {
210 if ((0 != szSrc[i - 1]) && (' ' != szSrc[i - 1]))
211 {
212 uiAllSpace = 0;
213 break;
214 }
215
216 if (' ' != szSrc[i - 1])
217 {
218 uiAllSpace = 0;
219 }
220 }
221
222 if (i > 0)
223 {
224 memcpy(szDest, szSrc, i);
225 }
226 szDest[i] = 0;
227
228 if (uiAllSpace == 1)
229 {
230 scnprintf(szDest, uiSrcSize, "*All Space*"); /* no safe */
231 }
232
233 if (szDest[0] == 0)
234 {
235 scnprintf(szDest, uiSrcSize, "*Empty*"); /* no safe */
236 }
237
238 return szDest;
239 }
240
241 CHAR * BISO_UTIL_CopyUCS2Str
242 (
243 IN CONST CHAR *szSrc,
244 IN UINT uiSrcSize,
245 OUT CHAR *szDest
246 )
247 {
248 UINT i;
249
250 memcpy(szDest, szSrc, uiSrcSize);
251
252 for (i = 0; (i * 2 + 1) < uiSrcSize; i++)
253 {
254 szDest[i] = szDest[i * 2 + 1];
255 }
256 szDest[i] = 0;
257
258 return szDest;
259 }
260
261 VOID BISO_UTIL_PathProc(INOUT CHAR *pcPath, INOUT UINT *puiLen)
262 {
263 UINT i;
264
265 if ((NULL == pcPath) || (NULL == puiLen) || (0 == *puiLen))
266 {
267 return;
268 }
269
270 /* 把所有的\替换为/ */
271 for (i = 0; i < *puiLen; i++)
272 {
273 if ('\\' == pcPath[i])
274 {
275 pcPath[i] = '/';
276 }
277 }
278
279 /* 确保最后有1个/ */
280 if ('/' != pcPath[*puiLen - 1])
281 {
282 pcPath[(*puiLen)++] = '/';
283 pcPath[*puiLen] = 0;
284 }
285 }
286
287 ULONG BISO_UTIL_PathSplit
288 (
289 IN CONST CHAR *pcFullPath,
290 OUT UINT *puiDirNum,
291 OUT UINT *puiDirPos
292 )
293 {
294 USHORT usPos = 0;
295 USHORT usLen = 0;
296 UINT uiDirNum = 0;
297 CONST CHAR *pcLastPos = pcFullPath;
298 CONST CHAR *pcCurPos = pcFullPath;
299
300 DBGASSERT(NULL != pcFullPath);
301 DBGASSERT(NULL != puiDirNum);
302 DBGASSERT(NULL != puiDirPos);
303
304 while (*pcCurPos)
305 {
306 if (('/' == *pcCurPos) || ('\\' == *pcCurPos))
307 {
308 usPos = pcLastPos - pcFullPath;
309 usLen = pcCurPos - pcLastPos;
310 if (usLen <= 0)
311 {
312 return BISO_ERR_FAILED;
313 }
314
315 puiDirPos[uiDirNum] = (UINT)((UINT)usPos << 16) | usLen;
316
317 uiDirNum++;
318 pcLastPos = pcCurPos + 1;
319 }
320
321 pcCurPos++;
322 }
323
324 usPos = pcLastPos - pcFullPath;
325 usLen = pcCurPos - pcLastPos;
326 if (usLen <= 0)
327 {
328 return BISO_ERR_FAILED;
329 }
330 puiDirPos[uiDirNum++] = (UINT)((UINT)usPos << 16) | usLen;
331
332 *puiDirNum = uiDirNum;
333 return BISO_SUCCESS;
334 }
335
336 BISO_DIR_TREE_S * BISO_UTIL_FindLinkTgt(IN BISO_DIR_TREE_S *pstCurNode)
337 {
338 UINT i = 0;
339 UINT uiDirNum = 0;
340 UINT auiDirPos[32];
341 CHAR szDirName[1024];
342 USHORT usPos = 0;
343 USHORT usLen = 0;
344 CHAR *pcLink = NULL;
345 BISO_DIR_TREE_S *pstFileList = NULL;
346 BISO_DIR_TREE_S *pstRootDir = NULL;
347
348 DBGASSERT(NULL != pstCurNode);
349
350 /* 如果不是符号链接则返回自己 */
351 if (BOOL_TRUE != BISO_DIR_TREE_IS_SYMLINK(pstCurNode))
352 {
353 return pstCurNode;
354 }
355
356 pcLink = pstCurNode->pstPosixInfo->pcLinkSrc;
357
358 if ('/' == pcLink[0])
359 {
360 return NULL;
361 }
362
363 /* 把链接分割开 */
364 if (BISO_SUCCESS != BISO_UTIL_PathSplit(pcLink, &uiDirNum, auiDirPos))
365 {
366 return NULL;
367 }
368
369 pstRootDir = pstCurNode->pstParent;
370
371 /* 依次查找每一部分目录 */
372 for (i = 0; (i < uiDirNum) && (NULL != pstCurNode)&& (NULL != pstRootDir); i++)
373 {
374 usPos = auiDirPos[i] >> 16;
375 usLen = auiDirPos[i] & 0xFF;
376
377 memcpy(szDirName, pcLink + usPos, usLen);
378 szDirName[usLen] = 0;
379
380 if (0 == BISO_PATH_STRCMP(szDirName, "."))
381 {
382 pstCurNode = pstCurNode->pstParent;
383 }
384 else if (0 == BISO_PATH_STRCMP(szDirName, ".."))
385 {
386 if (NULL == pstCurNode->pstParent)
387 {
388 return NULL;
389 }
390 pstCurNode = pstCurNode->pstParent->pstParent;
391 pstRootDir = pstCurNode;
392 }
393 else
394 {
395 pstCurNode = pstRootDir->pstChild;
396 pstFileList = pstRootDir->pstFileList;
397
398 /* 先找当前所在目录下的文件夹 */
399 while (pstCurNode)
400 {
401 if (0 == BISO_PATH_STRCMP(pstCurNode->szName, szDirName))
402 {
403 pstRootDir = pstCurNode;
404 break;
405 }
406 pstCurNode = pstCurNode->pstNext;
407 }
408
409 /* 文件夹找不到就找文件 */
410 if (NULL == pstCurNode)
411 {
412 pstCurNode = pstFileList;
413 while (pstCurNode)
414 {
415 if (0 == BISO_PATH_STRCMP(pstCurNode->szName, szDirName))
416 {
417 pstRootDir = NULL;
418 break;
419 }
420 pstCurNode = pstCurNode->pstNext;
421 }
422 }
423 }
424 }
425
426 return pstCurNode;
427 }
428
429 ULONG BISO_MBUF_Append
430 (
431 IN BISO_MBUF_S *pstMBuf,
432 IN UINT uiDataSize,
433 IN VOID *pData
434 )
435 {
436 if ((NULL == pstMBuf) || (pstMBuf->uiCurBufNum >= BISO_MBUF_MAX_BLK))
437 {
438 return BISO_ERR_INVALID_PARAM;
439 }
440
441 pstMBuf->apucDataBuf[pstMBuf->uiCurBufNum] = (UCHAR *)BISO_MALLOC(uiDataSize);
442 if (NULL == pstMBuf->apucDataBuf[pstMBuf->uiCurBufNum])
443 {
444 return BISO_ERR_ALLOC_MEM;
445 }
446
447 if (NULL == pData)
448 {
449 memset(pstMBuf->apucDataBuf[pstMBuf->uiCurBufNum], 0, uiDataSize);
450 }
451 else
452 {
453 memcpy(pstMBuf->apucDataBuf[pstMBuf->uiCurBufNum], pData, uiDataSize);
454 }
455
456 pstMBuf->auiBufSize[pstMBuf->uiCurBufNum] = uiDataSize;
457 pstMBuf->uiTotDataSize += uiDataSize;
458 pstMBuf->uiCurBufNum++;
459
460 return BISO_SUCCESS;
461 }
462
463 VOID BISO_MBUF_Free(IN BISO_MBUF_S *pstMBuf)
464 {
465 UINT i;
466 if (NULL != pstMBuf)
467 {
468 for (i = 0; i < pstMBuf->uiCurBufNum; i++)
469 {
470 BISO_FREE(pstMBuf->apucDataBuf[i]);
471 }
472 memset(pstMBuf, 0, sizeof(BISO_MBUF_S));
473 }
474 }
475
476 VOID BISO_MBUF_CopyToBuf(IN CONST BISO_MBUF_S *pstMBuf, OUT VOID *pDataBuf)
477 {
478 UINT i;
479 UCHAR *pucDataBuf = (UCHAR *)pDataBuf;
480
481 if ((NULL != pstMBuf) && (NULL != pucDataBuf))
482 {
483 for (i = 0; i < pstMBuf->uiCurBufNum; i++)
484 {
485 if (NULL != pstMBuf->apucDataBuf[i])
486 {
487 memcpy(pucDataBuf, pstMBuf->apucDataBuf[i], pstMBuf->auiBufSize[i]);
488 pucDataBuf += pstMBuf->auiBufSize[i];
489 }
490 }
491 }
492 }
493
494 VOID BISO_MBUF_PULLUP(INOUT BISO_MBUF_S *pstMBuf)
495 {
496 UINT uiSize = 0;
497 VOID *pData = NULL;
498
499 DBGASSERT(NULL != pstMBuf);
500
501 if (pstMBuf->uiCurBufNum <= 1)
502 {
503 return;
504 }
505
506 uiSize = pstMBuf->uiTotDataSize;
507 pData = BISO_MALLOC(uiSize);
508 if (NULL == pData)
509 {
510 return;
511 }
512
513 BISO_MBUF_CopyToBuf(pstMBuf, pData);
514 BISO_MBUF_Free(pstMBuf);
515
516 memset(pstMBuf, 0, sizeof(BISO_MBUF_S));
517 pstMBuf->apucDataBuf[0] = (UCHAR *)pData;
518 pstMBuf->auiBufSize[0] = uiSize;
519 pstMBuf->uiTotDataSize = uiSize;
520 pstMBuf->uiCurBufNum = 1;
521
522 return;
523 }
524
525 BISO_QUEUE_S * BISO_QUEUE_Create(VOID)
526 {
527 BISO_DLL_S *pstSLL = (BISO_DLL_S *)BISO_ZALLOC(sizeof(BISO_DLL_S));
528 if (NULL != pstSLL)
529 {
530 BISO_DLL_Init(pstSLL);
531 }
532 return (BISO_QUEUE_S *)pstSLL;
533 }
534
535 VOID BISO_QUEUE_Destroy(IN BISO_QUEUE_S *pstQueue)
536 {
537 BISO_DLL_Free(pstQueue);
538 BISO_FREE(pstQueue);
539 }
540
541 VOID BISO_QUEUE_Push(IN BISO_QUEUE_S *pstQueue, IN VOID *pData)
542 {
543 BISO_QUEUE_NODE_S *pstNode = NULL;
544
545 pstNode = (BISO_QUEUE_NODE_S *)BISO_DLL_Last(pstQueue);
546
547 /* 当前节点已满需要扩展新内存节点 */
548 if ((NULL == pstNode) || (BISO_QUEUE_PTR_NUM == pstNode->usLast))
549 {
550 pstNode = (BISO_QUEUE_NODE_S *)BISO_ZALLOC(sizeof(BISO_QUEUE_NODE_S));
551 if (NULL == pstNode)
552 {
553 return;
554 }
555 BISO_DLL_AddTail(pstQueue, (BISO_DLL_NODE_S *)pstNode);
556 }
557
558 /* Last往前走一步 */
559 pstNode = (BISO_QUEUE_NODE_S *)BISO_DLL_Last(pstQueue);
560 pstNode->apList[pstNode->usLast++] = pData;
561 }
562
563 VOID * BISO_QUEUE_PopHead(IN BISO_QUEUE_S *pstQueue)
564 {
565 VOID *pData = NULL;
566 BISO_QUEUE_NODE_S *pstNode = NULL;
567
568 pstNode = (BISO_QUEUE_NODE_S *)BISO_DLL_First(pstQueue);
569 if (NULL == pstNode)
570 {
571 return NULL;
572 }
573
574 /* First往前走一步 */
575 pData = pstNode->apList[pstNode->usFirst++];
576
577 /* 该节点已空,则摘除节点,释放内存 */
578 if (pstNode->usFirst == pstNode->usLast)
579 {
580 BISO_DLL_DelHead(pstQueue);
581 BISO_FREE(pstNode);
582 }
583
584 return pData;
585 }
586
587 VOID * BISO_QUEUE_PopTail(IN BISO_QUEUE_S *pstQueue)
588 {
589 VOID *pData = NULL;
590 BISO_QUEUE_NODE_S *pstNode = NULL;
591
592 pstNode = (BISO_QUEUE_NODE_S *)BISO_DLL_Last(pstQueue);
593 if ((NULL == pstNode) || (0 == pstNode->usLast))
594 {
595 return NULL;
596 }
597
598 /* Last往后退一步 */
599 pstNode->usLast--;
600 pData = pstNode->apList[pstNode->usLast];
601
602 /* 该节点已空,则摘除节点,释放内存 */
603 if (pstNode->usFirst == pstNode->usLast)
604 {
605 BISO_DLL_DelTail(pstQueue);
606 BISO_FREE(pstNode);
607 }
608
609 return pData;
610 }
611
612 UINT64 BISO_UTIL_WholeFile2Buf(IN CONST CHAR *szFileName, OUT UCHAR *pucBuf)
613 {
614 UINT uiFileSize;
615 UINT uiReadSize;
616 BISO_FILE_S *pstFile = BISO_PLAT_OpenExistFile(szFileName);
617
618 uiFileSize = BISO_PLAT_GetFileSize(szFileName);
619 uiReadSize = BISO_PLAT_ReadFile(pstFile, 1, uiFileSize, pucBuf);
620
621 BISO_PLAT_CloseFile(pstFile);
622
623 return uiReadSize;
624 }
625
626