/****************************************************************************** * bios_eltorito.c * * Copyright (c) 2020, longpanda * * 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 . * */ #include "biso.h" #include "biso_list.h" #include "biso_util.h" #include "biso_9660.h" #include "biso_eltorito.h" ULONG BISO_ELTORITO_ReadBootInfo ( IN BISO_FILE_S *pstFile, OUT BISO_PARSER_S *pstParser ) { USHORT i; UINT uiReadLen = 0; UINT64 ui64Seek = 0; UCHAR aucBuf[BISO_SECTOR_SIZE]; BISO_MBUF_S stMBuf; BISO_TORITO_SECHDR_ENTRY_S *pstSecHdr = NULL; BISO_TORITO_SECTION_ENTRY_S *pstSection = NULL; DBGASSERT(NULL != pstFile); DBGASSERT(NULL != pstParser); if (NULL == pstParser->pstBVD) { return BISO_SUCCESS; } memset(&stMBuf, 0, sizeof(stMBuf)); ui64Seek = (UINT64)pstParser->pstBVD->uiBootCatlogStart * BISO_SECTOR_SIZE; BISO_PLAT_SeekFile(pstFile, ui64Seek, SEEK_SET); /* 先读取1个逻辑扇区的内容 */ uiReadLen = (UINT)BISO_PLAT_ReadFile(pstFile, 1, BISO_SECTOR_SIZE, aucBuf); if (uiReadLen != BISO_SECTOR_SIZE) { BISO_DIAG("Read len %u buf len %u.", uiReadLen, BISO_SECTOR_SIZE); return BISO_ERR_READ_FILE; } /* 前两条Entry固定是Validation和Initial */ pstSecHdr = (BISO_TORITO_SECHDR_ENTRY_S *)(aucBuf + 2 * BISO_ELTORITO_ENTRY_LEN); pstSection = (BISO_TORITO_SECTION_ENTRY_S *)pstSecHdr; while ((0x90 == pstSecHdr->ucFlag) || (0x91 == pstSecHdr->ucFlag)) { pstSecHdr = (BISO_TORITO_SECHDR_ENTRY_S *)pstSection; BISO_ELTORITO_ENTRY_STEP(pstSection, pstFile, aucBuf, stMBuf); for (i = 0; i < pstSecHdr->usSecEntryNum; ) { /* * Section Entry和Extension Entry都是由ucFlag的Bit5决定是否结束 * 因此这里全部都用Section Entry的结构做判断 */ if (0 == (pstSection->ucFlag & 0x10)) { i++; } BISO_ELTORITO_ENTRY_STEP(pstSection, pstFile, aucBuf, stMBuf); } if (0x91 == pstSecHdr->ucFlag) /* 91代表最后一个 */ { break; } } if ((UCHAR *)pstSection > aucBuf) { (VOID)BISO_MBUF_Append(&stMBuf, (UCHAR *)pstSection - aucBuf, aucBuf); } /* 保存到全局结构中 */ pstParser->uiElToritoLen = stMBuf.uiTotDataSize; pstParser->pucElToritoEntry = (UCHAR *)BISO_MALLOC(pstParser->uiElToritoLen); if (NULL == pstParser->pucElToritoEntry) { BISO_MBUF_Free(&stMBuf); return BISO_ERR_ALLOC_MEM; } BISO_MBUF_CopyToBuf(&stMBuf, pstParser->pucElToritoEntry); BISO_MBUF_Free(&stMBuf); return BISO_SUCCESS; } VOID BISO_ELTORITO_Dump(IN CONST BISO_PARSER_S *pstParser) { BISO_DUMP("uiElToritoLen=%u\n", pstParser->uiElToritoLen); } UINT BISO_ELTORITO_GetBootEntryNum(IN CONST BISO_PARSER_S *pstParser) { UINT uiRet = 0; UINT uiEntryNum = 0; UCHAR *pucData = NULL; BISO_TORITO_VALIDATION_ENTRY_S *pstValidation = NULL; BISO_TORITO_INITIAL_ENTRY_S *pstInitial = NULL; if (NULL == pstParser->pucElToritoEntry) { return 0; } uiEntryNum = pstParser->uiElToritoLen / BISO_ELTORITO_ENTRY_LEN; pstValidation = (BISO_TORITO_VALIDATION_ENTRY_S *)pstParser->pucElToritoEntry; pstInitial = (BISO_TORITO_INITIAL_ENTRY_S *)(pstValidation + 1); if (pstInitial->ucBootId == 0x88) { uiRet++; } pucData = pstParser->pucElToritoEntry + 2 * BISO_ELTORITO_ENTRY_LEN; uiEntryNum-= 2; while (uiEntryNum > 0) { if ((0x90 == pucData[0]) || (0x91 == pucData[0])) { } else if (0x44 == pucData[0]) { } else { if (((BISO_TORITO_SECTION_ENTRY_S *)pucData)->ucBootId == 0x88) { uiRet++; } } pucData += BISO_ELTORITO_ENTRY_LEN; uiEntryNum--; } return uiRet; }