]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - VtoyTool/BabyISO/biso_rockridge.c
Support ext4 fs with checksum seed feature.
[Ventoy.git] / VtoyTool / BabyISO / biso_rockridge.c
1 /******************************************************************************
2 * biso_rockridge.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
22 #include "biso.h"
23 #include "biso_list.h"
24 #include "biso_util.h"
25 #include "biso_9660.h"
26 #include "biso_dump.h"
27 #include "biso_rockridge.h"
28
29 /* Rock Ridge扩展处理函数数组, NULL表示暂时不处理这类表项 */
30 STATIC BISO_RRIP_PARSE_ENTRY_CB_S g_astBISO_RRIP_ParseFunc[] =
31 {
32 { "CE", NULL },
33 { "PD", NULL },
34 { "SP", NULL },
35 { "ST", NULL },
36 { "ER", NULL },
37 { "ES", NULL },
38 { "RR", NULL },
39 { "PX", BISO_RRIP_GetPXInfo },
40 { "PN", BISO_RRIP_GetPNInfo },
41 { "SL", BISO_RRIP_GetSLInfo },
42 { "NM", BISO_RRIP_GetNMInfo },
43 { "CL", NULL },
44 { "PL", NULL },
45 { "RE", NULL },
46 { "TF", BISO_RRIP_GetTFInfo },
47 { "SF", NULL },
48 };
49
50 STATIC VOID BISO_RRIP_AddLinkBuf
51 (
52 IN CHAR *pcBuf,
53 IN UINT uiBufLen,
54 INOUT BISO_POSIX_INFO_S *pstPosixInfo
55 )
56 {
57 CHAR *pcNewBuf = NULL;
58
59 DBGASSERT(NULL != pstPosixInfo);
60 DBGASSERT(NULL != pcBuf);
61
62 /*
63 * 这里采用的是最简单的每次重新申请大内存保存老数据和新数据的方式
64 * 实际上效率是比较低的,但是由于普通ISO文件中link类型本身就不多
65 * 而有连续多条SL表项的就更少了,所以这里只是简单实现功能,没有特别考虑效率
66 */
67
68 /* 申请一个新Buf用于保存原有的数据和这次的新数据 */
69 pcNewBuf = (CHAR *)BISO_ZALLOC(uiBufLen + pstPosixInfo->uiLinkLen);
70 if (NULL == pcNewBuf)
71 {
72 return;
73 }
74
75 if (NULL == pstPosixInfo->pcLinkSrc)
76 {
77 memcpy(pcNewBuf, pcBuf, uiBufLen);
78 }
79 else
80 {
81 /* 分别保存新老数据,同时把老的Buf释放掉 */
82 memcpy(pcNewBuf, pstPosixInfo->pcLinkSrc, pstPosixInfo->uiLinkLen);
83 memcpy(pcNewBuf + pstPosixInfo->uiLinkLen, pcBuf, uiBufLen);
84 BISO_FREE(pstPosixInfo->pcLinkSrc);
85 }
86
87 /* 更新数据Buf */
88 pstPosixInfo->pcLinkSrc = pcNewBuf;
89 pstPosixInfo->uiLinkLen += uiBufLen;
90 }
91
92 STATIC UINT BISO_RRIP_CalcLinkLen
93 (
94 IN CONST CHAR *pcComponet,
95 IN UINT uiComponetLen
96 )
97 {
98 UINT uiBufLen = 0;
99 UINT uiOffset = 0;
100 UINT uiTotLen = 0;
101 BISO_RRIP_SL_COMPONENT_S *pstComp = NULL;
102
103 DBGASSERT(NULL != pcComponet);
104 DBGASSERT(uiComponetLen > 0);
105
106 /* 拼接出链接的源路径 */
107 while (uiOffset < uiComponetLen)
108 {
109 uiBufLen = 0;
110 pstComp = (BISO_RRIP_SL_COMPONENT_S *)(pcComponet + uiOffset);
111
112 if (BOOL_TRUE == BISO_SLCOMP_IS_ROOT(pstComp->ucFlags))
113 {
114 /* ROOT不需处理,后面会添加/ */
115 }
116 else if (BOOL_TRUE == BISO_SLCOMP_IS_CURRENT(pstComp->ucFlags))
117 {
118 uiBufLen = 1; /* . */
119 }
120 else if (BOOL_TRUE == BISO_SLCOMP_IS_PARENT(pstComp->ucFlags))
121 {
122 uiBufLen = 2; /* .. */
123 }
124 else
125 {
126 uiBufLen = pstComp->ucLength;
127 }
128
129 /* ucLength不包括头两个字节 */
130 uiOffset += pstComp->ucLength + 2;
131
132 /*
133 * 如果是link路径的一部分完结,则需要在后面加上'/',否则不加.
134 * 不加的情况有两种: 1是整体已经完了 2是路径的一部分还没有完整
135 * 比如说链接的位置是 /root/xxxx/a.txt 而xxxx可能非常长(200+个字符)
136 * 那么此时光xxxx的部分可能就需要两个Componet部分才能表达完,而这两个
137 * 之间是不能加反斜杠的.
138 */
139 if ((uiOffset < uiComponetLen) && (BOOL_TRUE != BISO_SLCOMP_IS_CONTINUE(pstComp->ucFlags)))
140 {
141 uiBufLen++;
142 }
143
144 uiTotLen += uiBufLen;
145 }
146
147 return uiTotLen;
148 }
149
150 STATIC UINT BISO_RRIP_GetPartLink
151 (
152 IN CONST BISO_RRIP_SL_COMPONENT_S *pstComponent,
153 IN UINT uiBufSize,
154 OUT CHAR *pcBuf
155 )
156 {
157 UINT uiBufLen = 0;
158
159 DBGASSERT(NULL != pstComponent);
160 DBGASSERT(NULL != pcBuf);
161
162 if (BOOL_TRUE == BISO_SLCOMP_IS_ROOT(pstComponent->ucFlags))
163 {
164 /* ROOT不需处理,后面会添加/ */
165 }
166 else if (BOOL_TRUE == BISO_SLCOMP_IS_CURRENT(pstComponent->ucFlags))
167 {
168 scnprintf(pcBuf, uiBufSize, ".");
169 uiBufLen = 1;
170 }
171 else if (BOOL_TRUE == BISO_SLCOMP_IS_PARENT(pstComponent->ucFlags))
172 {
173 scnprintf(pcBuf, uiBufSize, "..");
174 uiBufLen = 2;
175 }
176 else
177 {
178 memcpy(pcBuf, pstComponent->aucData, pstComponent->ucLength);
179 uiBufLen = pstComponent->ucLength;
180 }
181
182 return uiBufLen;
183 }
184
185 STATIC BOOL_T BISO_RRIP_IsThisType(IN BISO_SUSP_ENTRY_S *pstEntry, IN CONST CHAR *pcType)
186 {
187 if (NULL == pstEntry || NULL == pcType)
188 {
189 return BOOL_FALSE;
190 }
191
192 if ((pstEntry->cSignature1 == pcType[0]) && (pstEntry->cSignature2 == pcType[1]))
193 {
194 return BOOL_TRUE;
195 }
196
197 return BOOL_FALSE;
198 }
199
200 STATIC UCHAR * BISO_RRIP_GetSysUseArea
201 (
202 IN BISO_FILE_S *pstFile,
203 IN UCHAR *pucSysUseField,
204 IN UINT uiSysUseFieldLen,
205 OUT UINT *puiAreaSize
206 )
207 {
208 UINT uiCELen = 0;
209 UINT uiCurPos = 0;
210 UINT uiReadLen = 0;
211 UINT64 ui64Seek = 0;
212 UCHAR *pucSysUseArea = NULL;
213 BISO_SUSP_ENTRY_S *pstEntry = NULL;
214 BISO_SUSP_ENTRY_CE_S *pstCEEntry = NULL;
215
216 DBGASSERT(NULL != pstFile);
217 DBGASSERT(NULL != pucSysUseField);
218 DBGASSERT(NULL != puiAreaSize);
219
220 /*
221 * 虽然Rock Ridge扩展标准中允许整个System Use Area中有多个CE表项来扩展,
222 * 但是由于一条CE表项可以扩展的长度就足够了(32bit) 所以这里我感觉正常情况下
223 * 没有必要使用多个CE表项扩展空间。因此这里只支持1条CE表项的情况。
224 */
225
226 /* 遍历当前System Use Field, 标准规定剩余空间小于4字节,则后面的忽略 */
227 for (uiCurPos = 0; uiCurPos + 4 < uiSysUseFieldLen; uiCurPos += pstEntry->ucEntryLen)
228 {
229 pstEntry = (BISO_SUSP_ENTRY_S *)(pucSysUseField + uiCurPos);
230
231 /* 找到1个CE表项就停止,这里默认CE表项是最后一条表项 */
232 if (BOOL_TRUE == BISO_RRIP_IsThisType(pstEntry, "CE"))
233 {
234 pstCEEntry = (BISO_SUSP_ENTRY_CE_S *)pstEntry;
235 uiCELen = pstCEEntry->uiContinuationLen;
236 /* BISO_DUMP_ShowSUSPEntry(pstCEEntry); */
237 break;
238 }
239 }
240
241 /* 申请一块内存把这两部分合并起来 */
242 pucSysUseArea = (UCHAR *)BISO_MALLOC(uiCurPos + uiCELen);
243 if (NULL == pucSysUseArea)
244 {
245 return NULL;
246 }
247
248 /* 先拷贝System Use Field字段 */
249 memcpy(pucSysUseArea, pucSysUseField, uiCurPos);
250
251 /* 如果有CE表项则再同文件中读出CE部分的数据 */
252 if (NULL != pstCEEntry)
253 {
254 ui64Seek = (UINT64)pstCEEntry->uiBlockLoc * BISO_BLOCK_SIZE + pstCEEntry->uiByteOffset;
255 BISO_PLAT_SeekFile(pstFile, ui64Seek, SEEK_SET);
256 uiReadLen = (UINT)BISO_PLAT_ReadFile(pstFile, 1, uiCELen, pucSysUseArea + uiCurPos);
257 if (uiReadLen != uiCELen)
258 {
259 BISO_DIAG("Read len %u buf len %u.", uiReadLen, uiCELen);
260 BISO_FREE(pucSysUseArea);
261 return NULL;
262 }
263 }
264
265 *puiAreaSize = uiCurPos + uiCELen;
266 return pucSysUseArea;
267 }
268
269 VOID BISO_RRIP_GetPXInfo(IN VOID *pEntry, OUT BISO_DIR_TREE_S *pstDirTree)
270 {
271 BISO_POSIX_INFO_S *pstPosixInfo = NULL;
272 BISO_ROCK_RIDGE_ENTRY_PX_S *pstPXEntry = NULL;
273
274 DBGASSERT(NULL != pEntry);
275 DBGASSERT(NULL != pstDirTree);
276 DBGASSERT(NULL != pstDirTree->pstPosixInfo);
277
278 pstPXEntry = (BISO_ROCK_RIDGE_ENTRY_PX_S *)pEntry;
279 pstPosixInfo = pstDirTree->pstPosixInfo;
280
281 pstPosixInfo->uiPosixFileMode = pstPXEntry->uiPosixFileMode;
282 pstPosixInfo->uiPosixFileLink = pstPXEntry->uiPosixFileLink;
283 pstPosixInfo->uiPosixFileUserId = pstPXEntry->uiPosixFileUserId;
284 pstPosixInfo->uiPosixFileGroupId = pstPXEntry->uiPosixFileGroupId;
285 pstPosixInfo->uiPosixFileSNO = pstPXEntry->uiPosixFileSNO;
286 }
287
288 VOID BISO_RRIP_GetNMInfo(IN VOID *pEntry, OUT BISO_DIR_TREE_S *pstDirTree)
289 {
290 BISO_ROCK_RIDGE_ENTRY_NM_S *pstNMEntry = NULL;
291
292 DBGASSERT(NULL != pEntry);
293 DBGASSERT(NULL != pstDirTree);
294 DBGASSERT(NULL != pstDirTree->pstPosixInfo);
295
296 pstNMEntry = (BISO_ROCK_RIDGE_ENTRY_NM_S *)pEntry;
297
298 /* 如有NM表项就替换ISO9660文件名 */
299 if (BOOL_TRUE != pstDirTree->pstPosixInfo->bHasNMEntry)
300 {
301 pstDirTree->pstPosixInfo->bHasNMEntry = BOOL_TRUE;
302 memset(pstDirTree->szName, 0, sizeof(pstDirTree->szName));
303 pstDirTree->usNameLen = 0;
304 }
305
306 /*
307 * 拼接文件名, 有可能本函数会多次调用,多次拼接(文件名超长的情况)
308 * TODO: 是否需要关注字符编码???
309 */
310 strncat(pstDirTree->szName, pstNMEntry->szFileName, pstNMEntry->ucEntryLen - 5);
311 pstDirTree->usNameLen += pstNMEntry->ucEntryLen - 5;
312 }
313
314 VOID BISO_RRIP_GetTFInfo(IN VOID *pEntry, OUT BISO_DIR_TREE_S *pstDirTree)
315 {
316 UINT i;
317 UCHAR *pucCur = NULL;
318 BISO_DATE_915_S *pst915Date = NULL;
319 BISO_ROCK_RIDGE_ENTRY_TF_S *pstTFEntry = NULL;
320 BISO_DATE_S *apstDate[] =
321 {
322 &(pstDirTree->pstPosixInfo->stCreateTime),
323 &(pstDirTree->pstPosixInfo->stModifyTime),
324 &(pstDirTree->pstPosixInfo->stLastAccessTime),
325 &(pstDirTree->pstPosixInfo->stLastAttrChangeTime),
326 &(pstDirTree->pstPosixInfo->stLastBackupTime),
327 &(pstDirTree->pstPosixInfo->stExpirationTime),
328 &(pstDirTree->pstPosixInfo->stEffectiveTime)
329 };
330
331 DBGASSERT(NULL != pEntry);
332 DBGASSERT(NULL != pstDirTree);
333 DBGASSERT(NULL != pstDirTree->pstPosixInfo);
334
335 pstTFEntry = (BISO_ROCK_RIDGE_ENTRY_TF_S *)pEntry;
336 pucCur = pstTFEntry->aucTimeStamp;
337
338 for (i = 0; i < ARRAY_SIZE(apstDate); i++)
339 {
340 /* 比特位0说明该时间戳没有记录 */
341 if (0 == ((pstTFEntry->ucFlags >> i) & 0x1))
342 {
343 continue;
344 }
345
346 /* Bit7决定是按照哪种格式记录的 */
347 if ((pstTFEntry->ucFlags >> 7) & 0x1)
348 {
349 (VOID)BISO_9660_ParseDate84261((CHAR *)pucCur, apstDate[i]);
350 pucCur += 17;
351 }
352 else
353 {
354 pst915Date = (BISO_DATE_915_S *)pucCur;
355 pucCur += 7;
356
357 apstDate[i]->usYear = pst915Date->ucYear + 1900;
358 apstDate[i]->ucMonth = pst915Date->ucMonth;
359 apstDate[i]->ucDay = pst915Date->ucDay;
360 apstDate[i]->ucHour = pst915Date->ucHour;
361 apstDate[i]->ucMin = pst915Date->ucMin;
362 apstDate[i]->ucSecond = pst915Date->ucSec;
363 apstDate[i]->usMillSec = 0;
364 apstDate[i]->cZone = pst915Date->cTimeZone / 4;
365 }
366 }
367 }
368
369 VOID BISO_RRIP_GetPNInfo(IN VOID *pEntry, OUT BISO_DIR_TREE_S *pstDirTree)
370 {
371 BISO_ROCK_RIDGE_ENTRY_PN_S *pstPNEntry = NULL;
372
373 DBGASSERT(NULL != pEntry);
374 DBGASSERT(NULL != pstDirTree);
375 DBGASSERT(NULL != pstDirTree->pstPosixInfo);
376
377 pstPNEntry = (BISO_ROCK_RIDGE_ENTRY_PN_S *)pEntry;
378
379 pstDirTree->pstPosixInfo->ui64DevNum = ((UINT64)(pstPNEntry->uiDevNumHigh) << 32) | pstPNEntry->uiDevNumLow;
380 }
381
382 VOID BISO_RRIP_GetSLInfo(IN VOID *pEntry, OUT BISO_DIR_TREE_S *pstDirTree)
383 {
384 UINT uiBufLen = 0;
385 UINT uiOffset = 0;
386 UINT uiCurPos = 0;
387 UCHAR ucCompentLen = 0;
388 CHAR *pcFullLinkPath = NULL;
389 BISO_POSIX_INFO_S *pstPosixInfo = NULL;
390 BISO_ROCK_RIDGE_ENTRY_SL_S *pstSLEntry = NULL;
391 BISO_RRIP_SL_COMPONENT_S *pstComp = NULL;
392 CHAR szBuf[300]; /* 当前Length是用UCHAR存储的,一定不会超过300 */
393
394 DBGASSERT(NULL != pEntry);
395 DBGASSERT(NULL != pstDirTree);
396 DBGASSERT(NULL != pstDirTree->pstPosixInfo);
397
398 pstSLEntry = (BISO_ROCK_RIDGE_ENTRY_SL_S *)pEntry;
399 pstPosixInfo = pstDirTree->pstPosixInfo;
400 ucCompentLen = pstSLEntry->ucEntryLen - 5;
401
402 /*
403 * 把所有SL表项的Componet部分拼接起来,如果有连续几条SL表项
404 * 那么当前函数会依次被调用,每次都拼接一部分,直到整个Componet整合完成.
405 */
406 BISO_RRIP_AddLinkBuf((CHAR *)(pstSLEntry->aucComponet), ucCompentLen, pstPosixInfo);
407
408 /* FLAG的Bit0为0表示是最后1个SL表项,此时Componet已经整合在一起了,这里直接处理 */
409 if (0 == (pstSLEntry->ucFlags & 0x1))
410 {
411 /* 申请一段内存用来保存符号链接的源路径 */
412 uiBufLen = BISO_RRIP_CalcLinkLen(pstPosixInfo->pcLinkSrc, pstPosixInfo->uiLinkLen);
413 pcFullLinkPath = (CHAR *)BISO_MALLOC(uiBufLen + 10);
414 if (NULL == pcFullLinkPath)
415 {
416 BISO_FREE(pstPosixInfo->pcLinkSrc);
417 pstPosixInfo->uiLinkLen = 0;
418 return;
419 }
420
421 /* 拼接出链接的源路径 */
422 while (uiOffset < pstPosixInfo->uiLinkLen)
423 {
424 pstComp = (BISO_RRIP_SL_COMPONENT_S *)(pstPosixInfo->pcLinkSrc + uiOffset);
425 uiBufLen = BISO_RRIP_GetPartLink(pstComp, sizeof(szBuf), szBuf);
426
427 /* ucLength不包括头两个字节 */
428 uiOffset += pstComp->ucLength + 2;
429
430 /*
431 * 如果是link路径的一部分完结,则需要在后面加上'/',否则不加.
432 * 不加的情况有两种: 1是整体已经完了 2是路径的一部分还没有完整
433 * 比如说链接的位置是 /root/xxxx/a.txt 而xxxx可能非常长(200+个字符)
434 * 那么此时光xxxx的部分可能就需要两个Componet部分才能表达完,而这两个
435 * 之间是不能加反斜杠的.
436 */
437 if ((uiOffset < pstPosixInfo->uiLinkLen) && (BOOL_TRUE != BISO_SLCOMP_IS_CONTINUE(pstComp->ucFlags)))
438 {
439 szBuf[uiBufLen++] = '/';
440 }
441
442 memcpy(pcFullLinkPath + uiCurPos, szBuf, uiBufLen);
443 uiCurPos += uiBufLen;
444 }
445
446 pcFullLinkPath[uiCurPos++] = 0;
447
448 /* 原来的内存释放掉 */
449 BISO_FREE(pstPosixInfo->pcLinkSrc);
450 pstPosixInfo->pcLinkSrc = pcFullLinkPath;
451 pstPosixInfo->uiLinkLen = uiCurPos;
452 }
453 }
454
455 ULONG BISO_RRIP_ReadExtInfo
456 (
457 IN BISO_FILE_S *pstFile,
458 IN BISO_PARSER_S *pstParser,
459 IN BISO_DIR_RECORD_S *pstRecord,
460 OUT BISO_DIR_TREE_S *pstDirTree
461 )
462 {
463 UINT i = 0;
464 UINT uiOffset = 0;
465 UINT uiAreaSize = 0;
466 UCHAR *pucSysUseArea = NULL;
467 BISO_SUSP_ENTRY_S *pstEntry = NULL;
468
469 DBGASSERT(NULL != pstFile);
470 DBGASSERT(NULL != pstParser);
471 DBGASSERT(NULL != pstRecord);
472 DBGASSERT(NULL != pstDirTree);
473
474 /* 没有使用Rock Ridge扩展则直接返回 */
475 if (0 == pstParser->ucRRIPVersion)
476 {
477 return BISO_SUCCESS;
478 }
479
480 /* 先申请POSIX INFO结构体内存 */
481 if (NULL == pstDirTree->pstPosixInfo)
482 {
483 pstDirTree->pstPosixInfo = (BISO_POSIX_INFO_S *)BISO_ZALLOC(sizeof(BISO_POSIX_INFO_S));
484 if (NULL == pstDirTree->pstPosixInfo)
485 {
486 return BISO_ERR_ALLOC_MEM;
487 }
488 }
489
490 /* 偏移到System Use字段所在的位置,注意Padding字段, 保证偏移为偶数 */
491 uiOffset = 33 + pstRecord->ucNameLen;
492 uiOffset += uiOffset & 0x1;
493
494 /* 再加上SP Entry中定义的SkipLen长度 */
495 uiOffset += pstParser->ucRRIPSkipLen;
496
497 /* 获取整个Syetem Use区域的数据(包括CE扩展区) */
498 pucSysUseArea = BISO_RRIP_GetSysUseArea(pstFile, (UCHAR *)pstRecord + uiOffset,
499 pstRecord->ucLength - (UCHAR)uiOffset, &uiAreaSize);
500 if (NULL == pucSysUseArea)
501 {
502 return BISO_ERR_ALLOC_MEM;
503 }
504
505 /* 遍历所有的RRIP表项 */
506 for(uiOffset = 0; uiOffset + 4 < uiAreaSize; uiOffset += pstEntry->ucEntryLen)
507 {
508 pstEntry = (BISO_SUSP_ENTRY_S *)(pucSysUseArea + uiOffset);
509 /* BISO_DUMP_ShowSUSPEntry(pstEntry); */
510
511 /* 找到对应的处理函数处理 */
512 for (i = 0; i < ARRAY_SIZE(g_astBISO_RRIP_ParseFunc); i++)
513 {
514 if (BOOL_TRUE == BISO_RRIP_IsThisType(pstEntry, g_astBISO_RRIP_ParseFunc[i].szSignature))
515 {
516 if (NULL != g_astBISO_RRIP_ParseFunc[i].pfFunc)
517 {
518 g_astBISO_RRIP_ParseFunc[i].pfFunc(pstEntry, pstDirTree);
519 }
520 break;
521 }
522 }
523 }
524
525 BISO_FREE(pucSysUseArea);
526 return BISO_SUCCESS;
527 }
528
529 ULONG BISO_RRIP_ReadIndicator(INOUT BISO_PARSER_S *pstParser)
530 {
531 ULONG ulRet;
532 UINT64 ui64Seek = 0;
533 BISO_DIR_RECORD_S *pstRootDir = NULL;
534 BISO_SUSP_ENTRY_SP_S *pstSPEntry = NULL;
535 UCHAR aucBuf[sizeof(BISO_DIR_RECORD_S) + sizeof(BISO_SUSP_ENTRY_SP_S)];
536
537 DBGASSERT(NULL != pstParser);
538
539 /* 读出Root Directory Record */
540 pstRootDir = &(pstParser->pstPVD->stRootDirRecord);
541 ui64Seek = BISO_BLOCK_SIZE * (UINT64)pstRootDir->uiExtent;
542 ulRet = BISO_UTIL_ReadFile(pstParser->szFileName, ui64Seek, sizeof(aucBuf), aucBuf);
543 if (BISO_SUCCESS != ulRet)
544 {
545 return ulRet;
546 }
547
548 /* 看看Root Directory Record的System Use字段里有没有SP Entry */
549 pstRootDir = (BISO_DIR_RECORD_S *)aucBuf;
550 pstSPEntry = (BISO_SUSP_ENTRY_SP_S *)(pstRootDir + 1);
551 if (('S' != pstSPEntry->cSignature1) || ('P' != pstSPEntry->cSignature2) ||
552 (0xBE != pstSPEntry->ucChkBE) || (0xEF != pstSPEntry->ucChkEF))
553 {
554 pstParser->ucRRIPVersion = 0;
555 pstParser->ucRRIPSkipLen = 0;
556 }
557 else
558 {
559 pstParser->ucRRIPVersion = pstSPEntry->ucVersion;
560 pstParser->ucRRIPSkipLen = pstSPEntry->ucSkipLen;
561 }
562
563 return BISO_SUCCESS;
564 }
565
566
567