📄 udf_getudf.c
字号:
/* udf_tread is used as it takes care of block conversion for fixed packet written media */ error = UDF_tread(fsd->did, offset, 1, pBuffer, 1); if (error < 0) { /* Read error */ return error; } pFsd = (UDF_FilesetDesc*)pBuffer; /* * The root ICB tells us the length and location of root File Entry * Store the Root ICB length and location in fileset of PartitionInfo */ if (pFsd->descTag.tagIdent == UDF_FILE_SET_DESCRIPTOR_TAG256) { error = UDF_CheckDescriptorTag(pFsd); if (error != S_OK) { return error; } pPartitionInfo->fileSet.extLength = pFsd->rootDirectoryICB.extLength; pPartitionInfo->fileSet.extLocation = pFsd->rootDirectoryICB.extLocation.logicalBlockNum; if (fsd->PD.UDF_pd.flag == UDF_FLAG_SP_TABLE) { /* let us add the corresponding partition location */ partitionLoc = pFsd->rootDirectoryICB.extLocation.partitionReferenceNum; tempLoc = pPartitionInfo->fileSet.extLocation + fsd->PD.UDF_pd.partitionLoc[partitionLoc]; error = UDF_resolveAddresses(fsd, &tempLoc, 1, UDF_SINGLE_VALUE); if (error<0) return error; pPartitionInfo->fileSet.extLocation = tempLoc; } else { /* let us add the corresponding partition location */ partitionLoc = pFsd->rootDirectoryICB.extLocation.partitionReferenceNum; tempLoc = pPartitionInfo->fileSet.extLocation; error = UDF_resolveAddresses(fsd, &tempLoc, 1, UDF_SINGLE_VALUE); if (error<0) return error; pPartitionInfo->fileSet.extLocation = tempLoc + fsd->PD.UDF_pd.partitionLoc[partitionLoc]; } error = S_OK; } else { error = E_FAIL;// error = E_UDF_FSD_NOT_FOUND; } return error;} /* UDF_getRootNode *//* * Function Name : UDF_resolveAddresses * * Description : Recalculates addresses, taking in account VAT / Sparing table * * Parameters : FS_DESCRIPTOR* fsd - file system descriptor * uint32* pUnresolvedValue - buffer containing unresolved addresses * uint16 noOfEntries - num of addresses * uint16 flag - single/multiple adresses to solve * * Return Value : S_OK - resolved OK. * error - from subfunctions */GRESULT UDF_resolveAddresses(FS_DESCRIPTOR* fsd, uint32* pUnresolvedValue, uint16 noOfEntries, uint16 flag){ GRESULT error = S_OK; uint16 numOfSparingTable; PRIVATE_DATA_UDF* pUDF_desc; pUDF_desc = &(fsd->PD.UDF_pd); switch(pUDF_desc->flag) { case UDF_FLAG_SP_TABLE: /* Sparing Table */ { for(numOfSparingTable = 0; numOfSparingTable < 4; numOfSparingTable++) { if (pUDF_desc->locSparingTable[numOfSparingTable]) { /* If the required Sparing table is not present in Buffer */ if (pUDF_desc->curVATSparingInBuf != (numOfSparingTable + 1)) { /* Load the Sparing Table into pBuffer */ error = UDF_tread(fsd->did, pUDF_desc->locSparingTable[numOfSparingTable], 1, pUDF_desc->pVATSparingBuf, 1); if (error < 0) { pUDF_desc->curVATSparingInBuf = 0; //return E_READ_FAILURE; //return error; break; } pUDF_desc->curVATSparingInBuf = numOfSparingTable + 1; } error = UDF_resolveAddressSet(fsd, pUnresolvedValue, noOfEntries, pUDF_desc->pVATSparingBuf, flag); if (error < 0) //return error; break; } } } case UDF_FLAG_VAT15: /* VAT */ case UDF_FLAG_VAT20: { /* if the VAT table is not loaded already */ if (!(pUDF_desc->curVATSparingInBuf)) { /* * Load the VAT table which is obtained in the file entry * at the last block */ error = UDF_getFileDataLocations(fsd, pUDF_desc->pVATSparingBuf, pUDF_desc->end_LBN, &(pUDF_desc->pVAT_struct->VATAllocationDescriptorsTable[0]), &(pUDF_desc->pVAT_struct->NumberOfDescriptors), &(pUDF_desc->pVAT_struct->flags), UDF_TRUE); /*error = UDF_getNode( did, pUDF_desc->end_LBN, pUDF_desc->pVATSparingBuf ); */ if (error != S_OK) { /* curVATSparingInBuf is - when control comes here * so we need not reset it */ //return error; break; } pUDF_desc->curVATSparingInBuf = 1; } error = UDF_resolveAddressSet(fsd, pUnresolvedValue, noOfEntries, pUDF_desc->pVATSparingBuf, flag); break; } } return error;} /* UDF_resolveAddresses *//* * Function Name : UDF_resolveAddressSet * * Description : subfuc for addresses calculation * taking in account presence of VAT/SParing table * * Parameters : FS_DESCRIPTOR* fsd - file system descriptor * uint32* pUnresolvedValue * uint16 noOfEntries * uint8* pBuffer * uint16 flag * * Return Value : S_OK * E_FAIL - unknown input flag (shouldn't occur) * */GRESULT UDF_resolveAddressSet( FS_DESCRIPTOR* fsd, uint32* pUnresolvedValue, uint16 noOfEntries, uint8* pBuffer, uint16 flag){ GRESULT error = S_OK; uint32 resolvedValue; uint16 indexOfUnresolvedVal, counter; PRIVATE_DATA_UDF* pUDF_desc = &fsd->PD.UDF_pd; /* UDF_SINGLE_VALUE-> indicates that pUnresolvedValue is a single address value to be * resolved. * UDF_MULTIPLE_ADDRESS-> indicates that pUnresolvedValue is a consecutive set of * length and locations. * UDF_SINGLE_ADDRESS->it is a set of one single length and location. */ switch(flag) { case UDF_SINGLE_VALUE: case UDF_SINGLE_ADDRESS: if (pUDF_desc->flag == UDF_FLAG_SP_TABLE) { UDF_resolveSparingAddress(pUDF_desc, *pUnresolvedValue, pBuffer, &resolvedValue); } if (pUDF_desc->flag == UDF_FLAG_VAT15) { error = UDF_resolveVAT15Address(fsd->did, *pUnresolvedValue, pUDF_desc->pVAT_struct, pBuffer, &resolvedValue); } if (pUDF_desc->flag == UDF_FLAG_VAT20) { error = UDF_resolveVAT20Address(fsd->did, *pUnresolvedValue, pUDF_desc->pVAT_struct, pBuffer, &resolvedValue); } if (error == S_OK) /*Copy the resolved value into the same location*/ //error = UDF_memcpy(pUnresolvedValue, &resolvedValue, sizeof(resolvedValue)); *pUnresolvedValue = resolvedValue; break; case UDF_MULTIPLE_ADDRESS: indexOfUnresolvedVal = 0; //??? ??? if (pUDF_desc->flag == UDF_FLAG_SP_TABLE) { for(counter = 0; counter < noOfEntries; counter++) { UDF_resolveSparingAddress(pUDF_desc, pUnresolvedValue[indexOfUnresolvedVal], pBuffer, &resolvedValue); /*Copy the resolved value into the same location*/ //error = UDF_memcpy(&pUnresolvedValue[indexOfUnresolvedVal], &resolvedValue, sizeof(resolvedValue)); pUnresolvedValue[indexOfUnresolvedVal] = resolvedValue; if (error != S_OK) break; indexOfUnresolvedVal += VAT_ENTRY_SIZE; } } if (pUDF_desc->flag == UDF_FLAG_VAT15) { for( counter = 0; counter < noOfEntries; counter++) { error = UDF_resolveVAT15Address(fsd->did, pUnresolvedValue[indexOfUnresolvedVal], pUDF_desc->pVAT_struct, pBuffer, &resolvedValue); if (error != S_OK) break; /*Copy the resolved value into the same location*/ //error = UDF_memcpy(&pUnresolvedValue[indexOfUnresolvedVal], &resolvedValue, sizeof(resolvedValue)); pUnresolvedValue[indexOfUnresolvedVal] = resolvedValue; if (error != S_OK) break; indexOfUnresolvedVal += VAT_ENTRY_SIZE; } } if (pUDF_desc->flag == UDF_FLAG_VAT20) { for(counter = 0; counter < noOfEntries; counter++) { error = UDF_resolveVAT20Address(fsd->did, pUnresolvedValue[indexOfUnresolvedVal], pUDF_desc->pVAT_struct, pBuffer, &resolvedValue); if (error != S_OK) break; /*Copy the resolved value into the same location*/ //error = UDF_memcpy(&pUnresolvedValue[indexOfUnresolvedVal], &resolvedValue, sizeof(resolvedValue)); pUnresolvedValue[indexOfUnresolvedVal] = resolvedValue; if (error != S_OK) break; indexOfUnresolvedVal += VAT_ENTRY_SIZE; } } break; default: error = E_FAIL; break; } return error;} /* UDF_resolveAddressSet */ /* * Function Name : UDF_resolveSparingAddress * * Description : Reads Spating tables and finds entry for requested * address * * Parameters : PRIVATE_DATA_UDF* pUDF_desc * uint32 unresolvedValue * uint8* pBuffer * * Return Value : uint32* pResolvedVal */void UDF_resolveSparingAddress( PRIVATE_DATA_UDF* pUDF_desc, uint32 unresolvedValue, uint8* pBuffer, uint32* pResolvedVal){ UDF_SparingTable_i* ST = (UDF_SparingTable_i*)&pBuffer[1]; /* jump to first entry */ UDF_MapEntry* mapEntry; uint32 tempLoc; /* used to store the value read from buffer */ uint32 sp_table_offset = 0; *pResolvedVal = unresolvedValue; /* preset */ /* The block address is mapped to the appropriate packet * pUDF_desc->packetLength holds the packet length ??? */ tempLoc = unresolvedValue / pUDF_desc->packetLength; mapEntry = (UDF_MapEntry*)ST; /* first map entry (offset 56) */ /* Continue processing till we reach the end of the table */ while(sp_table_offset < pUDF_desc->sizeSparingTable) { if (mapEntry->originalLocation == tempLoc) { /* This is the Mapped location */ *pResolvedVal = mapEntry->mappedLocation; return; } /* The Sparing Entries are in ascending order. * If the sparing entry has crossed the value to be spared * then we return */ if (mapEntry->originalLocation > tempLoc) { return; } if ( mapEntry->originalLocation == UDF_NO_SPARING_VALUE) { return; } sp_table_offset += sizeof(UDF_MapEntry); mapEntry++; /* next Map Entry */ } /* while loop */} /* UDF_resolveSparingAddress *//* * Function Name : UDF_resolveVAT15Address * * Description : Resolves address whatever from Virt. alloc table * * Parameters : uint32 unresolvedValue - input value * uint8* pBuffer - buffer containing (allocated for VAT) * * Return Value : uint32* pResolvedValue - resolved val */GRESULT UDF_resolveVAT15Address(DUID did, uint32 unresolvedValue, VAT_struct* pVAT_struct, uint8* pBuffer, uint32* pResolvedValue){ GRESULT error; GRESULT result = S_OK; UDF_FileEntry_i* pFileEntry; /* pointer to file entry */ //uint8* extendedAttr; /* File Entry ext.attributes */ UDF_VAT_i* pVAT; /* Used to store the value retrieved from buffer for processing */ uint32 resolvedValueTmp; uint32 lengthExtendedAttr, lengthVATheader; uint16 counter; UDF_ALLOC_DESC_FLAG desc_flags; uint32* noOfEntries = &(pVAT_struct->noOfEntries); pFileEntry = (UDF_FileEntry_i*)pBuffer; desc_flags = (UDF_ALLOC_DESC_FLAG)pVAT_struct->flags; /* Extract the first 3 bits and interpret the value * If the value is 0 Short Allocation Descriptors are used * If the value is 1 Long Allocation Descriptors are used * If the value is 2 Extended Allocation Descriptors are used * If the value is 3 the data is recorded as one extent */ /* Get the first 3 bits and store the value in desc_flags */ switch(desc_flags) { case UDF_LONG_ALLOC_DESC: /* 1 */ { if (*noOfEntries <= 0) { /* there wasn't calculated number of VAT entries before */ *noOfEntries = 0; /* Read the first VAT location to get header of VAT */ error = UDF_tread(did, pVAT_struct->VATAllocationDescriptorsTable[0].extPosition, 1, pBuffer, 1); if (error != S_OK) return error; pVAT = (UDF_VAT_i*)pBuffer; /*calculate lenght of VAT header */ lengthVATheader = sizeof(UDF_VAT_i) + pVAT->lengthOfImplUse; /* in first VAT record decrease extLength by the VAT header */ pVAT_struct->VATAllocationDescriptorsTable[0].extLength -= lengthVATheader; /* in the VAT recalculate the extLength to number of VAT entries */ for (counter=0; counter < (pVAT_struct->NumberOfDescriptors); counter++) { pVAT_struct->VATAllocationDescriptorsTable[counter].extLength = pVAT_struct->VATAllocationDescriptorsTable[counter].extLength/4; //??? *noOfEntries += pVAT_struct->VATAllocationDescriptorsTable[counter].extLength; } /* in the last extent decrease by num of entries by 9 ~ num_of entries = (filesize - 36)/4 (.p35 in UDF 1.5) */ pVAT_struct->VATAllocationDescriptorsTable[counter].extLength -= 9; } if (unresolvedValue < (pVAT_struct->VATEntryBeginningIndex)) { /* VAT entry is in some previous extent */ while (unresolvedValue< (pVAT_struct->VATEntryBeginningIndex)) { (pVAT_struct->DescriptorIndex)--; pVAT_struct->VATEntryBeginningIndex-= (pVAT_struct->VATAllocationDescriptorsTable[pVAT_struct->DescriptorIndex].extLength); } error = UDF_tread(did, pVAT_struct->VATAllocationDescriptorsTable[pVAT_struct->DescriptorIndex].extPosition, 1, pBuffer, 1); if (error != S_OK) return error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -