1 /******************************************************************************
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
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.
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.
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/>.
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"
30 CONST STATIC CHAR
*g_aszErrMsg
[] =
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 */
49 VOID
BISO_SetDebug(int debug
)
54 CONST CHAR
* BISO_GetErrMsg(IN ULONG ulErrCode
)
56 if (ulErrCode
> BISO_ERR_BASE
)
58 ulErrCode
-= BISO_ERR_BASE
;
61 if (ulErrCode
> ARRAY_SIZE(g_aszErrMsg
))
66 return g_aszErrMsg
[ulErrCode
];
69 VOID
BISO_GetNow(OUT BISO_DATE_S
*pstTM
)
75 struct tm
*pstLocalTM
= NULL
;
76 struct tm
*pstGMTM
= NULL
;
84 pstGMTM
= gmtime(&ulTime
);
85 iGMTHour
= pstGMTM
->tm_hour
;
87 pstLocalTM
= localtime(&ulTime
);
88 iLocalHour
= pstLocalTM
->tm_hour
;
90 iTimeZone
= iLocalHour
- iGMTHour
;
95 else if (iTimeZone
> 12)
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
;
112 VOID
BISO_TimeConv(IN ULONG ulTime
, OUT BISO_DATE_S
*pstTM
)
114 time_t ulTm
= ulTime
;
115 struct tm
*pstLocalTM
= NULL
;
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();
130 BISO_READ_S
* BISO_AllocReadHandle(VOID
)
132 return (BISO_READ_S
*)BISO_9660_CreateParser();
135 VOID
BISO_FreeReadHandle(INOUT BISO_READ_S
*pstRead
)
137 BISO_9660_DestroyParser((BISO_PARSER_S
*)pstRead
);
140 BOOL_T
BISO_IsISOFile(IN CONST CHAR
*pcFileName
)
143 UINT64 ui64FileSize
= 0;
144 BISO_FILE_S
*pstFile
= NULL
;
147 /* 先看文件大小,过小的文件不可能是ISO文件 */
148 ui64FileSize
= BISO_PLAT_GetFileSize(pcFileName
);
149 if (ui64FileSize
< BISO_SYSTEM_AREA_SIZE
+ sizeof(BISO_PVD_S
))
155 pstFile
= BISO_PLAT_OpenExistFile(pcFileName
);
161 /* 标准规定前16个逻辑扇区用来保存系统数据,VD信息从第17个扇区开始 */
162 BISO_PLAT_SeekFile(pstFile
, BISO_SYSTEM_AREA_SIZE
, SEEK_SET
);
165 uiReadLen
= (UINT
)BISO_PLAT_ReadFile(pstFile
, 1, sizeof(stVolDesc
), &stVolDesc
);
166 if (uiReadLen
!= sizeof(stVolDesc
))
168 BISO_PLAT_CloseFile(pstFile
);
172 /* 根据ID检验是否是合法的ISO-9660格式 */
173 if (0 != strncmp(stVolDesc
.szId
, BISO_VD_ID
, strlen(BISO_VD_ID
)))
175 BISO_PLAT_CloseFile(pstFile
);
179 BISO_PLAT_CloseFile(pstFile
);
183 BOOL_T
BISO_HasSVD(IN CONST BISO_READ_S
*pstRead
)
185 if (((BISO_PARSER_S
*)pstRead
)->pstSVD
)
193 BOOL_T
BISO_IsUDFFile(IN CONST CHAR
*pcFileName
)
196 UINT64 ui64FileSize
= 0;
197 BISO_FILE_S
*pstFile
= NULL
;
200 /* 先看文件大小,过小的文件不可能是ISO文件 */
201 ui64FileSize
= BISO_PLAT_GetFileSize(pcFileName
);
202 if (ui64FileSize
< BISO_SYSTEM_AREA_SIZE
+ sizeof(BISO_PVD_S
))
208 pstFile
= BISO_PLAT_OpenExistFile(pcFileName
);
214 /* 标准规定前16个逻辑扇区用来保存系统数据,VD信息从第17个扇区开始 */
215 BISO_PLAT_SeekFile(pstFile
, BISO_SYSTEM_AREA_SIZE
, SEEK_SET
);
220 uiReadLen
= (UINT
)BISO_PLAT_ReadFile(pstFile
, 1, sizeof(stVolDesc
), &stVolDesc
);
221 if (uiReadLen
!= sizeof(stVolDesc
))
223 BISO_PLAT_CloseFile(pstFile
);
226 } while (BISO_VD_TYPE_END
!= stVolDesc
.ucType
);
228 /* 根据ID检验是否是合法的UDF格式 */
229 (VOID
)BISO_PLAT_ReadFile(pstFile
, 1, sizeof(stVolDesc
), &stVolDesc
);
230 if (0 != strncmp(stVolDesc
.szId
, "BEA01", strlen("BEA01")))
232 BISO_PLAT_CloseFile(pstFile
);
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")))
241 BISO_PLAT_CloseFile(pstFile
);
245 BISO_PLAT_CloseFile(pstFile
);
249 ULONG
BISO_OpenImage(IN CONST CHAR
*pcFileName
, OUT BISO_READ_S
*pstRead
)
251 return BISO_9660_OpenImage(BOOL_FALSE
, pcFileName
, (BISO_PARSER_S
*)pstRead
);
254 ULONG
BISO_OpenImageWithSVD(IN CONST CHAR
*pcFileName
, OUT BISO_READ_S
*pstRead
)
256 return BISO_9660_OpenImage(BOOL_TRUE
, pcFileName
, (BISO_PARSER_S
*)pstRead
);
259 ULONG BISO_GetVolumeSummary
261 IN CONST BISO_READ_S
*pstRead
,
262 OUT BISO_VOLUME_SUMMARY_S
*pstSummary
265 BISO_PVD_S
*pstPVD
= NULL
;
266 BISO_PARSER_S
*pstParser
= NULL
;
268 if (NULL
== pstRead
|| NULL
== pstSummary
)
270 return BISO_ERR_NULL_PTR
;
273 if (BOOL_TRUE
!= BISO_IS_READ_HANDLE_VALID(pstRead
))
275 return BISO_ERR_INVALID_PARAM
;
278 pstParser
= (BISO_PARSER_S
*)pstRead
;
279 pstPVD
= pstParser
->pstPVD
;
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
);
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
;
302 IN CONST BISO_READ_S
*pstRead
,
303 IN BISO_DATE_TYPE_E enType
,
304 OUT BISO_DATE_S
*pstDate
307 CONST CHAR
*pcDate
= NULL
;
308 BISO_PVD_S
*pstPVD
= NULL
;
310 if ((NULL
== pstRead
) || (enType
>= BISO_DATE_TYPE_BUTT
) || (NULL
== pstDate
))
312 BISO_DIAG("Invalid param %p %d %p.", pstRead
, enType
, pstDate
);
313 return BISO_ERR_INVALID_PARAM
;
316 BISO_CHECK_READ_HANDLE(pstRead
);
317 pstPVD
= ((BISO_PARSER_S
*)pstRead
)->pstPVD
;
321 case BISO_DATE_TYPE_CREATE
:
323 pcDate
= pstPVD
->szCreationDate
;
326 case BISO_DATE_TYPE_MODIFY
:
328 pcDate
= pstPVD
->szModifyDate
;
331 case BISO_DATE_TYPE_EXPIRATION
:
333 pcDate
= pstPVD
->szExpirationDate
;
336 case BISO_DATE_TYPE_EFFECTIVE
:
338 pcDate
= pstPVD
->szEffectiveDate
;
343 return BISO_ERR_INVALID_PARAM
;
347 return BISO_9660_ParseDate84261(pcDate
, pstDate
);
350 /* 获取Rock Ridge扩展的Version 0: 没有使用Rock Ridge扩展 具体版本号: 一般都是1 */
351 UINT
BISO_GetRockRidgeVer(IN CONST BISO_READ_S
*pstRead
)
353 if ((NULL
== pstRead
) || (BOOL_TRUE
!= BISO_IS_READ_HANDLE_VALID(pstRead
)))
358 return ((BISO_PARSER_S
*)pstRead
)->ucRRIPVersion
;
361 /* 获取Joliet扩展的Level */
362 UINT
BISO_GetJolietLevel(IN CONST BISO_READ_S
*pstRead
)
364 BISO_PARSER_S
*pstParser
= NULL
;
366 if ((NULL
== pstRead
) || (BOOL_TRUE
!= BISO_IS_READ_HANDLE_VALID(pstRead
)))
371 pstParser
= (BISO_PARSER_S
*)pstRead
;
372 if (NULL
== pstParser
->pstSVD
)
376 return BISO_JOLIET_GetLevel(pstParser
->pstSVD
->aucEscape
);
379 BISO_HANDLE
BISO_GetRoot(IN CONST BISO_READ_S
*pstRead
)
381 BISO_PARSER_S
*pstParser
= (BISO_PARSER_S
*)pstRead
;
383 if (NULL
== pstParser
)
387 return (BISO_HANDLE
)(&pstParser
->stDirTree
);
390 ULONG BISO_GetFileNodeByHdl
392 IN BISO_HANDLE hFileHdl
,
393 OUT BISO_FILE_NODE_S
*pstFileNode
396 BISO_POSIX_INFO_S
*pstPosix
= NULL
;
397 BISO_DIR_TREE_S
*pstDirTree
= (BISO_DIR_TREE_S
*)hFileHdl
;
399 if ((NULL
== pstDirTree
) || (NULL
== pstFileNode
))
401 return BISO_ERR_NULL_PTR
;
404 pstPosix
= pstDirTree
->pstPosixInfo
;
407 BISO_SET_FLAG(pstFileNode
, pstDirTree
);
410 scnprintf(pstFileNode
->szName
, sizeof(pstFileNode
->szName
), "%s", pstDirTree
->szName
);
413 if (BOOL_TRUE
== BISO_DIR_TREE_IS_SYMLINK(pstDirTree
))
415 scnprintf(pstFileNode
->szLinkTgt
, sizeof(pstFileNode
->szLinkTgt
), "%s", pstPosix
->pcLinkSrc
);
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
;
426 ULONG BISO_GetFileNodeByName
428 IN CONST BISO_READ_S
*pstRead
,
429 IN CONST CHAR
*pcFullPath
,
430 IN UCHAR ucFollowLink
,
431 OUT BISO_FILE_NODE_S
*pstFileNode
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
;
445 if ((NULL
== pstRead
) || (NULL
== pcFullPath
) || (NULL
== pstFileNode
))
447 return BISO_ERR_NULL_PTR
;
450 if ('/' == pcFullPath
[0])
452 return BISO_ERR_FAILED
;
455 pstRootDir
= &(pstParser
->stDirTree
);
456 pstCurDir
= pstRootDir
->pstChild
;
458 if ((0 == pcFullPath
[0]) || ((1 == strlen(pcFullPath
)) && ('/' == pcFullPath
[0])))
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
);
469 if ((1 == uiDirNum
) && (NULL
!= pstRootDir
))
471 pstFileList
= pstRootDir
->pstFileList
;
472 pstCurDir
= pstFileList
;
475 if (0 == BISO_PATH_STRCMP(pstCurDir
->szName
, pcFullPath
))
479 pstCurDir
= pstCurDir
->pstNext
;
484 if (BISO_SUCCESS
!= BISO_UTIL_PathSplit(pcFullPath
, &uiDirNum
, auiDirPos
))
486 BISO_DIAG("Failed to split path %s", pcFullPath
);
487 return BISO_ERR_FAILED
;
493 pstCurDir
= pstRootDir
->pstChild
;
495 for (i
= 0; (i
< uiDirNum
) && (NULL
!= pstRootDir
) && (NULL
!= pstCurDir
); i
++)
497 usPos
= auiDirPos
[i
] >> 16;
498 usLen
= auiDirPos
[i
] & 0xFF;
500 memcpy(szDirName
, pcFullPath
+ usPos
, usLen
);
501 szDirName
[usLen
] = 0;
503 pstCurDir
= pstRootDir
->pstChild
;
504 pstFileList
= pstRootDir
->pstFileList
;
509 if (0 == BISO_PATH_STRCMP(pstCurDir
->szName
, szDirName
))
511 pstRootDir
= pstCurDir
;
514 pstCurDir
= pstCurDir
->pstNext
;
518 if (NULL
== pstCurDir
)
520 pstCurDir
= pstFileList
;
523 if (0 == BISO_PATH_STRCMP(pstCurDir
->szName
, szDirName
))
527 pstCurDir
= pstCurDir
->pstNext
;
531 if (NULL
== pstCurDir
)
533 return BISO_ERR_FAILED
;
536 /* 如果是符号链接则尝试找对应的实际文件 */
537 if ((ucFollowLink
> 0) && (BOOL_TRUE
== BISO_DIR_TREE_IS_SYMLINK(pstCurDir
)))
539 pstCurDir
= BISO_UTIL_FindLinkTgt(pstCurDir
);
542 /* 如果是文件(或者是非法链接)的话一定是最后一级 */
543 if ((NULL
== pstCurDir
->pstDirStat
) && (i
+ 1 != uiDirNum
))
545 return BISO_ERR_FAILED
;
551 if (NULL
== pstCurDir
)
553 return BISO_ERR_FAILED
;
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
))
563 scnprintf(pstFileNode
->szLinkTgt
, sizeof(pstFileNode
->szLinkTgt
), "%s",
564 pstCurDir
->pstPosixInfo
->pcLinkSrc
);
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
);
575 ULONG BISO_GetFileNodeByExtent
577 IN CONST BISO_READ_S
*pstRead
,
579 OUT BISO_FILE_NODE_S
*pstFileNode
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
;
590 if ((NULL
== pstRead
) || (NULL
== pstFileNode
))
592 return BISO_ERR_NULL_PTR
;
595 pstRootDir
= &(pstParser
->stDirTree
);
598 pstQueue
= BISO_QUEUE_Create();
599 BISO_QUEUE_Push(pstQueue
, pstRootDir
);
601 while (NULL
!= (pstDirTree
= (BISO_DIR_TREE_S
*)BISO_QUEUE_PopHead(pstQueue
)))
603 pstCurDir
= pstDirTree
->pstChild
;
606 BISO_QUEUE_Push(pstQueue
, pstCurDir
);
607 pstCurDir
= pstCurDir
->pstNext
;
610 pstFileList
= pstDirTree
->pstFileList
;
611 pstCurDir
= pstFileList
;
614 if (uiExtent
== pstCurDir
->uiExtent
)
616 while (BISO_QUEUE_PopHead(pstQueue
))
622 pstCurDir
= pstCurDir
->pstNext
;
626 BISO_QUEUE_Destroy(pstQueue
);
627 if (BOOL_TRUE
!= bFind
)
629 return BISO_ERR_FAILED
;
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
))
639 scnprintf(pstFileNode
->szLinkTgt
, sizeof(pstFileNode
->szLinkTgt
), "%s",
640 pstCurDir
->pstPosixInfo
->pcLinkSrc
);
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
);
652 ULONG BISO_GetSVDFileNodeByExtent
654 IN CONST BISO_READ_S
*pstRead
,
656 OUT BISO_SVD_FILE_NODE_S
*pstFileNode
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
;
667 if ((NULL
== pstRead
) || (NULL
== pstFileNode
))
669 return BISO_ERR_NULL_PTR
;
672 pstRootDir
= &(pstParser
->stSVDDirTree
);
675 pstQueue
= BISO_QUEUE_Create();
676 BISO_QUEUE_Push(pstQueue
, pstRootDir
);
678 while (NULL
!= (pstDirTree
= (BISO_SVD_DIR_TREE_S
*)BISO_QUEUE_PopHead(pstQueue
)))
680 pstCurDir
= pstDirTree
->pstChild
;
683 BISO_QUEUE_Push(pstQueue
, pstCurDir
);
684 pstCurDir
= pstCurDir
->pstNext
;
687 pstFileList
= pstDirTree
->pstFileList
;
688 pstCurDir
= pstFileList
;
691 if (uiExtent
== pstCurDir
->uiExtent
)
693 while (BISO_QUEUE_PopHead(pstQueue
))
699 pstCurDir
= pstCurDir
->pstNext
;
703 BISO_QUEUE_Destroy(pstQueue
);
704 if (BOOL_TRUE
!= bFind
)
706 return BISO_ERR_FAILED
;
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
);
719 ULONG BISO_GetFileTree
721 IN BISO_HANDLE hTopDir
,
723 OUT BISO_HANDLE
*phFileTree
,
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
;
731 if ((NULL
== pstDirTree
) || (NULL
== phFileTree
) || (NULL
== puiNodeNum
))
733 return BISO_ERR_NULL_PTR
;
736 pstDirStat
= pstDirTree
->pstDirStat
;
737 if (NULL
== pstDirStat
)
739 return BISO_ERR_INVALID_PARAM
;
742 *puiNodeNum
= pstDirStat
->uiCurDirNum
+ pstDirStat
->uiCurFileNum
+ pstDirStat
->uiCurLinkNum
;
746 case BISO_TREE_FLAG_CUR
:
748 pstCurNode
= pstDirTree
->pstChild
;
750 while (NULL
!= pstCurNode
)
752 *phFileTree
++ = (BISO_HANDLE
)pstCurNode
;
753 pstCurNode
= pstCurNode
->pstNext
;
756 pstCurNode
= pstDirTree
->pstFileList
;
757 while (NULL
!= pstCurNode
)
759 *phFileTree
++ = (BISO_HANDLE
)pstCurNode
;
760 pstCurNode
= pstCurNode
->pstNext
;
765 case BISO_TREE_FLAG_DFS
:
769 case BISO_TREE_FLAG_BFS
:
775 return BISO_ERR_INVALID_PARAM
;
782 ULONG BISO_GetDirStat
784 IN BISO_HANDLE hTopDir
,
785 OUT BISO_DIR_STAT_S
*pstDirStat
788 BISO_DIR_TREE_S
*pstDirTree
= NULL
;
790 if ((NULL
== hTopDir
) || (NULL
== pstDirStat
))
792 return BISO_ERR_NULL_PTR
;
795 pstDirTree
= (BISO_DIR_TREE_S
*)hTopDir
;
796 if (NULL
== pstDirTree
->pstDirStat
)
798 return BISO_ERR_INVALID_PARAM
;
801 memcpy(pstDirStat
, pstDirTree
->pstDirStat
, sizeof(BISO_DIR_STAT_S
));
806 VOID
BISO_Fill733(IN UINT uiData
, OUT VOID
*pBuf
)
809 UINT
*puiData
= (UINT
*)pBuf
;
811 uiSwap
|= (uiData
& 0xFF) << 24;
812 uiSwap
|= ((uiData
>> 8) & 0xFF) << 16;
813 uiSwap
|= ((uiData
>> 16) & 0xFF) << 8;
814 uiSwap
|= (uiData
>> 24) & 0xFF;
816 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
825 UINT
BISO_Get733(IN CONST VOID
*pBuf
)
827 UINT
*puiData
= (UINT
*)pBuf
;
829 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
836 UINT
BISO_GetFileOccupySize(IN UINT uiRawSize
)
838 UINT uiAlign
= uiRawSize
% BISO_SECTOR_SIZE
;
846 return uiRawSize
+ BISO_SECTOR_SIZE
- uiAlign
;
850 UINT
BISO_GetBootEntryNum(IN CONST BISO_READ_S
*pstRead
)
852 return BISO_ELTORITO_GetBootEntryNum((CONST BISO_PARSER_S
*)pstRead
);
855 VOID
BISO_DumpFileTree(IN CONST BISO_READ_S
*pstRead
)
857 BISO_PARSER_S
*pstParser
= (BISO_PARSER_S
*)pstRead
;
859 if (NULL
!= pstParser
)
861 BISO_DUMP_ShowFileTree(1, pstParser
->stDirTree
.pstChild
);
862 BISO_DUMP_ShowFileTree(1, pstParser
->stDirTree
.pstFileList
);