]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - VtoyTool/BabyISO/biso_eltorito.c
Support ext4 fs with checksum seed feature.
[Ventoy.git] / VtoyTool / BabyISO / biso_eltorito.c
1 /******************************************************************************
2 * bios_eltorito.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
27 ULONG BISO_ELTORITO_ReadBootInfo
28 (
29 IN BISO_FILE_S *pstFile,
30 OUT BISO_PARSER_S *pstParser
31 )
32 {
33 USHORT i;
34 UINT uiReadLen = 0;
35 UINT64 ui64Seek = 0;
36 UCHAR aucBuf[BISO_SECTOR_SIZE];
37 BISO_MBUF_S stMBuf;
38 BISO_TORITO_SECHDR_ENTRY_S *pstSecHdr = NULL;
39 BISO_TORITO_SECTION_ENTRY_S *pstSection = NULL;
40
41 DBGASSERT(NULL != pstFile);
42 DBGASSERT(NULL != pstParser);
43
44 if (NULL == pstParser->pstBVD)
45 {
46 return BISO_SUCCESS;
47 }
48
49 memset(&stMBuf, 0, sizeof(stMBuf));
50 ui64Seek = (UINT64)pstParser->pstBVD->uiBootCatlogStart * BISO_SECTOR_SIZE;
51 BISO_PLAT_SeekFile(pstFile, ui64Seek, SEEK_SET);
52
53 /* 先读取1个逻辑扇区的内容 */
54 uiReadLen = (UINT)BISO_PLAT_ReadFile(pstFile, 1, BISO_SECTOR_SIZE, aucBuf);
55 if (uiReadLen != BISO_SECTOR_SIZE)
56 {
57 BISO_DIAG("Read len %u buf len %u.", uiReadLen, BISO_SECTOR_SIZE);
58 return BISO_ERR_READ_FILE;
59 }
60
61 /* 前两条Entry固定是Validation和Initial */
62 pstSecHdr = (BISO_TORITO_SECHDR_ENTRY_S *)(aucBuf + 2 * BISO_ELTORITO_ENTRY_LEN);
63 pstSection = (BISO_TORITO_SECTION_ENTRY_S *)pstSecHdr;
64
65 while ((0x90 == pstSecHdr->ucFlag) || (0x91 == pstSecHdr->ucFlag))
66 {
67 pstSecHdr = (BISO_TORITO_SECHDR_ENTRY_S *)pstSection;
68 BISO_ELTORITO_ENTRY_STEP(pstSection, pstFile, aucBuf, stMBuf);
69
70 for (i = 0; i < pstSecHdr->usSecEntryNum; )
71 {
72 /*
73 * Section Entry和Extension Entry都是由ucFlag的Bit5决定是否结束
74 * 因此这里全部都用Section Entry的结构做判断
75 */
76 if (0 == (pstSection->ucFlag & 0x10))
77 {
78 i++;
79 }
80
81 BISO_ELTORITO_ENTRY_STEP(pstSection, pstFile, aucBuf, stMBuf);
82 }
83
84 if (0x91 == pstSecHdr->ucFlag) /* 91代表最后一个 */
85 {
86 break;
87 }
88 }
89
90 if ((UCHAR *)pstSection > aucBuf)
91 {
92 (VOID)BISO_MBUF_Append(&stMBuf, (UCHAR *)pstSection - aucBuf, aucBuf);
93 }
94
95 /* 保存到全局结构中 */
96 pstParser->uiElToritoLen = stMBuf.uiTotDataSize;
97 pstParser->pucElToritoEntry = (UCHAR *)BISO_MALLOC(pstParser->uiElToritoLen);
98 if (NULL == pstParser->pucElToritoEntry)
99 {
100 BISO_MBUF_Free(&stMBuf);
101 return BISO_ERR_ALLOC_MEM;
102 }
103
104 BISO_MBUF_CopyToBuf(&stMBuf, pstParser->pucElToritoEntry);
105 BISO_MBUF_Free(&stMBuf);
106 return BISO_SUCCESS;
107 }
108
109 VOID BISO_ELTORITO_Dump(IN CONST BISO_PARSER_S *pstParser)
110 {
111 BISO_DUMP("uiElToritoLen=%u\n", pstParser->uiElToritoLen);
112 }
113
114
115 UINT BISO_ELTORITO_GetBootEntryNum(IN CONST BISO_PARSER_S *pstParser)
116 {
117 UINT uiRet = 0;
118 UINT uiEntryNum = 0;
119 UCHAR *pucData = NULL;
120 BISO_TORITO_VALIDATION_ENTRY_S *pstValidation = NULL;
121 BISO_TORITO_INITIAL_ENTRY_S *pstInitial = NULL;
122
123 if (NULL == pstParser->pucElToritoEntry)
124 {
125 return 0;
126 }
127
128 uiEntryNum = pstParser->uiElToritoLen / BISO_ELTORITO_ENTRY_LEN;
129 pstValidation = (BISO_TORITO_VALIDATION_ENTRY_S *)pstParser->pucElToritoEntry;
130 pstInitial = (BISO_TORITO_INITIAL_ENTRY_S *)(pstValidation + 1);
131
132 if (pstInitial->ucBootId == 0x88)
133 {
134 uiRet++;
135 }
136
137 pucData = pstParser->pucElToritoEntry + 2 * BISO_ELTORITO_ENTRY_LEN;
138 uiEntryNum-= 2;
139
140 while (uiEntryNum > 0)
141 {
142 if ((0x90 == pucData[0]) || (0x91 == pucData[0]))
143 {
144 }
145 else if (0x44 == pucData[0])
146 {
147 }
148 else
149 {
150 if (((BISO_TORITO_SECTION_ENTRY_S *)pucData)->ucBootId == 0x88)
151 {
152 uiRet++;
153 }
154 }
155 pucData += BISO_ELTORITO_ENTRY_LEN;
156 uiEntryNum--;
157 }
158
159 return uiRet;
160 }
161