📄 udf_getudf.c
字号:
DBG_PRINTF("udf: *W - Unknown descriptor [0x%x]\r\n", descTag->tagIdent);#endif /*UDF_DEBUG*/ return E_INVALID_FS_DESCRIPTOR; } CRCLength = wmin(descriptorSize - sizeof(UDF_Tag), 65535); if (descTag->descCRCLength != CRCLength) { DBG_PRINTF("udf: *E - Wrong CRC or checksum\r\n"); result = E_INVALID_FS_DESCRIPTOR; } return result;}/* * Function Name : UDF_findPartitions * * Description : finds partitions in UDF filesystem. * By the spec there can be max 2 partitions * There's also checked presence of Sparing tables or VAT * * Parameters : DUID did - device identifier * uint8* pBuffer - buffer for parsed data * UDF_ExtentAd *pVolAd, - main or reserve vloume descriptor * PRIVATE_DATA_UDF *pUDF_desc - structure for UDF static data * * Return Value : E_READ_FAILURE * E_UDF_PARTITION_NOT_FOUND * E_UDF_FSD_NOT_FOUND * E_UDF_LVDP_NOT_FOUND * S_OK - all read correctly */GRESULT UDF_findPartitions(DUID did, uint8* pBuffer, UDF_ExtentAd* pVolAd, PRIVATE_DATA_UDF* pUDF_desc) { GRESULT error; GRESULT result = S_OK; t_conv_param p; uint16 volPartitionNumber; uint16 LocalVolName[VOLUME_IDENTIFIER_LENGTH]; uint32 startOffset = 0U, endOffset, partitionLocation, numOfPartitions; UDF_BOOL partitionFound = UDF_FALSE; UDF_BOOL lvdpFound = UDF_FALSE; UDF_LogVolIntegrityDesc_i* pLvid; /* pointer to logical volume integrity descriptor */ UDF_PartitionDesc* pPartition; /* Pointer to Partition */ UDF_LogVolDesc_i* pLvdp; /* Pointer to LVDP */ UDF_Tag* pTag; UDF_LongAD* pLongAd; //6.9.2.3, pp.136, udf260.pdf (DVD only?) memset(LocalVolName, 0x00, VOLUME_IDENTIFIER_LENGTH*2); startOffset = pVolAd->extLocation; endOffset = startOffset + (pVolAd->extLength / UDF_LOGICAL_BLOCK_SIZE);#ifdef UDF_DEBUG DBG_PRINTF("UDF_findPartitions: VDS start at block [%d] ends at block [%d]\r\n", startOffset, endOffset);#endif /*UDF_DEBUG*/ pUDF_desc->partitionLoc[0] = 0; pUDF_desc->partitionLoc[1] = 0; while(startOffset < endOffset) /* (one descriptor per sector) */ { error = UDF_tread(did, startOffset, 1, pBuffer, 1); if (error < 0) {#ifdef UDF_DEBUG DBG_PRINTF("UDF_findPartitions:UDF_READ_ERROR at block [%d]\r\n", startOffset);#endif /*UDF_DEBUG*/ /* Error */ return error; //E_READ_FAILURE; } pTag = (UDF_Tag*)pBuffer; switch (pTag->tagIdent) { /* Primary Volume Descriptor */ case UDF_PRIMARY_VOLUME_DESCRIPTOR_TAG1: pPartition = (UDF_PartitionDesc*)pBuffer; error = UDF_CheckDescriptorTag(pPartition); if (error != S_OK) { result = error; break; } dstrcpy(LocalVolName, (char*)&(pPartition->partitionContents), VOLUME_IDENTIFIER_LENGTH); p.be = 0; p.trunc = 0; p.limit = 0; WideFileNameToUTF8((uint8*)LocalVolName, (uint8*)pUDF_desc->VolumeName, VOLUME_IDENTIFIER_LENGTH, &p);#ifdef UDF_DEBUG DBG_PRINTF("UDF_findPartitions: Primary volume descriptor has volume identifier at:[%xh]\r\n", pUDF_desc->VolumeName );#endif /*UDF_DEBUG*/ break; /* Partition Descriptor */ case UDF_PARTITION_DESCRIPTOR_TAG5: /* length!! - reduced to 400B without metadata */#ifdef UDF_DEBUG DBG_PRINTF("UDF_findPartitions: PD found at block [%d]\r\n", startOffset );#endif /*UDF_DEBUG*/ pPartition = (UDF_PartitionDesc*)pBuffer; error = UDF_CheckDescriptorTag(pPartition); if (error != S_OK) { result = error; break; } /* store this value in Vol Params */ volPartitionNumber = pPartition->partitionNumber; partitionLocation = pPartition->partitionStartingLocation; (pUDF_desc->partitionLoc)[volPartitionNumber] = partitionLocation; //??? (pUDF_desc->partitionLoc)[1] = partitionLocation; //??? /* When the partition number is zero then store this length and location in pPartitionInfo. */ if (volPartitionNumber == 0) { pUDF_desc->partitionInfo.partition.extLocation = partitionLocation; pUDF_desc->partitionInfo.partition.extLength = pPartition->partitionLength; } partitionFound = UDF_TRUE; break; /* Logical Volume Descriptor */ case UDF_LOGICAL_VOLUME_DESCRIPTOR_TAG6:#ifdef UDF_DEBUG DBG_PRINTF("UDF_findPartitions: LVD found at block [%xh]\r\n", startOffset );#endif /*UDF_DEBUG*/ pLvdp = (UDF_LogVolDesc_i*)pBuffer; error = UDF_CheckDescriptorTag(pLvdp); if (error != S_OK) { result = error; break; } /* TBD - logical block size */ if (pLvdp->logicalBlockSize != UDF_LOGICAL_BLOCK_SIZE) {#ifdef UDF_DEBUG DBG_PRINTF("UDF_logicalBlockSize: is [%d] !!!\r\n", pLvdp->logicalBlockSize);#endif /*UDF_DEBUG*/ } /* TBD - integrity extent */ if ((pLvdp->integritySeqExt.extLength != 0) /*|| (pLvdp->numPartitionMaps > 0)*/) {#ifdef UDF_DEBUG DBG_PRINTF("UDF_extents: Logical Volume Integrity Sequence exist\r\n");#endif /*UDF_DEBUG*/ } /* Get File Set Descriptor locations */ pLongAd = (UDF_LongAD*)pLvdp->logicalVolContentsUse; if (pLongAd) { pUDF_desc->partitionInfo.fileSet.extLength = pLongAd->extLength; pUDF_desc->partitionInfo.fileSet.extLocation = pLongAd->extLocation.logicalBlockNum;#ifdef UDF_DEBUG DBG_PRINTF("UDF_findPartitions: File Set found at logical block [%xh] length [%xh]\r\n", pUDF_desc->partitionInfo.fileSet.extLocation, pUDF_desc->partitionInfo.fileSet.extLength);#endif /*UDF_DEBUG*/ /* Check for the presence of VAT or Sparing Table */ error = UDF_checkVATAndSparingTable(pLvdp, pUDF_desc);/* if (error == UDF_NO_TABLE) return E_FAIL;// return E_UDF_VAT_OR_SPARTABLE; //TBD */ lvdpFound = UDF_TRUE; } else { return E_FAIL;// return E_UDF_FSD_NOT_FOUND; } break; /* Logical Volume Integrity Descriptor */ case UDF_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR_TAG9: // length!! /* Find the number of partitions in the given volume */ pLvid = (UDF_LogVolIntegrityDesc_i*)pBuffer; error = UDF_CheckDescriptorTag(pLvid); if (error != S_OK) { result = error; break; } /* TBD - other integrity extents */ if (pLvid->nextIntegrityExt.extLength != 0) {#ifdef UDF_DEBUG DBG_PRINTF("UDF_extents: other Logical Volume Integrity Sequence exists\r\n");#endif /*UDF_DEBUG*/ } numOfPartitions = pLvid->numOfPartitions; if (numOfPartitions > 2) { DBG_PRINTF("Number of Partitions exceeds allocated space!!!!!\r\n" ); //result = E_UDF_PARTITION_NUM //TBD - error??? } if ((pUDF_desc->partitionLoc[0] == 0) && (pUDF_desc->partitionLoc[1] == 0)) { return E_FAIL;// return E_UDF_PARTITION_NOT_FOUND; } break; } /* * Go to next block in the Volume descriptor sequence * until partition descriptor and logical volume descriptor * are found */ startOffset = startOffset + 1; } /* end of scanning vds */ if (!partitionFound) {#ifdef UDF_DEBUG DBG_PRINTF("UDF_findPartitions: PD not found\r\n" );#endif /*UDF_DEBUG*/ result = E_FAIL;// result = E_UDF_PARTITION_NOT_FOUND; } if (!lvdpFound) {#ifdef UDF_DEBUG DBG_PRINTF("UDF_findPartitions: LVD not found\r\n" );#endif /*UDF_DEBUG*/ result = E_FAIL;// result = E_UDF_LVDP_NOT_FOUND; } return result;} /* UDF_findPartitions *//* * Function Name : UDF_checkVATAndSparingTable * * Description : Checking presence of Sparing table * or Virtual allocation table * * Parameters : UDF_LogVolDesc_i* pLvdp - ptr to buffer for checking * of presence of tables * PRIVATE_DATA_UDF* pUDF_desc * * Return Value : PRIVATE_DATA_UDF* pUDF_desc - contains flags and adresses * of VAT/Sparing tables */URESULT UDF_checkVATAndSparingTable(UDF_LogVolDesc_i* pLvdp, PRIVATE_DATA_UDF* pUDF_desc){ URESULT result = UDF_NO_TABLE; UDF_PartitionMap* pGpm = NULL; /* Pointer to sparable partition map */ //UDF_VirtualPartitionMap* pVpm = NULL; UDF_SparablePartitionMap* pSpm = NULL; uint32 offset, mapTableLen; uint16 sparingLocationNum, partMapType, partitionMapLength; /* VAT and Sparing Table Identifers*/ uint8 udf_vat_ident_str[] = { '*','U','D','F',' ',\ 'V','i','r','t','u','a','l',' ',\ 'P','a','r','t','i','t','i','o','n', 0 }; uint8 udf_sparing_ident_str[] = { '*','U','D','F',' ',\ 'S','p','a','r','a','b','l','e',' ',\ 'P','a','r','t','i','t','i','o','n', 0 }; pUDF_desc->curVATSparingInBuf = 0; pUDF_desc->sizeSparingTable = 0; mapTableLen = pLvdp->mapTableLength; for(offset=0; offset<mapTableLen; ) { pGpm = (UDF_PartitionMap*)((uint8*)&pLvdp[1] + offset); /* jump to partition map */// pGpm = (UDF_PartitionMap*)((uint8*)pLvdp + sizeof(UDF_LogVolDesc_i) + offset); partMapType = pGpm->Generic.partitionMapType; if (partMapType == UDF_PARTITION_MAP_TYPE2) { /* check if it is VAT */ if (UDF_strncmp((uint8*)pGpm->VPM.partitionIdent.ident, udf_vat_ident_str, sizeof(udf_vat_ident_str))) { /* The domainIdent parameter of the LVDP contains the * domain identifier and version number. The first 2 bytes * of the suffix indicate version number. * The offset is 120 in terms of words */ if (pLvdp->domainIdent.Suffix.UdfIdentSuffix.udfRevision == UDF_VAT_VERSION15) result = UDF_FLAG_VAT15; if (pLvdp->domainIdent.Suffix.UdfIdentSuffix.udfRevision == UDF_VAT_VERSION20) result = UDF_FLAG_VAT20; if (pLvdp->domainIdent.Suffix.UdfIdentSuffix.udfRevision == UDF_VAT_VERSION201) result = UDF_FLAG_VAT20; } /* check if it is SAT */ if (UDF_strncmp((uint8*)pGpm->VPM.partitionIdent.ident, udf_sparing_ident_str, sizeof(udf_sparing_ident_str))) { /* Update UDF_params ( of pDev) with sparing table info */ /* pSpm = ( UDF_SparablePartitionMap * ) &( pLvdp->logVol[UDF_PARTITION_MAPS_OFFSET] ); */ // with 0 offset??? pSpm = (UDF_SparablePartitionMap*)pGpm; // "offset"offset result = UDF_FLAG_SP_TABLE; /* Store the size and location of sparing tables in * UDF_params */ pUDF_desc->sizeSparingTable = pSpm->sizeSparingTable; /* Initialize all the sparing table locations to zero */ for( sparingLocationNum = 0; /* max number of tables is 4 udf260 p.38 */ sparingLocationNum < 4; sparingLocationNum++ ) { pUDF_desc->locSparingTable[sparingLocationNum] = 0U; } for( sparingLocationNum = 0; sparingLocationNum < pSpm->numSparingTables; sparingLocationNum++ ) { pUDF_desc->locSparingTable[sparingLocationNum] = pSpm->locations[sparingLocationNum]; } pUDF_desc->packetLength = pSpm->packetLength; } } /* this value is actually 2nd byte of first word*/ partitionMapLength = pGpm->Generic.partitionMapLength; /* convert it to words */ offset += partitionMapLength; } /* for loop */ pUDF_desc->flag = result; return result;} /* UDF_checkVATorSparingTable *//* * Function Name : UDF_strncmp * * Description : text comparison function * * Parameters : uint8 src[], * uint8 dst[], * uint16 length, * * Return Value : UDF_TRUE/UDF_FALSE * */UDF_BOOL UDF_strncmp(uint8* src, uint8* dst, uint16 length){ uint8 compCount = 0; if ((src == NULL) || (dst == NULL) || (!length)) { DBG_PRINTF("UDF_strncmp: FAILURE - Null length [%d] Or Src [%d] Or Dst [%d]\r\n", length, src, dst ); return UDF_FALSE; } for (compCount = 0; (compCount < length); compCount++) { if (src[compCount] != dst[compCount]) { return UDF_FALSE; } } return UDF_TRUE;} /* UDF_strncmp *//* * Function Name : UDF_getRootNode * * Description : locates position of root file entry * * Parameters : FS_DESCRIPTOR* fsd - UDF private data * UDF_Partition* pPartitionInfo * uint8* pBuffer * * Return Value : E_FAIL * S_OK * E_UDF_FSD_NOT_FOUND * error - from subfunctions UDF_resolveAddresses * */GRESULT UDF_getRootNode(FS_DESCRIPTOR* fsd, UDF_Partition* pPartitionInfo, uint8* pBuffer){ GRESULT error = S_OK; uint32 tempLoc = 0, offset = 0, partitionLoc = 0; /* temporary variable to store resolved & unresolved logical address */ UDF_FilesetDesc* pFsd = NULL; /* pointer to a file set descriptor */ //6.9.2.4, pp.136, udf260.pdf /* * The location of the FSD is Partition_location + FSD_location */ tempLoc = pPartitionInfo->fileSet.extLocation; if (fsd->PD.UDF_pd.flag == UDF_FLAG_SP_TABLE) { offset = (pPartitionInfo->partition.extLocation + tempLoc); error = UDF_resolveAddresses(fsd, &offset, 1, UDF_SINGLE_VALUE); if (error < 0) return error; } else { error = UDF_resolveAddresses(fsd, &tempLoc, 1, UDF_SINGLE_VALUE); if (error < 0) return error; offset = (pPartitionInfo->partition.extLocation + tempLoc); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -