]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - VtoyTool/BabyISO/biso.c
1.1.07 release
[Ventoy.git] / VtoyTool / BabyISO / biso.c
1 /******************************************************************************
2 * biso.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 #include "biso.h"
22 #include "biso_list.h"
23 #include "biso_util.h"
24 #include "biso_9660.h"
25 #include "biso_eltorito.h"
26 #include "biso_rockridge.h"
27 #include "biso_joliet.h"
28 #include "biso_dump.h"
29
30 CONST STATIC CHAR *g_aszErrMsg[] =
31 {
32 "Success", /* BISO_SUCCESS */
33 "General failed", /* BISO_ERR_FAILED */
34 "Null pointer", /* BISO_ERR_NULL_PTR */
35 "Failed to alloc memory", /* BISO_ERR_ALLOC_MEM */
36 "Failed to open file", /* BISO_ERR_OPEN_FILE */
37 "Failed to read file", /* BISO_ERR_READ_FILE */
38 "Failed to write file", /* BISO_ERR_WRITE_FILE */
39 "Invalid iso-9660 format", /* BISO_ERR_INVALID_ISO9660 */
40 "Unsupported block size", /* BISO_ERR_UNSUPPORTED_BLKSIZE */
41 "Invalid parameter", /* BISO_ERR_INVALID_PARAM */
42 "Not found", /* BISO_ERR_NOT_FOUND */
43 "Not record in iso file", /* BISO_ERR_NOT_RECORD */
44 "Handle is not initialized", /* BISO_ERR_HANDLE_UNINITIALIZED */
45 };
46
47 int g_biso_debug = 0;
48
49 VOID BISO_SetDebug(int debug)
50 {
51 g_biso_debug = debug;
52 }
53
54 CONST CHAR * BISO_GetErrMsg(IN ULONG ulErrCode)
55 {
56 if (ulErrCode > BISO_ERR_BASE)
57 {
58 ulErrCode -= BISO_ERR_BASE;
59 }
60
61 if (ulErrCode > ARRAY_SIZE(g_aszErrMsg))
62 {
63 return NULL;
64 }
65
66 return g_aszErrMsg[ulErrCode];
67 }
68
69 VOID BISO_GetNow(OUT BISO_DATE_S *pstTM)
70 {
71 INT iTimeZone;
72 INT iLocalHour;
73 INT iGMTHour;
74 time_t ulTime;
75 struct tm *pstLocalTM = NULL;
76 struct tm *pstGMTM = NULL;
77
78 if (NULL == pstTM)
79 {
80 return;
81 }
82
83 time(&ulTime);
84 pstGMTM = gmtime(&ulTime);
85 iGMTHour = pstGMTM->tm_hour;
86
87 pstLocalTM = localtime(&ulTime);
88 iLocalHour = pstLocalTM->tm_hour;
89
90 iTimeZone = iLocalHour - iGMTHour;
91 if (iTimeZone < -12)
92 {
93 iTimeZone += 24;
94 }
95 else if (iTimeZone > 12)
96 {
97 iTimeZone -= 24;
98 }
99
100 pstTM->usYear = pstLocalTM->tm_year + 1900;
101 pstTM->ucMonth = pstLocalTM->tm_mon + 1;
102 pstTM->ucDay = pstLocalTM->tm_mday;
103 pstTM->ucHour = pstLocalTM->tm_hour;
104 pstTM->ucMin = pstLocalTM->tm_min;
105 pstTM->ucSecond = pstLocalTM->tm_sec;
106 pstTM->usMillSec = 0;
107 pstTM->cZone = (CHAR)iTimeZone;
108
109 return;
110 }
111
112 VOID BISO_TimeConv(IN ULONG ulTime, OUT BISO_DATE_S *pstTM)
113 {
114 time_t ulTm = ulTime;
115 struct tm *pstLocalTM = NULL;
116
117 pstLocalTM = localtime(&ulTm);
118 pstTM->usYear = pstLocalTM->tm_year + 1900;
119 pstTM->ucMonth = pstLocalTM->tm_mon + 1;
120 pstTM->ucDay = pstLocalTM->tm_mday;
121 pstTM->ucHour = pstLocalTM->tm_hour;
122 pstTM->ucMin = pstLocalTM->tm_min;
123 pstTM->ucSecond = pstLocalTM->tm_sec;
124 pstTM->usMillSec = 0;
125 pstTM->cZone = (CHAR)BISO_UTIL_GetTimeZone();
126
127 return;
128 }
129
130 BISO_READ_S * BISO_AllocReadHandle(VOID)
131 {
132 return (BISO_READ_S *)BISO_9660_CreateParser();
133 }
134
135 VOID BISO_FreeReadHandle(INOUT BISO_READ_S *pstRead)
136 {
137 BISO_9660_DestroyParser((BISO_PARSER_S *)pstRead);
138 }
139
140 BOOL_T BISO_IsISOFile(IN CONST CHAR *pcFileName)
141 {
142 UINT uiReadLen;
143 UINT64 ui64FileSize = 0;
144 BISO_FILE_S *pstFile = NULL;
145 BISO_VD_S stVolDesc;
146
147 /* 先看文件大小,过小的文件不可能是ISO文件 */
148 ui64FileSize = BISO_PLAT_GetFileSize(pcFileName);
149 if (ui64FileSize < BISO_SYSTEM_AREA_SIZE + sizeof(BISO_PVD_S))
150 {
151 return BOOL_FALSE;
152 }
153
154 /* 打开ISO文件 */
155 pstFile = BISO_PLAT_OpenExistFile(pcFileName);
156 if (NULL == pstFile)
157 {
158 return BOOL_FALSE;
159 }
160
161 /* 标准规定前16个逻辑扇区用来保存系统数据,VD信息从第17个扇区开始 */
162 BISO_PLAT_SeekFile(pstFile, BISO_SYSTEM_AREA_SIZE, SEEK_SET);
163
164 /* 读出VD信息 */
165 uiReadLen = (UINT)BISO_PLAT_ReadFile(pstFile, 1, sizeof(stVolDesc), &stVolDesc);
166 if (uiReadLen != sizeof(stVolDesc))
167 {
168 BISO_PLAT_CloseFile(pstFile);
169 return BOOL_FALSE;
170 }
171
172 /* 根据ID检验是否是合法的ISO-9660格式 */
173 if (0 != strncmp(stVolDesc.szId, BISO_VD_ID, strlen(BISO_VD_ID)))
174 {
175 BISO_PLAT_CloseFile(pstFile);
176 return BOOL_FALSE;
177 }
178
179 BISO_PLAT_CloseFile(pstFile);
180 return BOOL_TRUE;
181 }
182
183 BOOL_T BISO_HasSVD(IN CONST BISO_READ_S *pstRead)
184 {
185 if (((BISO_PARSER_S *)pstRead)->pstSVD)
186 {
187 return BOOL_TRUE;
188 }
189
190 return BOOL_FALSE;
191 }
192
193 BOOL_T BISO_IsUDFFile(IN CONST CHAR *pcFileName)
194 {
195 UINT uiReadLen;
196 UINT64 ui64FileSize = 0;
197 BISO_FILE_S *pstFile = NULL;
198 BISO_VD_S stVolDesc;
199
200 /* 先看文件大小,过小的文件不可能是ISO文件 */
201 ui64FileSize = BISO_PLAT_GetFileSize(pcFileName);
202 if (ui64FileSize < BISO_SYSTEM_AREA_SIZE + sizeof(BISO_PVD_S))
203 {
204 return BOOL_FALSE;
205 }
206
207 /* 打开ISO文件 */
208 pstFile = BISO_PLAT_OpenExistFile(pcFileName);
209 if (NULL == pstFile)
210 {
211 return BOOL_FALSE;
212 }
213
214 /* 标准规定前16个逻辑扇区用来保存系统数据,VD信息从第17个扇区开始 */
215 BISO_PLAT_SeekFile(pstFile, BISO_SYSTEM_AREA_SIZE, SEEK_SET);
216
217 do
218 {
219 /* 每次读取1个VD结构 */
220 uiReadLen = (UINT)BISO_PLAT_ReadFile(pstFile, 1, sizeof(stVolDesc), &stVolDesc);
221 if (uiReadLen != sizeof(stVolDesc))
222 {
223 BISO_PLAT_CloseFile(pstFile);
224 return BOOL_FALSE;
225 }
226 } while (BISO_VD_TYPE_END != stVolDesc.ucType);
227
228 /* 根据ID检验是否是合法的UDF格式 */
229 (VOID)BISO_PLAT_ReadFile(pstFile, 1, sizeof(stVolDesc), &stVolDesc);
230 if (0 != strncmp(stVolDesc.szId, "BEA01", strlen("BEA01")))
231 {
232 BISO_PLAT_CloseFile(pstFile);
233 return BOOL_FALSE;
234 }
235
236 /* 根据ID检验是否是合法的UDF格式 */
237 (VOID)BISO_PLAT_ReadFile(pstFile, 1, sizeof(stVolDesc), &stVolDesc);
238 if (0 != strncmp(stVolDesc.szId, "NSR02", strlen("NSR02")) &&
239 0 != strncmp(stVolDesc.szId, "NSR03", strlen("NSR03")))
240 {
241 BISO_PLAT_CloseFile(pstFile);
242 return BOOL_FALSE;
243 }
244
245 BISO_PLAT_CloseFile(pstFile);
246 return BOOL_TRUE;
247 }
248
249 ULONG BISO_OpenImage(IN CONST CHAR *pcFileName, OUT BISO_READ_S *pstRead)
250 {
251 return BISO_9660_OpenImage(BOOL_FALSE, pcFileName, (BISO_PARSER_S *)pstRead);
252 }
253
254 ULONG BISO_OpenImageWithSVD(IN CONST CHAR *pcFileName, OUT BISO_READ_S *pstRead)
255 {
256 return BISO_9660_OpenImage(BOOL_TRUE, pcFileName, (BISO_PARSER_S *)pstRead);
257 }
258
259 ULONG BISO_GetVolumeSummary
260 (
261 IN CONST BISO_READ_S *pstRead,
262 OUT BISO_VOLUME_SUMMARY_S *pstSummary
263 )
264 {
265 BISO_PVD_S *pstPVD = NULL;
266 BISO_PARSER_S *pstParser = NULL;
267
268 if (NULL == pstRead || NULL == pstSummary)
269 {
270 return BISO_ERR_NULL_PTR;
271 }
272
273 if (BOOL_TRUE != BISO_IS_READ_HANDLE_VALID(pstRead))
274 {
275 return BISO_ERR_INVALID_PARAM;
276 }
277
278 pstParser = (BISO_PARSER_S *)pstRead;
279 pstPVD = pstParser->pstPVD;
280
281 /* 拷贝字符串 */
282 BISO_UTIL_CopyStr(pstPVD->szVolumeId, sizeof(pstPVD->szVolumeId), pstSummary->szVolumeId);
283 BISO_UTIL_CopyStr(pstPVD->szSystemId, sizeof(pstPVD->szSystemId), pstSummary->szSystemId);
284 BISO_UTIL_CopyStr(pstPVD->szPublisherId, sizeof(pstPVD->szPublisherId), pstSummary->szPublisherId);
285 BISO_UTIL_CopyStr(pstPVD->szPreparerId, sizeof(pstPVD->szPreparerId), pstSummary->szPreparerId);
286 BISO_UTIL_CopyStr(pstPVD->szApplicationId, sizeof(pstPVD->szApplicationId), pstSummary->szApplicationId);
287 BISO_UTIL_CopyStr(pstPVD->szCopyrightFileId, sizeof(pstPVD->szCopyrightFileId), pstSummary->szCopyrightFileId);
288 BISO_UTIL_CopyStr(pstPVD->szAbstractFileId, sizeof(pstPVD->szAbstractFileId), pstSummary->szAbstractFileId);
289
290 /* 其他字段赋值 */
291 pstSummary->uiRockRidgeVer = pstParser->ucRRIPVersion;
292 pstSummary->uiJolietLevel = BISO_GetJolietLevel(pstRead);
293 pstSummary->uiTotDirNum = pstParser->stDirTree.pstDirStat->uiTotDirNum;
294 pstSummary->uiTotFileNum = pstParser->stDirTree.pstDirStat->uiTotFileNum;
295 pstSummary->uiTotLinkNum = pstParser->stDirTree.pstDirStat->uiTotLinkNum;
296
297 return BISO_SUCCESS;
298 }
299
300 ULONG BISO_GetDate
301 (
302 IN CONST BISO_READ_S *pstRead,
303 IN BISO_DATE_TYPE_E enType,
304 OUT BISO_DATE_S *pstDate
305 )
306 {
307 CONST CHAR *pcDate = NULL;
308 BISO_PVD_S *pstPVD = NULL;
309
310 if ((NULL == pstRead) || (enType >= BISO_DATE_TYPE_BUTT) || (NULL == pstDate))
311 {
312 BISO_DIAG("Invalid param %p %d %p.", pstRead, enType, pstDate);
313 return BISO_ERR_INVALID_PARAM;
314 }
315
316 BISO_CHECK_READ_HANDLE(pstRead);
317 pstPVD = ((BISO_PARSER_S *)pstRead)->pstPVD;
318
319 switch (enType)
320 {
321 case BISO_DATE_TYPE_CREATE:
322 {
323 pcDate = pstPVD->szCreationDate;
324 break;
325 }
326 case BISO_DATE_TYPE_MODIFY:
327 {
328 pcDate = pstPVD->szModifyDate;
329 break;
330 }
331 case BISO_DATE_TYPE_EXPIRATION:
332 {
333 pcDate = pstPVD->szExpirationDate;
334 break;
335 }
336 case BISO_DATE_TYPE_EFFECTIVE:
337 {
338 pcDate = pstPVD->szEffectiveDate;
339 break;
340 }
341 default :
342 {
343 return BISO_ERR_INVALID_PARAM;
344 }
345 }
346
347 return BISO_9660_ParseDate84261(pcDate, pstDate);
348 }
349
350 /* 获取Rock Ridge扩展的Version 0: 没有使用Rock Ridge扩展 具体版本号: 一般都是1 */
351 UINT BISO_GetRockRidgeVer(IN CONST BISO_READ_S *pstRead)
352 {
353 if ((NULL == pstRead) || (BOOL_TRUE != BISO_IS_READ_HANDLE_VALID(pstRead)))
354 {
355 return 0;
356 }
357
358 return ((BISO_PARSER_S *)pstRead)->ucRRIPVersion;
359 }
360
361 /* 获取Joliet扩展的Level */
362 UINT BISO_GetJolietLevel(IN CONST BISO_READ_S *pstRead)
363 {
364 BISO_PARSER_S *pstParser = NULL;
365
366 if ((NULL == pstRead) || (BOOL_TRUE != BISO_IS_READ_HANDLE_VALID(pstRead)))
367 {
368 return 0;
369 }
370
371 pstParser = (BISO_PARSER_S *)pstRead;
372 if (NULL == pstParser->pstSVD)
373 {
374 return 0;
375 }
376 return BISO_JOLIET_GetLevel(pstParser->pstSVD->aucEscape);
377 }
378
379 BISO_HANDLE BISO_GetRoot(IN CONST BISO_READ_S *pstRead)
380 {
381 BISO_PARSER_S *pstParser = (BISO_PARSER_S *)pstRead;
382
383 if (NULL == pstParser)
384 {
385 return NULL;
386 }
387 return (BISO_HANDLE)(&pstParser->stDirTree);
388 }
389
390 ULONG BISO_GetFileNodeByHdl
391 (
392 IN BISO_HANDLE hFileHdl,
393 OUT BISO_FILE_NODE_S *pstFileNode
394 )
395 {
396 BISO_POSIX_INFO_S *pstPosix = NULL;
397 BISO_DIR_TREE_S *pstDirTree = (BISO_DIR_TREE_S *)hFileHdl;
398
399 if ((NULL == pstDirTree) || (NULL == pstFileNode))
400 {
401 return BISO_ERR_NULL_PTR;
402 }
403
404 pstPosix = pstDirTree->pstPosixInfo;
405
406 /* 设置类型 */
407 BISO_SET_FLAG(pstFileNode, pstDirTree);
408
409 /* 设置名称 */
410 scnprintf(pstFileNode->szName, sizeof(pstFileNode->szName), "%s", pstDirTree->szName);
411
412 /* 设置连接路径 */
413 if (BOOL_TRUE == BISO_DIR_TREE_IS_SYMLINK(pstDirTree))
414 {
415 scnprintf(pstFileNode->szLinkTgt, sizeof(pstFileNode->szLinkTgt), "%s", pstPosix->pcLinkSrc);
416 }
417
418 pstFileNode->ui64FileSize = pstDirTree->uiSize;
419 pstFileNode->ui64Seek = (UINT64)((UINT64)pstDirTree->uiExtent * BISO_BLOCK_SIZE);
420 pstFileNode->hParent = (BISO_HANDLE)(pstDirTree->pstParent);
421 pstFileNode->hCurrent = hFileHdl;
422
423 return BISO_SUCCESS;
424 }
425
426 ULONG BISO_GetFileNodeByName
427 (
428 IN CONST BISO_READ_S *pstRead,
429 IN CONST CHAR *pcFullPath,
430 IN UCHAR ucFollowLink,
431 OUT BISO_FILE_NODE_S *pstFileNode
432 )
433 {
434 UINT i = 0;
435 UINT uiDirNum = 0;
436 UINT auiDirPos[32];
437 USHORT usPos = 0;
438 USHORT usLen = 0;
439 CHAR szDirName[1024];
440 BISO_DIR_TREE_S *pstCurDir = NULL;
441 BISO_DIR_TREE_S *pstRootDir = NULL;
442 BISO_DIR_TREE_S *pstFileList = NULL;
443 BISO_PARSER_S *pstParser = (BISO_PARSER_S *)pstRead;
444
445 if ((NULL == pstRead) || (NULL == pcFullPath) || (NULL == pstFileNode))
446 {
447 return BISO_ERR_NULL_PTR;
448 }
449
450 if ('/' == pcFullPath[0])
451 {
452 return BISO_ERR_FAILED;
453 }
454
455 pstRootDir = &(pstParser->stDirTree);
456 pstCurDir = pstRootDir->pstChild;
457
458 if ((0 == pcFullPath[0]) || ((1 == strlen(pcFullPath)) && ('/' == pcFullPath[0])))
459 {
460 /* 出参赋值 */
461 memset(pstFileNode, 0, sizeof(BISO_FILE_NODE_S));
462 BISO_SET_FLAG(pstFileNode, pstCurDir);
463 scnprintf(pstFileNode->szName, sizeof(pstFileNode->szName), "%s", pstCurDir->szName);
464 pstFileNode->hParent = 0;
465 pstFileNode->hCurrent = (BISO_HANDLE)(pstRootDir);
466 return BISO_SUCCESS;
467 }
468
469 if ((1 == uiDirNum) && (NULL != pstRootDir))
470 {
471 pstFileList = pstRootDir->pstFileList;
472 pstCurDir = pstFileList;
473 while (pstCurDir)
474 {
475 if (0 == BISO_PATH_STRCMP(pstCurDir->szName, pcFullPath))
476 {
477 goto FOUND;
478 }
479 pstCurDir = pstCurDir->pstNext;
480 }
481 }
482
483 /* 先将目录分解开 */
484 if (BISO_SUCCESS != BISO_UTIL_PathSplit(pcFullPath, &uiDirNum, auiDirPos))
485 {
486 BISO_DIAG("Failed to split path %s", pcFullPath);
487 return BISO_ERR_FAILED;
488 }
489
490 /* 依次查找每一级目录 */
491 if (pstRootDir)
492 {
493 pstCurDir = pstRootDir->pstChild;
494 }
495 for (i = 0; (i < uiDirNum) && (NULL != pstRootDir) && (NULL != pstCurDir); i++)
496 {
497 usPos = auiDirPos[i] >> 16;
498 usLen = auiDirPos[i] & 0xFF;
499
500 memcpy(szDirName, pcFullPath + usPos, usLen);
501 szDirName[usLen] = 0;
502
503 pstCurDir = pstRootDir->pstChild;
504 pstFileList = pstRootDir->pstFileList;
505
506 /* 先查找目录 */
507 while (pstCurDir)
508 {
509 if (0 == BISO_PATH_STRCMP(pstCurDir->szName, szDirName))
510 {
511 pstRootDir = pstCurDir;
512 break;
513 }
514 pstCurDir = pstCurDir->pstNext;
515 }
516
517 /* 再查找文件 */
518 if (NULL == pstCurDir)
519 {
520 pstCurDir = pstFileList;
521 while (pstCurDir)
522 {
523 if (0 == BISO_PATH_STRCMP(pstCurDir->szName, szDirName))
524 {
525 break;
526 }
527 pstCurDir = pstCurDir->pstNext;
528 }
529 }
530
531 if (NULL == pstCurDir)
532 {
533 return BISO_ERR_FAILED;
534 }
535
536 /* 如果是符号链接则尝试找对应的实际文件 */
537 if ((ucFollowLink > 0) && (BOOL_TRUE == BISO_DIR_TREE_IS_SYMLINK(pstCurDir)))
538 {
539 pstCurDir = BISO_UTIL_FindLinkTgt(pstCurDir);
540 }
541
542 /* 如果是文件(或者是非法链接)的话一定是最后一级 */
543 if ((NULL == pstCurDir->pstDirStat) && (i + 1 != uiDirNum))
544 {
545 return BISO_ERR_FAILED;
546 }
547 }
548
549 FOUND:
550
551 if (NULL == pstCurDir)
552 {
553 return BISO_ERR_FAILED;
554 }
555 else
556 {
557 /* 出参赋值 */
558 memset(pstFileNode, 0, sizeof(BISO_FILE_NODE_S));
559 BISO_SET_FLAG(pstFileNode, pstCurDir);
560 scnprintf(pstFileNode->szName, sizeof(pstFileNode->szName), "%s", pstCurDir->szName);
561 if (BOOL_TRUE == BISO_DIR_TREE_IS_SYMLINK(pstCurDir))
562 {
563 scnprintf(pstFileNode->szLinkTgt, sizeof(pstFileNode->szLinkTgt), "%s",
564 pstCurDir->pstPosixInfo->pcLinkSrc);
565 }
566 pstFileNode->ui64FileSize = pstCurDir->uiSize;
567 pstFileNode->ui64DirRecOffet = pstCurDir->ui64FileRecordOffset;
568 pstFileNode->ui64Seek = (UINT64)((UINT64)pstCurDir->uiExtent * BISO_BLOCK_SIZE);
569 pstFileNode->hParent = (BISO_HANDLE)(pstCurDir->pstParent);
570 pstFileNode->hCurrent = (BISO_HANDLE)(pstCurDir);
571 return BISO_SUCCESS;
572 }
573 }
574
575 ULONG BISO_GetFileNodeByExtent
576 (
577 IN CONST BISO_READ_S *pstRead,
578 IN UINT uiExtent,
579 OUT BISO_FILE_NODE_S *pstFileNode
580 )
581 {
582 BOOL_T bFind = BOOL_FALSE;
583 BISO_QUEUE_S *pstQueue = NULL;
584 BISO_DIR_TREE_S *pstRootDir = NULL;
585 BISO_DIR_TREE_S *pstDirTree = NULL;
586 BISO_DIR_TREE_S *pstCurDir = NULL;
587 BISO_DIR_TREE_S *pstFileList = NULL;
588 BISO_PARSER_S *pstParser = (BISO_PARSER_S *)pstRead;
589
590 if ((NULL == pstRead) || (NULL == pstFileNode))
591 {
592 return BISO_ERR_NULL_PTR;
593 }
594
595 pstRootDir = &(pstParser->stDirTree);
596
597 /* 创建堆栈,同时ROOT入栈 */
598 pstQueue = BISO_QUEUE_Create();
599 BISO_QUEUE_Push(pstQueue, pstRootDir);
600
601 while (NULL != (pstDirTree = (BISO_DIR_TREE_S *)BISO_QUEUE_PopHead(pstQueue)))
602 {
603 pstCurDir = pstDirTree->pstChild;
604 while (pstCurDir)
605 {
606 BISO_QUEUE_Push(pstQueue, pstCurDir);
607 pstCurDir = pstCurDir->pstNext;
608 }
609
610 pstFileList = pstDirTree->pstFileList;
611 pstCurDir = pstFileList;
612 while (pstCurDir)
613 {
614 if (uiExtent == pstCurDir->uiExtent)
615 {
616 while (BISO_QUEUE_PopHead(pstQueue))
617 {
618 bFind = BOOL_TRUE;
619 }
620 break;
621 }
622 pstCurDir = pstCurDir->pstNext;
623 }
624 }
625
626 BISO_QUEUE_Destroy(pstQueue);
627 if (BOOL_TRUE != bFind)
628 {
629 return BISO_ERR_FAILED;
630 }
631 else
632 {
633 /* 出参赋值 */
634 memset(pstFileNode, 0, sizeof(BISO_FILE_NODE_S));
635 BISO_SET_FLAG(pstFileNode, pstCurDir);
636 scnprintf(pstFileNode->szName, sizeof(pstFileNode->szName), "%s", pstCurDir->szName);
637 if (BOOL_TRUE == BISO_DIR_TREE_IS_SYMLINK(pstCurDir))
638 {
639 scnprintf(pstFileNode->szLinkTgt, sizeof(pstFileNode->szLinkTgt), "%s",
640 pstCurDir->pstPosixInfo->pcLinkSrc);
641 }
642 pstFileNode->ui64FileSize = pstCurDir->uiSize;
643 pstFileNode->ui64DirRecOffet = pstCurDir->ui64FileRecordOffset;
644 pstFileNode->ui64Seek = (UINT64)((UINT64)pstCurDir->uiExtent * BISO_BLOCK_SIZE);
645 pstFileNode->hParent = (BISO_HANDLE)(pstCurDir->pstParent);
646 pstFileNode->hCurrent = (BISO_HANDLE)(pstCurDir);
647 return BISO_SUCCESS;
648 }
649 }
650
651
652 ULONG BISO_GetSVDFileNodeByExtent
653 (
654 IN CONST BISO_READ_S *pstRead,
655 IN UINT uiExtent,
656 OUT BISO_SVD_FILE_NODE_S *pstFileNode
657 )
658 {
659 BOOL_T bFind = BOOL_FALSE;
660 BISO_QUEUE_S *pstQueue = NULL;
661 BISO_SVD_DIR_TREE_S *pstRootDir = NULL;
662 BISO_SVD_DIR_TREE_S *pstDirTree = NULL;
663 BISO_SVD_DIR_TREE_S *pstCurDir = NULL;
664 BISO_SVD_DIR_TREE_S *pstFileList = NULL;
665 BISO_PARSER_S *pstParser = (BISO_PARSER_S *)pstRead;
666
667 if ((NULL == pstRead) || (NULL == pstFileNode))
668 {
669 return BISO_ERR_NULL_PTR;
670 }
671
672 pstRootDir = &(pstParser->stSVDDirTree);
673
674 /* 创建堆栈,同时ROOT入栈 */
675 pstQueue = BISO_QUEUE_Create();
676 BISO_QUEUE_Push(pstQueue, pstRootDir);
677
678 while (NULL != (pstDirTree = (BISO_SVD_DIR_TREE_S *)BISO_QUEUE_PopHead(pstQueue)))
679 {
680 pstCurDir = pstDirTree->pstChild;
681 while (pstCurDir)
682 {
683 BISO_QUEUE_Push(pstQueue, pstCurDir);
684 pstCurDir = pstCurDir->pstNext;
685 }
686
687 pstFileList = pstDirTree->pstFileList;
688 pstCurDir = pstFileList;
689 while (pstCurDir)
690 {
691 if (uiExtent == pstCurDir->uiExtent)
692 {
693 while (BISO_QUEUE_PopHead(pstQueue))
694 {
695 bFind = BOOL_TRUE;
696 }
697 break;
698 }
699 pstCurDir = pstCurDir->pstNext;
700 }
701 }
702
703 BISO_QUEUE_Destroy(pstQueue);
704 if (BOOL_TRUE != bFind)
705 {
706 return BISO_ERR_FAILED;
707 }
708 else
709 {
710 /* 出参赋值 */
711 memset(pstFileNode, 0, sizeof(BISO_SVD_FILE_NODE_S));
712 pstFileNode->ui64FileSize = pstCurDir->uiSize;
713 pstFileNode->ui64DirRecOffet = pstCurDir->ui64FileRecordOffset;
714 pstFileNode->ui64Seek = (UINT64)((UINT64)pstCurDir->uiExtent * BISO_BLOCK_SIZE);
715 return BISO_SUCCESS;
716 }
717 }
718
719 ULONG BISO_GetFileTree
720 (
721 IN BISO_HANDLE hTopDir,
722 IN UINT uiFlag,
723 OUT BISO_HANDLE *phFileTree,
724 OUT UINT *puiNodeNum
725 )
726 {
727 BISO_DIR_STAT_S *pstDirStat = NULL;
728 BISO_DIR_TREE_S *pstCurNode = NULL;
729 BISO_DIR_TREE_S *pstDirTree = (BISO_DIR_TREE_S *)hTopDir;
730
731 if ((NULL == pstDirTree) || (NULL == phFileTree) || (NULL == puiNodeNum))
732 {
733 return BISO_ERR_NULL_PTR;
734 }
735
736 pstDirStat = pstDirTree->pstDirStat;
737 if (NULL == pstDirStat)
738 {
739 return BISO_ERR_INVALID_PARAM;
740 }
741
742 *puiNodeNum = pstDirStat->uiCurDirNum + pstDirStat->uiCurFileNum + pstDirStat->uiCurLinkNum;
743
744 switch (uiFlag)
745 {
746 case BISO_TREE_FLAG_CUR:
747 {
748 pstCurNode = pstDirTree->pstChild;
749
750 while (NULL != pstCurNode)
751 {
752 *phFileTree++ = (BISO_HANDLE)pstCurNode;
753 pstCurNode = pstCurNode->pstNext;
754 }
755
756 pstCurNode = pstDirTree->pstFileList;
757 while (NULL != pstCurNode)
758 {
759 *phFileTree++ = (BISO_HANDLE)pstCurNode;
760 pstCurNode = pstCurNode->pstNext;
761 }
762
763 break;
764 }
765 case BISO_TREE_FLAG_DFS:
766 {
767 break;
768 }
769 case BISO_TREE_FLAG_BFS:
770 {
771 break;
772 }
773 default :
774 {
775 return BISO_ERR_INVALID_PARAM;
776 }
777 }
778
779 return BISO_SUCCESS;
780 }
781
782 ULONG BISO_GetDirStat
783 (
784 IN BISO_HANDLE hTopDir,
785 OUT BISO_DIR_STAT_S *pstDirStat
786 )
787 {
788 BISO_DIR_TREE_S *pstDirTree = NULL;
789
790 if ((NULL == hTopDir) || (NULL == pstDirStat))
791 {
792 return BISO_ERR_NULL_PTR;
793 }
794
795 pstDirTree = (BISO_DIR_TREE_S *)hTopDir;
796 if (NULL == pstDirTree->pstDirStat)
797 {
798 return BISO_ERR_INVALID_PARAM;
799 }
800
801 memcpy(pstDirStat, pstDirTree->pstDirStat, sizeof(BISO_DIR_STAT_S));
802 return BISO_SUCCESS;
803 }
804
805
806 VOID BISO_Fill733(IN UINT uiData, OUT VOID *pBuf)
807 {
808 UINT uiSwap = 0;
809 UINT *puiData = (UINT *)pBuf;
810
811 uiSwap |= (uiData & 0xFF) << 24;
812 uiSwap |= ((uiData >> 8) & 0xFF) << 16;
813 uiSwap |= ((uiData >> 16) & 0xFF) << 8;
814 uiSwap |= (uiData >> 24) & 0xFF;
815
816 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
817 puiData[0] = uiData;
818 puiData[1] = uiSwap;
819 #else
820 puiData[0] = uiSwap;
821 puiData[1] = uiData;
822 #endif
823 }
824
825 UINT BISO_Get733(IN CONST VOID *pBuf)
826 {
827 UINT *puiData = (UINT *)pBuf;
828
829 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
830 return puiData[0];
831 #else
832 return puiData[1];
833 #endif
834 }
835
836 UINT BISO_GetFileOccupySize(IN UINT uiRawSize)
837 {
838 UINT uiAlign = uiRawSize % BISO_SECTOR_SIZE;
839
840 if (0 == uiAlign)
841 {
842 return uiRawSize;
843 }
844 else
845 {
846 return uiRawSize + BISO_SECTOR_SIZE - uiAlign;
847 }
848 }
849
850 UINT BISO_GetBootEntryNum(IN CONST BISO_READ_S *pstRead)
851 {
852 return BISO_ELTORITO_GetBootEntryNum((CONST BISO_PARSER_S *)pstRead);
853 }
854
855 VOID BISO_DumpFileTree(IN CONST BISO_READ_S *pstRead)
856 {
857 BISO_PARSER_S *pstParser = (BISO_PARSER_S *)pstRead;
858
859 if (NULL != pstParser)
860 {
861 BISO_DUMP_ShowFileTree(1, pstParser->stDirTree.pstChild);
862 BISO_DUMP_ShowFileTree(1, pstParser->stDirTree.pstFileList);
863 }
864 }
865