You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Ventoy/VtoyTool/BabyISO/biso.c

866 lines
23 KiB
C

4 years ago
/******************************************************************************
* biso.c
*
* Copyright (c) 2020, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include "biso.h"
#include "biso_list.h"
#include "biso_util.h"
#include "biso_9660.h"
#include "biso_eltorito.h"
#include "biso_rockridge.h"
#include "biso_joliet.h"
#include "biso_dump.h"
CONST STATIC CHAR *g_aszErrMsg[] =
{
"Success", /* BISO_SUCCESS */
"General failed", /* BISO_ERR_FAILED */
"Null pointer", /* BISO_ERR_NULL_PTR */
"Failed to alloc memory", /* BISO_ERR_ALLOC_MEM */
"Failed to open file", /* BISO_ERR_OPEN_FILE */
"Failed to read file", /* BISO_ERR_READ_FILE */
"Failed to write file", /* BISO_ERR_WRITE_FILE */
"Invalid iso-9660 format", /* BISO_ERR_INVALID_ISO9660 */
"Unsupported block size", /* BISO_ERR_UNSUPPORTED_BLKSIZE */
"Invalid parameter", /* BISO_ERR_INVALID_PARAM */
"Not found", /* BISO_ERR_NOT_FOUND */
"Not record in iso file", /* BISO_ERR_NOT_RECORD */
"Handle is not initialized", /* BISO_ERR_HANDLE_UNINITIALIZED */
};
int g_biso_debug = 0;
VOID BISO_SetDebug(int debug)
{
g_biso_debug = debug;
}
CONST CHAR * BISO_GetErrMsg(IN ULONG ulErrCode)
{
if (ulErrCode > BISO_ERR_BASE)
{
ulErrCode -= BISO_ERR_BASE;
}
if (ulErrCode > ARRAY_SIZE(g_aszErrMsg))
{
return NULL;
}
return g_aszErrMsg[ulErrCode];
}
VOID BISO_GetNow(OUT BISO_DATE_S *pstTM)
{
INT iTimeZone;
INT iLocalHour;
INT iGMTHour;
time_t ulTime;
struct tm *pstLocalTM = NULL;
struct tm *pstGMTM = NULL;
if (NULL == pstTM)
{
return;
}
time(&ulTime);
pstGMTM = gmtime(&ulTime);
iGMTHour = pstGMTM->tm_hour;
pstLocalTM = localtime(&ulTime);
iLocalHour = pstLocalTM->tm_hour;
iTimeZone = iLocalHour - iGMTHour;
if (iTimeZone < -12)
{
iTimeZone += 24;
}
else if (iTimeZone > 12)
{
iTimeZone -= 24;
}
pstTM->usYear = pstLocalTM->tm_year + 1900;
pstTM->ucMonth = pstLocalTM->tm_mon + 1;
pstTM->ucDay = pstLocalTM->tm_mday;
pstTM->ucHour = pstLocalTM->tm_hour;
pstTM->ucMin = pstLocalTM->tm_min;
pstTM->ucSecond = pstLocalTM->tm_sec;
pstTM->usMillSec = 0;
pstTM->cZone = (CHAR)iTimeZone;
return;
}
VOID BISO_TimeConv(IN ULONG ulTime, OUT BISO_DATE_S *pstTM)
{
time_t ulTm = ulTime;
struct tm *pstLocalTM = NULL;
pstLocalTM = localtime(&ulTm);
pstTM->usYear = pstLocalTM->tm_year + 1900;
pstTM->ucMonth = pstLocalTM->tm_mon + 1;
pstTM->ucDay = pstLocalTM->tm_mday;
pstTM->ucHour = pstLocalTM->tm_hour;
pstTM->ucMin = pstLocalTM->tm_min;
pstTM->ucSecond = pstLocalTM->tm_sec;
pstTM->usMillSec = 0;
pstTM->cZone = (CHAR)BISO_UTIL_GetTimeZone();
return;
}
BISO_READ_S * BISO_AllocReadHandle(VOID)
{
return (BISO_READ_S *)BISO_9660_CreateParser();
}
VOID BISO_FreeReadHandle(INOUT BISO_READ_S *pstRead)
{
BISO_9660_DestroyParser((BISO_PARSER_S *)pstRead);
}
BOOL_T BISO_IsISOFile(IN CONST CHAR *pcFileName)
{
UINT uiReadLen;
UINT64 ui64FileSize = 0;
BISO_FILE_S *pstFile = NULL;
BISO_VD_S stVolDesc;
/* 先看文件大小过小的文件不可能是ISO文件 */
ui64FileSize = BISO_PLAT_GetFileSize(pcFileName);
if (ui64FileSize < BISO_SYSTEM_AREA_SIZE + sizeof(BISO_PVD_S))
{
return BOOL_FALSE;
}
/* 打开ISO文件 */
pstFile = BISO_PLAT_OpenExistFile(pcFileName);
if (NULL == pstFile)
{
return BOOL_FALSE;
}
/* 标准规定前16个逻辑扇区用来保存系统数据VD信息从第17个扇区开始 */
BISO_PLAT_SeekFile(pstFile, BISO_SYSTEM_AREA_SIZE, SEEK_SET);
/* 读出VD信息 */
uiReadLen = (UINT)BISO_PLAT_ReadFile(pstFile, 1, sizeof(stVolDesc), &stVolDesc);
if (uiReadLen != sizeof(stVolDesc))
{
BISO_PLAT_CloseFile(pstFile);
return BOOL_FALSE;
}
/* 根据ID检验是否是合法的ISO-9660格式 */
if (0 != strncmp(stVolDesc.szId, BISO_VD_ID, strlen(BISO_VD_ID)))
{
BISO_PLAT_CloseFile(pstFile);
return BOOL_FALSE;
}
BISO_PLAT_CloseFile(pstFile);
return BOOL_TRUE;
}
BOOL_T BISO_HasSVD(IN CONST BISO_READ_S *pstRead)
{
if (((BISO_PARSER_S *)pstRead)->pstSVD)
{
return BOOL_TRUE;
}
return BOOL_FALSE;
}
BOOL_T BISO_IsUDFFile(IN CONST CHAR *pcFileName)
{
UINT uiReadLen;
UINT64 ui64FileSize = 0;
BISO_FILE_S *pstFile = NULL;
BISO_VD_S stVolDesc;
/* 先看文件大小过小的文件不可能是ISO文件 */
ui64FileSize = BISO_PLAT_GetFileSize(pcFileName);
if (ui64FileSize < BISO_SYSTEM_AREA_SIZE + sizeof(BISO_PVD_S))
{
return BOOL_FALSE;
}
/* 打开ISO文件 */
pstFile = BISO_PLAT_OpenExistFile(pcFileName);
if (NULL == pstFile)
{
return BOOL_FALSE;
}
/* 标准规定前16个逻辑扇区用来保存系统数据VD信息从第17个扇区开始 */
BISO_PLAT_SeekFile(pstFile, BISO_SYSTEM_AREA_SIZE, SEEK_SET);
do
{
/* 每次读取1个VD结构 */
uiReadLen = (UINT)BISO_PLAT_ReadFile(pstFile, 1, sizeof(stVolDesc), &stVolDesc);
if (uiReadLen != sizeof(stVolDesc))
{
BISO_PLAT_CloseFile(pstFile);
return BOOL_FALSE;
}
} while (BISO_VD_TYPE_END != stVolDesc.ucType);
/* 根据ID检验是否是合法的UDF格式 */
(VOID)BISO_PLAT_ReadFile(pstFile, 1, sizeof(stVolDesc), &stVolDesc);
if (0 != strncmp(stVolDesc.szId, "BEA01", strlen("BEA01")))
{
BISO_PLAT_CloseFile(pstFile);
return BOOL_FALSE;
}
/* 根据ID检验是否是合法的UDF格式 */
(VOID)BISO_PLAT_ReadFile(pstFile, 1, sizeof(stVolDesc), &stVolDesc);
if (0 != strncmp(stVolDesc.szId, "NSR02", strlen("NSR02")) &&
0 != strncmp(stVolDesc.szId, "NSR03", strlen("NSR03")))
{
BISO_PLAT_CloseFile(pstFile);
return BOOL_FALSE;
}
BISO_PLAT_CloseFile(pstFile);
return BOOL_TRUE;
}
ULONG BISO_OpenImage(IN CONST CHAR *pcFileName, OUT BISO_READ_S *pstRead)
{
return BISO_9660_OpenImage(BOOL_FALSE, pcFileName, (BISO_PARSER_S *)pstRead);
}
ULONG BISO_OpenImageWithSVD(IN CONST CHAR *pcFileName, OUT BISO_READ_S *pstRead)
{
return BISO_9660_OpenImage(BOOL_TRUE, pcFileName, (BISO_PARSER_S *)pstRead);
}
ULONG BISO_GetVolumeSummary
(
IN CONST BISO_READ_S *pstRead,
OUT BISO_VOLUME_SUMMARY_S *pstSummary
)
{
BISO_PVD_S *pstPVD = NULL;
BISO_PARSER_S *pstParser = NULL;
if (NULL == pstRead || NULL == pstSummary)
{
return BISO_ERR_NULL_PTR;
}
if (BOOL_TRUE != BISO_IS_READ_HANDLE_VALID(pstRead))
{
return BISO_ERR_INVALID_PARAM;
}
pstParser = (BISO_PARSER_S *)pstRead;
pstPVD = pstParser->pstPVD;
/* 拷贝字符串 */
BISO_UTIL_CopyStr(pstPVD->szVolumeId, sizeof(pstPVD->szVolumeId), pstSummary->szVolumeId);
BISO_UTIL_CopyStr(pstPVD->szSystemId, sizeof(pstPVD->szSystemId), pstSummary->szSystemId);
BISO_UTIL_CopyStr(pstPVD->szPublisherId, sizeof(pstPVD->szPublisherId), pstSummary->szPublisherId);
BISO_UTIL_CopyStr(pstPVD->szPreparerId, sizeof(pstPVD->szPreparerId), pstSummary->szPreparerId);
BISO_UTIL_CopyStr(pstPVD->szApplicationId, sizeof(pstPVD->szApplicationId), pstSummary->szApplicationId);
BISO_UTIL_CopyStr(pstPVD->szCopyrightFileId, sizeof(pstPVD->szCopyrightFileId), pstSummary->szCopyrightFileId);
BISO_UTIL_CopyStr(pstPVD->szAbstractFileId, sizeof(pstPVD->szAbstractFileId), pstSummary->szAbstractFileId);
/* 其他字段赋值 */
pstSummary->uiRockRidgeVer = pstParser->ucRRIPVersion;
pstSummary->uiJolietLevel = BISO_GetJolietLevel(pstRead);
pstSummary->uiTotDirNum = pstParser->stDirTree.pstDirStat->uiTotDirNum;
pstSummary->uiTotFileNum = pstParser->stDirTree.pstDirStat->uiTotFileNum;
pstSummary->uiTotLinkNum = pstParser->stDirTree.pstDirStat->uiTotLinkNum;
return BISO_SUCCESS;
}
ULONG BISO_GetDate
(
IN CONST BISO_READ_S *pstRead,
IN BISO_DATE_TYPE_E enType,
OUT BISO_DATE_S *pstDate
)
{
CONST CHAR *pcDate = NULL;
BISO_PVD_S *pstPVD = NULL;
if ((NULL == pstRead) || (enType >= BISO_DATE_TYPE_BUTT) || (NULL == pstDate))
{
BISO_DIAG("Invalid param %p %d %p.", pstRead, enType, pstDate);
return BISO_ERR_INVALID_PARAM;
}
BISO_CHECK_READ_HANDLE(pstRead);
pstPVD = ((BISO_PARSER_S *)pstRead)->pstPVD;
switch (enType)
{
case BISO_DATE_TYPE_CREATE:
{
pcDate = pstPVD->szCreationDate;
break;
}
case BISO_DATE_TYPE_MODIFY:
{
pcDate = pstPVD->szModifyDate;
break;
}
case BISO_DATE_TYPE_EXPIRATION:
{
pcDate = pstPVD->szExpirationDate;
break;
}
case BISO_DATE_TYPE_EFFECTIVE:
{
pcDate = pstPVD->szEffectiveDate;
break;
}
default :
{
return BISO_ERR_INVALID_PARAM;
}
}
return BISO_9660_ParseDate84261(pcDate, pstDate);
}
/* 获取Rock Ridge扩展的Version 0: 没有使用Rock Ridge扩展 具体版本号: 一般都是1 */
UINT BISO_GetRockRidgeVer(IN CONST BISO_READ_S *pstRead)
{
if ((NULL == pstRead) || (BOOL_TRUE != BISO_IS_READ_HANDLE_VALID(pstRead)))
{
return 0;
}
return ((BISO_PARSER_S *)pstRead)->ucRRIPVersion;
}
/* 获取Joliet扩展的Level */
UINT BISO_GetJolietLevel(IN CONST BISO_READ_S *pstRead)
{
BISO_PARSER_S *pstParser = NULL;
if ((NULL == pstRead) || (BOOL_TRUE != BISO_IS_READ_HANDLE_VALID(pstRead)))
{
return 0;
}
pstParser = (BISO_PARSER_S *)pstRead;
if (NULL == pstParser->pstSVD)
{
return 0;
}
return BISO_JOLIET_GetLevel(pstParser->pstSVD->aucEscape);
}
BISO_HANDLE BISO_GetRoot(IN CONST BISO_READ_S *pstRead)
{
BISO_PARSER_S *pstParser = (BISO_PARSER_S *)pstRead;
if (NULL == pstParser)
{
return NULL;
}
return (BISO_HANDLE)(&pstParser->stDirTree);
}
ULONG BISO_GetFileNodeByHdl
(
IN BISO_HANDLE hFileHdl,
OUT BISO_FILE_NODE_S *pstFileNode
)
{
BISO_POSIX_INFO_S *pstPosix = NULL;
BISO_DIR_TREE_S *pstDirTree = (BISO_DIR_TREE_S *)hFileHdl;
if ((NULL == pstDirTree) || (NULL == pstFileNode))
{
return BISO_ERR_NULL_PTR;
}
pstPosix = pstDirTree->pstPosixInfo;
/* 设置类型 */
BISO_SET_FLAG(pstFileNode, pstDirTree);
/* 设置名称 */
scnprintf(pstFileNode->szName, sizeof(pstFileNode->szName), "%s", pstDirTree->szName);
/* 设置连接路径 */
if (BOOL_TRUE == BISO_DIR_TREE_IS_SYMLINK(pstDirTree))
{
scnprintf(pstFileNode->szLinkTgt, sizeof(pstFileNode->szLinkTgt), "%s", pstPosix->pcLinkSrc);
}
pstFileNode->ui64FileSize = pstDirTree->uiSize;
pstFileNode->ui64Seek = (UINT64)((UINT64)pstDirTree->uiExtent * BISO_BLOCK_SIZE);
pstFileNode->hParent = (BISO_HANDLE)(pstDirTree->pstParent);
pstFileNode->hCurrent = hFileHdl;
return BISO_SUCCESS;
}
ULONG BISO_GetFileNodeByName
(
IN CONST BISO_READ_S *pstRead,
IN CONST CHAR *pcFullPath,
IN UCHAR ucFollowLink,
OUT BISO_FILE_NODE_S *pstFileNode
)
{
UINT i = 0;
UINT uiDirNum = 0;
UINT auiDirPos[32];
USHORT usPos = 0;
USHORT usLen = 0;
CHAR szDirName[1024];
BISO_DIR_TREE_S *pstCurDir = NULL;
BISO_DIR_TREE_S *pstRootDir = NULL;
BISO_DIR_TREE_S *pstFileList = NULL;
BISO_PARSER_S *pstParser = (BISO_PARSER_S *)pstRead;
if ((NULL == pstRead) || (NULL == pcFullPath) || (NULL == pstFileNode))
{
return BISO_ERR_NULL_PTR;
}
if ('/' == pcFullPath[0])
{
return BISO_ERR_FAILED;
}
pstRootDir = &(pstParser->stDirTree);
pstCurDir = pstRootDir->pstChild;
if ((0 == pcFullPath[0]) || ((1 == strlen(pcFullPath)) && ('/' == pcFullPath[0])))
{
/* 出参赋值 */
memset(pstFileNode, 0, sizeof(BISO_FILE_NODE_S));
BISO_SET_FLAG(pstFileNode, pstCurDir);
scnprintf(pstFileNode->szName, sizeof(pstFileNode->szName), "%s", pstCurDir->szName);
pstFileNode->hParent = 0;
pstFileNode->hCurrent = (BISO_HANDLE)(pstRootDir);
return BISO_SUCCESS;
}
if ((1 == uiDirNum) && (NULL != pstRootDir))
{
pstFileList = pstRootDir->pstFileList;
pstCurDir = pstFileList;
while (pstCurDir)
{
if (0 == BISO_PATH_STRCMP(pstCurDir->szName, pcFullPath))
{
goto FOUND;
}
pstCurDir = pstCurDir->pstNext;
}
}
/* 先将目录分解开 */
if (BISO_SUCCESS != BISO_UTIL_PathSplit(pcFullPath, &uiDirNum, auiDirPos))
{
BISO_DIAG("Failed to split path %s", pcFullPath);
return BISO_ERR_FAILED;
}
/* 依次查找每一级目录 */
if (pstRootDir)
{
pstCurDir = pstRootDir->pstChild;
}
for (i = 0; (i < uiDirNum) && (NULL != pstRootDir) && (NULL != pstCurDir); i++)
{
usPos = auiDirPos[i] >> 16;
usLen = auiDirPos[i] & 0xFF;
memcpy(szDirName, pcFullPath + usPos, usLen);
szDirName[usLen] = 0;
pstCurDir = pstRootDir->pstChild;
pstFileList = pstRootDir->pstFileList;
/* 先查找目录 */
while (pstCurDir)
{
if (0 == BISO_PATH_STRCMP(pstCurDir->szName, szDirName))
{
pstRootDir = pstCurDir;
break;
}
pstCurDir = pstCurDir->pstNext;
}
/* 再查找文件 */
if (NULL == pstCurDir)
{
pstCurDir = pstFileList;
while (pstCurDir)
{
if (0 == BISO_PATH_STRCMP(pstCurDir->szName, szDirName))
{
break;
}
pstCurDir = pstCurDir->pstNext;
}
}
if (NULL == pstCurDir)
{
return BISO_ERR_FAILED;
}
/* 如果是符号链接则尝试找对应的实际文件 */
if ((ucFollowLink > 0) && (BOOL_TRUE == BISO_DIR_TREE_IS_SYMLINK(pstCurDir)))
{
pstCurDir = BISO_UTIL_FindLinkTgt(pstCurDir);
}
/* 如果是文件(或者是非法链接)的话一定是最后一级 */
if ((NULL == pstCurDir->pstDirStat) && (i + 1 != uiDirNum))
{
return BISO_ERR_FAILED;
}
}
FOUND:
if (NULL == pstCurDir)
{
return BISO_ERR_FAILED;
}
else
{
/* 出参赋值 */
memset(pstFileNode, 0, sizeof(BISO_FILE_NODE_S));
BISO_SET_FLAG(pstFileNode, pstCurDir);
scnprintf(pstFileNode->szName, sizeof(pstFileNode->szName), "%s", pstCurDir->szName);
if (BOOL_TRUE == BISO_DIR_TREE_IS_SYMLINK(pstCurDir))
{
scnprintf(pstFileNode->szLinkTgt, sizeof(pstFileNode->szLinkTgt), "%s",
pstCurDir->pstPosixInfo->pcLinkSrc);
}
pstFileNode->ui64FileSize = pstCurDir->uiSize;
pstFileNode->ui64DirRecOffet = pstCurDir->ui64FileRecordOffset;
pstFileNode->ui64Seek = (UINT64)((UINT64)pstCurDir->uiExtent * BISO_BLOCK_SIZE);
pstFileNode->hParent = (BISO_HANDLE)(pstCurDir->pstParent);
pstFileNode->hCurrent = (BISO_HANDLE)(pstCurDir);
return BISO_SUCCESS;
}
}
ULONG BISO_GetFileNodeByExtent
(
IN CONST BISO_READ_S *pstRead,
IN UINT uiExtent,
OUT BISO_FILE_NODE_S *pstFileNode
)
{
BOOL_T bFind = BOOL_FALSE;
BISO_QUEUE_S *pstQueue = NULL;
BISO_DIR_TREE_S *pstRootDir = NULL;
BISO_DIR_TREE_S *pstDirTree = NULL;
BISO_DIR_TREE_S *pstCurDir = NULL;
BISO_DIR_TREE_S *pstFileList = NULL;
BISO_PARSER_S *pstParser = (BISO_PARSER_S *)pstRead;
if ((NULL == pstRead) || (NULL == pstFileNode))
{
return BISO_ERR_NULL_PTR;
}
pstRootDir = &(pstParser->stDirTree);
/* 创建堆栈,同时ROOT入栈 */
pstQueue = BISO_QUEUE_Create();
BISO_QUEUE_Push(pstQueue, pstRootDir);
while (NULL != (pstDirTree = (BISO_DIR_TREE_S *)BISO_QUEUE_PopHead(pstQueue)))
{
pstCurDir = pstDirTree->pstChild;
while (pstCurDir)
{
BISO_QUEUE_Push(pstQueue, pstCurDir);
pstCurDir = pstCurDir->pstNext;
}
pstFileList = pstDirTree->pstFileList;
pstCurDir = pstFileList;
while (pstCurDir)
{
if (uiExtent == pstCurDir->uiExtent)
{
while (BISO_QUEUE_PopHead(pstQueue))
{
bFind = BOOL_TRUE;
}
break;
}
pstCurDir = pstCurDir->pstNext;
}
}
BISO_QUEUE_Destroy(pstQueue);
if (BOOL_TRUE != bFind)
{
return BISO_ERR_FAILED;
}
else
{
/* 出参赋值 */
memset(pstFileNode, 0, sizeof(BISO_FILE_NODE_S));
BISO_SET_FLAG(pstFileNode, pstCurDir);
scnprintf(pstFileNode->szName, sizeof(pstFileNode->szName), "%s", pstCurDir->szName);
if (BOOL_TRUE == BISO_DIR_TREE_IS_SYMLINK(pstCurDir))
{
scnprintf(pstFileNode->szLinkTgt, sizeof(pstFileNode->szLinkTgt), "%s",
pstCurDir->pstPosixInfo->pcLinkSrc);
}
pstFileNode->ui64FileSize = pstCurDir->uiSize;
pstFileNode->ui64DirRecOffet = pstCurDir->ui64FileRecordOffset;
pstFileNode->ui64Seek = (UINT64)((UINT64)pstCurDir->uiExtent * BISO_BLOCK_SIZE);
pstFileNode->hParent = (BISO_HANDLE)(pstCurDir->pstParent);
pstFileNode->hCurrent = (BISO_HANDLE)(pstCurDir);
return BISO_SUCCESS;
}
}
ULONG BISO_GetSVDFileNodeByExtent
(
IN CONST BISO_READ_S *pstRead,
IN UINT uiExtent,
OUT BISO_SVD_FILE_NODE_S *pstFileNode
)
{
BOOL_T bFind = BOOL_FALSE;
BISO_QUEUE_S *pstQueue = NULL;
BISO_SVD_DIR_TREE_S *pstRootDir = NULL;
BISO_SVD_DIR_TREE_S *pstDirTree = NULL;
BISO_SVD_DIR_TREE_S *pstCurDir = NULL;
BISO_SVD_DIR_TREE_S *pstFileList = NULL;
BISO_PARSER_S *pstParser = (BISO_PARSER_S *)pstRead;
if ((NULL == pstRead) || (NULL == pstFileNode))
{
return BISO_ERR_NULL_PTR;
}
pstRootDir = &(pstParser->stSVDDirTree);
/* 创建堆栈,同时ROOT入栈 */
pstQueue = BISO_QUEUE_Create();
BISO_QUEUE_Push(pstQueue, pstRootDir);
while (NULL != (pstDirTree = (BISO_SVD_DIR_TREE_S *)BISO_QUEUE_PopHead(pstQueue)))
{
pstCurDir = pstDirTree->pstChild;
while (pstCurDir)
{
BISO_QUEUE_Push(pstQueue, pstCurDir);
pstCurDir = pstCurDir->pstNext;
}
pstFileList = pstDirTree->pstFileList;
pstCurDir = pstFileList;
while (pstCurDir)
{
if (uiExtent == pstCurDir->uiExtent)
{
while (BISO_QUEUE_PopHead(pstQueue))
{
bFind = BOOL_TRUE;
}
break;
}
pstCurDir = pstCurDir->pstNext;
}
}
BISO_QUEUE_Destroy(pstQueue);
if (BOOL_TRUE != bFind)
{
return BISO_ERR_FAILED;
}
else
{
/* 出参赋值 */
memset(pstFileNode, 0, sizeof(BISO_SVD_FILE_NODE_S));
pstFileNode->ui64FileSize = pstCurDir->uiSize;
pstFileNode->ui64DirRecOffet = pstCurDir->ui64FileRecordOffset;
pstFileNode->ui64Seek = (UINT64)((UINT64)pstCurDir->uiExtent * BISO_BLOCK_SIZE);
return BISO_SUCCESS;
}
}
ULONG BISO_GetFileTree
(
IN BISO_HANDLE hTopDir,
IN UINT uiFlag,
OUT BISO_HANDLE *phFileTree,
OUT UINT *puiNodeNum
)
{
BISO_DIR_STAT_S *pstDirStat = NULL;
BISO_DIR_TREE_S *pstCurNode = NULL;
BISO_DIR_TREE_S *pstDirTree = (BISO_DIR_TREE_S *)hTopDir;
if ((NULL == pstDirTree) || (NULL == phFileTree) || (NULL == puiNodeNum))
{
return BISO_ERR_NULL_PTR;
}
pstDirStat = pstDirTree->pstDirStat;
if (NULL == pstDirStat)
{
return BISO_ERR_INVALID_PARAM;
}
*puiNodeNum = pstDirStat->uiCurDirNum + pstDirStat->uiCurFileNum + pstDirStat->uiCurLinkNum;
switch (uiFlag)
{
case BISO_TREE_FLAG_CUR:
{
pstCurNode = pstDirTree->pstChild;
while (NULL != pstCurNode)
{
*phFileTree++ = (BISO_HANDLE)pstCurNode;
pstCurNode = pstCurNode->pstNext;
}
pstCurNode = pstDirTree->pstFileList;
while (NULL != pstCurNode)
{
*phFileTree++ = (BISO_HANDLE)pstCurNode;
pstCurNode = pstCurNode->pstNext;
}
break;
}
case BISO_TREE_FLAG_DFS:
{
break;
}
case BISO_TREE_FLAG_BFS:
{
break;
}
default :
{
return BISO_ERR_INVALID_PARAM;
}
}
return BISO_SUCCESS;
}
ULONG BISO_GetDirStat
(
IN BISO_HANDLE hTopDir,
OUT BISO_DIR_STAT_S *pstDirStat
)
{
BISO_DIR_TREE_S *pstDirTree = NULL;
if ((NULL == hTopDir) || (NULL == pstDirStat))
{
return BISO_ERR_NULL_PTR;
}
pstDirTree = (BISO_DIR_TREE_S *)hTopDir;
if (NULL == pstDirTree->pstDirStat)
{
return BISO_ERR_INVALID_PARAM;
}
memcpy(pstDirStat, pstDirTree->pstDirStat, sizeof(BISO_DIR_STAT_S));
return BISO_SUCCESS;
}
VOID BISO_Fill733(IN UINT uiData, OUT VOID *pBuf)
{
UINT uiSwap = 0;
UINT *puiData = (UINT *)pBuf;
uiSwap |= (uiData & 0xFF) << 24;
uiSwap |= ((uiData >> 8) & 0xFF) << 16;
uiSwap |= ((uiData >> 16) & 0xFF) << 8;
uiSwap |= (uiData >> 24) & 0xFF;
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
puiData[0] = uiData;
puiData[1] = uiSwap;
#else
puiData[0] = uiSwap;
puiData[1] = uiData;
#endif
}
UINT BISO_Get733(IN CONST VOID *pBuf)
{
UINT *puiData = (UINT *)pBuf;
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
return puiData[0];
#else
return puiData[1];
#endif
}
UINT BISO_GetFileOccupySize(IN UINT uiRawSize)
{
UINT uiAlign = uiRawSize % BISO_SECTOR_SIZE;
if (0 == uiAlign)
{
return uiRawSize;
}
else
{
return uiRawSize + BISO_SECTOR_SIZE - uiAlign;
}
}
UINT BISO_GetBootEntryNum(IN CONST BISO_READ_S *pstRead)
{
return BISO_ELTORITO_GetBootEntryNum((CONST BISO_PARSER_S *)pstRead);
}
VOID BISO_DumpFileTree(IN CONST BISO_READ_S *pstRead)
{
BISO_PARSER_S *pstParser = (BISO_PARSER_S *)pstRead;
if (NULL != pstParser)
{
BISO_DUMP_ShowFileTree(1, pstParser->stDirTree.pstChild);
BISO_DUMP_ShowFileTree(1, pstParser->stDirTree.pstFileList);
}
}