📄 udf_getudf.c
字号:
/************************************************** * * UDF_getUDF.c * * CVS ID: $Id: UDF_getUDF.c,v 1.19 2007/01/05 13:38:08 sedmik Exp $ * Author: Jiri Sedmik [JS] - STM * Date: $Date: 2007/01/05 13:38:08 $ * Revision: $Revision: 1.19 $ * * Description: * * *************************************************** * * COPYRIGHT (C) ST Microelectronics 2005 * All Rights Reserved * *************************************************** * * STM CVS Log: * * $Log: UDF_getUDF.c,v $ * Revision 1.19 2007/01/05 13:38:08 sedmik * fixed anchor point selection * * Revision 1.18 2006/12/12 19:16:21 trubac * change of uin16 to int32 of directory parsing offset * * Revision 1.17 2006/11/28 09:39:21 trubac * sess_LBA changed from in16 to int32 * * Revision 1.16 2006/11/27 19:45:38 belardi * Removed unused variable * * Revision 1.15 2006/11/21 11:54:57 longauer * *** empty log message *** * * Revision 1.14 2006/11/15 12:25:06 trubac * E_FORCED_UNPLUG handling * * Revision 1.13 2006/11/09 16:21:41 belardi * Removed unused variable * * Revision 1.12 2006/11/07 19:36:10 longauer * all songs recognized on the UDF test disk 1 and 2 * * Revision 1.11 2006/10/26 13:35:14 longauer * File Entry reorganized; VAT20 re-addressing bug found * * Revision 1.10 2006/10/20 15:08:35 longauer * VAT works; + code reorganization * * Revision 1.9 2006/10/17 09:59:41 trubac * copy protected CD support * * Revision 1.8 2006/09/27 15:39:16 longauer * VAT first time working * * Revision 1.7 2006/09/18 09:55:22 belardi * Corrected CVS keyword usage * * Revision 1.6 2006/09/18 09:24:02 belardi * Added Log CVS keyword into file header * * ***************************************************/#include "configuration.h"#if (HAVE_UDF)#include <string.h>#include <stdio.h>#include <stdlib.h>#include "debug.h"#include "UDF_macros.h"#include "UDF_getUDF.h"#include "allocation.h"#include "apdevsys.h"#include "cddevice.h"#include "utf8.h"#include "xfile.h"#include "ISO9660.h"#include "filesys.h"VAT_struct VAT;/* * Function Name : UDF_Detect * * Description : Checks presence of UDF filesystem. * Finds anchor points for UDF filesystem. * Finds partitions of UDF volume * * * Parameters : DUID cdid - device identifier * int partition - partition number * FS_DESCRIPTOR* fsd - file system descriptor * * Return Value : E_INVALID_DEVICE_DESCRIPTOR * E_INVALID_DEVICE_TYPE - device type invalid for UDF * E_INVALID_FS_DESCRIPTOR - Descriptor expected but not found * E_UNKNOWN_FS_TYPE - UDF filesystem not found * E_MEMORY_ERROR - allocation failed * E_FAIL - reading problems * S_OK - filesystem present */GRESULT UDF_Detect(DUID cdid, int partition, FS_DESCRIPTOR* fsd){ GRESULT error; GRESULT result = S_TRUE; t_duid duid; int32 sess_LBA; CD_DeviceDescriptor* cddesc; PRIVATE_DATA_UDF* pUDF_desc; uint8* pBuffer; uint8* pVATSparingBuf = NULL; VAT_struct* pVAT = NULL; UDF_Partition* pPartitionInfo; duid = SYS_DeviceType(cdid); if (duid != DEV_CD_ID) { return E_INVALID_DEVICE_TYPE; } cddesc = (CD_DeviceDescriptor*)SYS_DeviceDescriptor(cdid); if (NULL == (void*)cddesc) { return E_INVALID_DEVICE_DESCRIPTOR; }// pUDF_desc->start_LBN = cddesc->LastSessionLba - TOC_OFFSET_SECTOR;// pUDF_desc->end_LBN = cddesc->LastSessionLastLba - TOC_OFFSET_SECTOR - 1; sess_LBA = CD_LastSessionLBA(); //cddesc->LastSessionLba; if (sess_LBA < 0) { return E_NO_FS_CARRIER; } pUDF_desc = &fsd->PD.UDF_pd; do { /* allocate what is needed to don't load task stack*/ pBuffer = MALLOC(UDF_LOGICAL_BLOCK_SIZE); if (!pBuffer) { result = E_MEMORY_ERROR; break; } pVATSparingBuf = MALLOC(UDF_LOGICAL_BLOCK_SIZE); if (!pVATSparingBuf) { result = E_MEMORY_ERROR; break; } pVAT = &VAT;#ifdef UDF_DEBUG memset(pBuffer, 1, UDF_LOGICAL_BLOCK_SIZE); memset(pVATSparingBuf, 2, UDF_LOGICAL_BLOCK_SIZE); memset(pVAT, 3, sizeof(VAT_struct));#endif /*UDF_DEBUG*/ /* Initialise VAT table variables (alloc desc array stays uninitialised) */ pVAT->VATEntryBeginningIndex = 0; pVAT->DescriptorIndex = 0; pVAT->noOfEntries = 0; pVAT->NumberOfDescriptors = 0; fsd->attributes = 0; fsd->LargeBlockSize = 2048; fsd->Partition = partition; fsd->PartitionLBA = SYS_PartitionLBA(cdid, partition, 2048); fsd->FSType = FS_UDF_TYPE; fsd->did = cdid; pUDF_desc->pVATSparingBuf = pVATSparingBuf; pUDF_desc->pVAT_struct = pVAT; pUDF_desc->pBuffer = pBuffer; pUDF_desc->curVATSparingInBuf = 0; pUDF_desc->start_LBN = sess_LBA - TOC_OFFSET_SECTOR; pUDF_desc->end_LBN = CD_LastSessionLBAEndAddress() - TOC_OFFSET_SECTOR; error = UDF_FindAnchor(cdid, pUDF_desc->start_LBN, pUDF_desc->end_LBN, pBuffer, &(pUDF_desc->MainVol), &(pUDF_desc->ReserveVol)); if (error != S_OK) { DBG_PRINTF("udf: Anchor point not found!!\r\n"); if(error == E_FORCED_UNPLUG) { result = error; } else { result = E_INVALID_FS_DESCRIPTOR; } break; } /* parse Main Volume Descriptor Sequence */ error = UDF_findPartitions(cdid, pBuffer, &(pUDF_desc->MainVol), pUDF_desc); if (error != S_OK) { DBG_PRINTF("udf: *E - Could not find valid partitions [%d]: scanning reserve volume\r\n", error); if(error == E_FORCED_UNPLUG) { result = error; break; } /* Try reading the Reserve Volume descriptor Sequence */ error = UDF_findPartitions(cdid, pBuffer, &(pUDF_desc->ReserveVol), pUDF_desc); if (error != S_OK) { DBG_PRINTF("udf: *E - Could not find valid partitions in reserve volume [%d]\r\n", error); if(error == E_FORCED_UNPLUG) { result = error; } else { result = E_UNKNOWN_FS_TYPE; } break; } } /* End of UDF Find Partition Info */ pPartitionInfo = &(pUDF_desc->partitionInfo); /* Read the root node */ error = UDF_getRootNode(fsd, pPartitionInfo, pBuffer); if (error < 0) { DBG_PRINTF("udf: *E - Could not find root node ! error :%d\r\n",error); if(error == E_FORCED_UNPLUG) { result = error; } else { result = E_INVALID_FS_DESCRIPTOR; } break; } } while(FALSE); if (pBuffer) FREE(pBuffer); if (pVATSparingBuf) FREE(pVATSparingBuf); fsd->attributes = DEV_ATTR_UDF_FILESYSTEM; pUDF_desc->pVATSparingBuf = NULL; pUDF_desc->pBuffer = NULL; pUDF_desc->curVATSparingInBuf = 0; /* VATSparingBuf perish - we must ensure data for VAT parsing be present in the UDF_GetDirItem by forcing to scan VAT again */ pVAT->noOfEntries = 0; return result;} /* UDF_Detect *//* * Function Name : UDF_FindAnchor * * Description : Finds anchor points in actual session * * Parameters : DUID did - device identifier * uint32 start_LBN - session start * uint32 end_LBN - session end * uint8* pBuffer - buffer for parsed data * UDF_ExtentAd* pMainVol - main volume descriptor extent * UDF_ExtentAd* pReserveVol - reserve volume descriptor extent * * Return Value : E_FAIL - reading problems * S_OK - anchor points are correct, pMainVol, pReserveVol contains filesystem extents * E_INVALID_FS_DESCRIPTOR * */GRESULT UDF_FindAnchor(DUID did, uint32 start_LBN, uint32 end_LBN, uint8* pBuffer, UDF_ExtentAd* pMainVol, UDF_ExtentAd* pReserveVol){ GRESULT error; GRESULT result = S_OK; uint32 offset[UDF_ANCHOR_NUMBER]; /* Anchor offsets */ UDF_AnchVolDescPointer* pAnchor; /* Anchor pointer */ UDF_ANCHOR_POSITIONS anchorParsed = UDF_ANCHOR_FIRST; /* 8.4.2.1, pp.47ecma Let k be ip(n/59), where n is the largest logical sector number in the volume space. Anchor points shall be at two or more of the following logical sector numbers: 256, n-256, n and all the nonzero integral multiples of k not greater than n. Order of anchors scanned is described in the udf260_allApprovedDCNs.pdf, pp.51, pp.53 */ /* First Anchor at 256 */ offset[UDF_ANCHOR_FIRST] = start_LBN + UDF_MEDIA_ANCHOR_BLOCKNO; /* Anchor ar N-256 */ offset[UDF_ANCHOR_FIRST_BACKUP_SESS_OPEN] = end_LBN - UDF_MEDIA_ANCHOR_BLOCKNO; /* Duplicate Anchor at N */ offset[UDF_ANCHOR_FIRST_BACKUP_SESS_CLOSED] = end_LBN ; /* Open disc Anchor at 512 */ offset[UDF_ANCHOR_SECOND] = start_LBN + UDF_MEDIA_OPEN_ANCHOR_BLOCKNO; do {#ifdef UDF_DEBUG DBG_PRINTF("anchor: %d\r\n", anchorParsed);#endif /*UDF_DEBUG*/ error = UDF_tread(did, offset[anchorParsed], 1, pBuffer, 1); if (error < 0) { result = error; //result = E_FAIL; break; } else { pAnchor = (UDF_AnchVolDescPointer*)pBuffer; } /* Anchor Volume Descriptor Pointer */ if (pAnchor->descTag.tagIdent == UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER_TAG2) { /* to check if the tag is valid */ error = UDF_CheckDescriptorTag(pAnchor); if (error == S_OK) {#ifdef UDF_DEBUG DBG_PRINTF("UDF_findVolume: Anchor found at block [%d]\r\n",offset[anchorParsed]);#endif /*UDF_DEBUG*/ memset(pMainVol, 0x0000, sizeof(UDF_ExtentAd)); pMainVol->extLength = (uint32)pAnchor->mainVolDescSeqExt.extLength;#ifdef UDF_DEBUG DBG_PRINTF("Mainvol length %d\r\n", pMainVol->extLength);#endif /*UDF_DEBUG*/ pMainVol->extLocation = (uint32)pAnchor->mainVolDescSeqExt.extLocation;#ifdef UDF_DEBUG DBG_PRINTF("Mainvol location %d\r\n", pMainVol->extLocation);#endif /*UDF_DEBUG*/ memset(pReserveVol,0x0000,sizeof(UDF_ExtentAd)); pReserveVol->extLength = (uint32)pAnchor->reserveVolDescSeqExt.extLength;#ifdef UDF_DEBUG DBG_PRINTF("Reserve length %d\r\n", pReserveVol->extLength);#endif /*UDF_DEBUG*/ pReserveVol->extLocation = (uint32)pAnchor->reserveVolDescSeqExt.extLocation;#ifdef UDF_DEBUG DBG_PRINTF("Reserve location %d\r\n", pReserveVol->extLocation);#endif /*UDF_DEBUG*/ break; } } if (++anchorParsed == UDF_ANCHOR_NUMBER) /* try another */ { result = E_INVALID_FS_DESCRIPTOR; break; } } while(1); return result;} /* UDF_FindAnchor *//* * Function Name : UDF_CheckDescriptorTag * * Description : Checks the validity of the descriptor * * Parameters : UDF_Tag descTag - descriptor tag * * Return Value : E_FAIL - possible descriptor error * S_OK - descriptor validated * */GRESULT UDF_CheckDescriptorTag(void* pDescriptor){ GRESULT result = S_OK; UDF_Tag* descTag; uint32 descriptorSize = 0; uint16 CRCLength; if (!pDescriptor) {#ifdef UDF_DEBUG DBG_PRINTF("udf: *W - Descriptor doesn't exist\r\n");#endif /*UDF_DEBUG*/ return E_FAIL; } descTag = (UDF_Tag*)pDescriptor; /* first item of all descriptors */ //TBD CRC checking is missing; 7.2.6, pp.44 if ((descTag->descCRC == 0) && (descTag->descCRCLength == 0)) {#ifdef UDF_DEBUG DBG_PRINTF("UDF_CheckDescriptorTag: no CRC\r\n");#endif /*UDF_DEBUG*/ return result; } switch(descTag->tagIdent) { /* Primary Volume Descriptor */ case UDF_PRIMARY_VOLUME_DESCRIPTOR_TAG1: case UDF_PARTITION_DESCRIPTOR_TAG5: /* Logical Volume Descriptor */ descriptorSize = sizeof(UDF_PartitionDesc); break; /* Anchor Volume Descriptor Pointer */ case UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER_TAG2: descriptorSize = sizeof(UDF_AnchVolDescPointer); break; /* Partition Descriptor */ case UDF_LOGICAL_VOLUME_DESCRIPTOR_TAG6: descriptorSize = sizeof(UDF_LogVolDesc_i) + ((UDF_LogVolDesc_i*)pDescriptor)->mapTableLength; break; /* Logical Volume Integrity Descriptor */ case UDF_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR_TAG9: descriptorSize = sizeof(UDF_LogVolIntegrityDesc_i); break; case UDF_FILE_SET_DESCRIPTOR_TAG256: descriptorSize = sizeof(UDF_FilesetDesc); break; case UDF_FILE_IDENTIFIER_DESCRIPTOR_TAG257: descriptorSize = sizeof(UDF_fileIdentDesc_i) + UDF_GetFIDLength((UDF_fileIdentDesc_i*)pDescriptor); break; default:#ifdef UDF_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -