📄 udf_getudf.c
字号:
uint32 tmpOffset = 0; uint32 isZero; uint16 desc_size; //TBD: if desc_flag hasn't sense -> abort switch (desc_flags) { case UDF_SHORT_ALLOC_DESC: desc_size = sizeof(UDF_ShortAD); break; case UDF_LONG_ALLOC_DESC: desc_size = sizeof(UDF_LongAD); break; case UDF_EXTENDED_ALLOC_DESC: desc_size = sizeof(UDF_ExtAD); break; default: return 0; } while(1) { isZero = pBuff[tmpOffset]; if (isZero == 0) break; tmpOffset += desc_size; noOfDesc = noOfDesc + 1; } return noOfDesc;} /* UDF_findNumDesc *//* * Function Name : UDF_checkConfigParams * * Description : This function checks to see wether a particular FID * matches the conditions specified in the config params. * If the FID matches the criteria specified by the config * params UDF_TRUE is returned else UDF_FALSE. * * Parameters : fileID -> Pointer to File Identifeir Descriptor. * pParams -> Pointer to config params. * * * Return Value : UDF_BOOL. */UDF_BOOL UDF_checkConfigParams(UDF_fileIdentDesc_i* fileID){ uint8 lenFileIdent; UDF_FileCharact fileChar; fileChar = (UDF_FileCharact)fileID->fileCharacteristics; lenFileIdent = fileID->lengthFileIdent; /* Checking for ".." node*/ if (lenFileIdent == 0) {#ifdef UDF_DEBUG DBG_PRINTF("Parsing new directory (..)\r\n");#endif /*UDF_DEBUG*/ return UDF_FALSE; } /* If the directory or file is deleted do not process FID */ if (fileChar & UDF_FILE_DELETED) return UDF_FALSE; /* In the case of a directory we always need to create it */ if (fileChar & UDF_FILE_IS_DIRECTORY) { /* This is a directory - so create it*/ return UDF_TRUE; } /* check to see if the file type falls into the file types listed * by config params */ else { /* Here can be test for file extension */ return UDF_TRUE; } /* At this stage we have compared all the filetypes and have * not found the corresponding file type in the list. */ //return UDF_FALSE; } /* UDF_checkConfigParams */ /* * Function Name : UDF_updateFIDCharacteristics * * Description : This function updates the node with the FID * information. * * Parameters : FS_DESCRIPTOR *fsd * INT32 Offset - offset pos from current ICB recordset (for future fullname parsing) * UDF_fileIdentDesc_i *pFileID - ptr in current buffer pointing to FID structure * * * Return Value : DIR_ITEM *item - filled structure contains info about file/dir * GRESULT = S_PARENT_DIR / S_FILE_FOUND / S_DIR_FOUND */GRESULT UDF_updateFIDCharacteristics(FS_DESCRIPTOR* fsd, int32 Offset, UDF_fileIdentDesc_i* pFileID, DIR_ITEM* item){ GRESULT error = S_OK; UDF_FileCharact fileChar; uint16 wordTmp; uint16 liu; /* length of the Implementation Use */ uint16 lenFileIdent; /* length of the File Identifier */ uint8* fileIdent; /* Compressed Unicode format pointer */ uint16 cId; /* Compression ID */ uint8* bitStream; /* Compressed Bit Stream pointer */ uint16 index = 0; UDF_ShortAD AllocDescriptor; //uint16 FileName[FILENAME_MAX]; //stdio.h definition ??? uint16 FileName[UDF_MAX_NAME_LENGTH]; t_conv_param p; PRIVATE_DATA_UDF* pUDF_desc = &fsd->PD.UDF_pd; p.be = 1; p.trunc = 0; p.limit = 0; lenFileIdent = pFileID->lengthFileIdent; if (lenFileIdent > UDF_MAX_NAME_LENGTH) {#ifdef UDF_DEBUG DBG_PRINTF(": *W - Unexpected file identifier length [%d]\r\n", lenFileIdent);#endif /*UDF_DEBUG*/ lenFileIdent = UDF_MAX_NAME_LENGTH; } memset(FileName, 0x0000, UDF_MAX_NAME_LENGTH); /* Check for ".."entry * If the file identifier is 0 then it means * it is the first FID in the current directory * pointing to the FE of it's parent directory */ if (lenFileIdent == 0) { /* This is the first FID in the directory * Make it a ".." entry node */#ifdef UDF_DEBUG DBG_PRINTF(".. FID directory record\r\n");#endif /*UDF_DEBUG*/ /* The FID is that of a directory * Update the first bit of pFileNode->fileCharacteristics in C55x * Update pFileNode->flag in C54x */ return S_PARENT_DIR; } /* Here we make use of "Best fit" theory. The length of file identifier * should not exceed the length specified in the parameters * For as directory, the length of the file identifier should not exceed * the length specified in the udf parameters */ /* Get the compression Id * The file identifier is found at offset of LIU + UDF_INCOMPLETE_FID */ liu = pFileID->lengthOfImplUse; fileIdent = (uint8*)pFileID + UDF_INCOMPLETE_FID + liu; cId = fileIdent[0]; bitStream = &fileIdent[1]; /* Since the length of file identifier should be in words, * the size should be even number of bytes. */ lenFileIdent--; /* decrease by the 1 (COMPRESSION_ID) byte */ if (cId == UDF_STR_08_COMPRESSION_ID) { for(index=0; index<(lenFileIdent); index++) { FileName[index++] = (uint16)*bitStream; // really good SB order ??? bitStream++; } } else if (cId == UDF_STR_16_COMPRESSION_ID) { /* Fill in the name of the file */ for(index=0; index<(lenFileIdent/2); index++) //lenFileIdent/2 must be integral number { wordTmp = *bitStream++; wordTmp = wordTmp | ((*bitStream++) << 8); FileName[index] = wordTmp; } //Here is appended 0 at the end of entry name } lenFileIdent = index; /* number of unicode characters */ /* In the file size field you should update the unresolved File Entry * location */ AllocDescriptor.extLength = pFileID->icb.extLocation.logicalBlockNum; /* Length OK */ /* In the packet.extent update the corresponding partition location */ AllocDescriptor.extPosition = pUDF_desc->partitionLoc[pFileID->icb.extLocation.partitionReferenceNum]; /* Update the file characteristics * The file characteristics are in a byte * We need to extract the bits and appropriately set them * The only useful information is wether it is dir or a file. */ fileChar = (UDF_FileCharact)pFileID->fileCharacteristics; UDF_resolveFIDAddress(fsd, pUDF_desc, &AllocDescriptor); /* Set the pFileNode->fileCharacteristics */ if (fileChar & UDF_FILE_IS_DIRECTORY) { /* The FID is that of a directory * Update the first bit of pFileNode->fileCharacteristics */ error = S_DIR_FOUND; item->dir.DirRecordLba = AllocDescriptor.extLength; lenFileIdent = WideFileNameToUTF8((uint8*)FileName,item->dir.Name, lenFileIdent, &p); item->dir.NameLength = lenFileIdent; // item->dir.ParentOffset = (uint16)Offset; item->dir.ParentOffset = Offset; // OT ParentOffset is now 32 bits#ifdef UDF_DEBUG item->dir.Name[lenFileIdent] = 0; //add 0 at the end of string// DBG_PRINTF("FID (DIR) processed: [%s], extent address: [%dd], length [%dd]\r\n", // item->dir.Name, AllocDescriptor.extPosition, AllocDescriptor.extLength); DBG_PRINTF("D %s %d, %d\r\n", item->dir.Name, AllocDescriptor.extPosition, AllocDescriptor.extLength);#endif /*UDF_DEBUG*/ /* Even Directory inside a directory is considered to be * a file as it can have files inside it that need to be built */ } else { /* the FID is that of a file * Here we need to check whether it is a play list file or not * Check whether the file is part of a play list */ error = S_FILE_FOUND; item->file.ExtentLba = AllocDescriptor.extLength; lenFileIdent = WideFileNameToUTF8((uint8*)FileName,item->file.Name, lenFileIdent, &p); item->file.NameLength = lenFileIdent; //item->file.DirRecordOffset = (uint16)Offset; item->file.DirRecordOffset = Offset; //estrcpy((char*)&(item->file.Name[lenFileIdent+1]),(char*)FileExt,lenOfExt);#ifdef UDF_DEBUG item->file.Name[lenFileIdent] = 0; //add 0 at the end of string// DBG_PRINTF("FID (FILE) processed: [%s], extent address: [%dd], length [%dd]\r\n", // item->file.Name, AllocDescriptor.extPosition,AllocDescriptor.extLength); DBG_PRINTF("F %s, %d, %d\r\n", item->file.Name, AllocDescriptor.extPosition,AllocDescriptor.extLength);#endif } return error; } /* UDF_updateFIDCharacteristics *//* * Function Name : UDF_getFileDataLocations * * Description : This function retrieves all the resolved locations * and lengths of file data space. * * * Parameters : FS_DESCRIPTOR* fsd, * uint8* pBuffer - working buffer for data parsing * uint32 ICB_LBN - address of FE to be parsed * * * Return Value : UDF_ShortAD* pallocation_descriptor_table - table contains descriptors for dir parsing * uint16* pallocation_descriptor_count - number of descriptors in pallocation_descriptor_table * UDF_ALLOC_DESC_FLAG* pallocation_descriptor_flags - if there's special case when dir description is included in actual ICB (3) * GRESULT - S_OK / E_FAIL */GRESULT UDF_getFileDataLocations( FS_DESCRIPTOR* fsd, uint8* pBuffer, uint32 ICB_LBN, UDF_ShortAD* pallocation_descriptor_table, uint16* pallocation_descriptor_count, UDF_ALLOC_DESC_FLAG* pallocation_descriptor_flags, UDF_BOOL split_extents){ GRESULT error = S_OK; uint8* pAD; /* pointer to Allocation Descriptors field in the File Entry */ UDF_FileEntry_i* pFileEntry; /* pointer to file entry */ UDF_ALLOC_DESC_FLAG desc_flags; uint16 icb_flags; /* variable to store the number of allocation descriptors */ uint16 numberOfADs = 0, maxNumberOfADs; /* variable to store length of extended attributes which is obtained in FE */ uint32 lengthExtendedAttr; uint32 lengthAllocDescs; uint16 positionOfAD, countAD; uint16 counter; uint32 temp; /* Variable used for retrieving data * from Allocation desc buffer */ uint16 tempAllocDesc = 0; /* used in case of splitting extents to blocks of sector length */ uint32 extPositionTmp, extLengthTmp; /* These variables are used to differentiate between Long Allocation * Descriptors and Extended Allocation Decsriptors */ PRIVATE_DATA_UDF* pUDF_desc; pUDF_desc = &fsd->PD.UDF_pd; error = UDF_getNode(fsd->did, ICB_LBN, pBuffer); if (error != S_UDF_FILE_ENTRY_FOUND) return error; /* general for all AD */ pFileEntry = (UDF_FileEntry_i*)pBuffer; lengthExtendedAttr = pFileEntry->lengthExtendedAttr; lengthAllocDescs = pFileEntry->lengthAllocDescs; positionOfAD = sizeof(UDF_FileEntry_i) + lengthExtendedAttr; /* jump to AD of the File Entry */ pAD = (uint8*)pFileEntry + positionOfAD; icb_flags = pFileEntry->icbTag.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 */ desc_flags = (UDF_ALLOC_DESC_FLAG)(icb_flags & UDF_MASK_3_BITS); *pallocation_descriptor_flags = desc_flags; /* recognizes the allocation descriptors used */ switch (desc_flags) { case UDF_SHORT_ALLOC_DESC: /* ==0 */ { /* Short allocation descriptors */ numberOfADs = lengthAllocDescs / sizeof(UDF_ShortAD); for (countAD = 0; countAD < numberOfADs; countAD++) { pallocation_descriptor_table[tempAllocDesc].extLength = UDF_getADExtLength(pAD, desc_flags); /* The second 32 bit value of AD holds the location * of the extent. */ pallocation_descriptor_table[tempAllocDesc].extPosition = UDF_getADExtPosition(pAD, desc_flags); /* Add the partition location to the location of * the extent */ pallocation_descriptor_table[tempAllocDesc].extPosition += pUDF_desc->partitionLoc[0]; /* if splitting of long extent into blocks is necessary */ if (UDF_TRUE == split_extents) { extPositionTmp = pallocation_descriptor_table[tempAllocDesc].extPosition; extLengthTmp = pallocation_descriptor_table[tempAllocDesc].extLength; if (extLengthTmp > UDF_LOGICAL_BLOCK_SIZE) { for (counter = 0; counter < (extLengthTmp / UDF_LOGICAL_BLOCK_SIZE); counter ++ ) { pallocation_descriptor_table[tempAllocDesc].extPosition = extPositionTmp; pallocation_descriptor_table[tempAllocDesc].extLength = UDF_LOGICAL_BLOCK_SIZE; extPositionTmp++; tempAllocDesc++; } if (extLengthTmp % UDF_LOGICAL_BLOCK_SIZE) /* add the rest of extent */ { pallocation_descriptor_table[tempAllocDesc].extPosition = extPositionTmp; pallocation_descriptor_table[tempAllocDesc].extLength = extLengthTmp & (UDF_LOGICAL_BLOCK_SIZE - 1); } else tempAllocDesc--; /* already increased index, but no new extent is added in this case */ } } tempAllocDesc++; UDF_jumpToNextAD(&pAD, desc_flags); } *pallocation_descriptor_count = tempAllocDesc; break; } case UDF_LONG_ALLOC_DESC: /* ==1 */ case UDF_EXTENDED_ALLOC_DESC: /* ==2 */ { /* The data is in the form of long or extended allocation * descriptors. * positionOfAD indexes to the location * where the allocation descriptors start */ numberOfADs = UDF_findNumDesc(pAD, desc_flags); maxNumberOfADs = (UDF_LOGICAL_BLOCK_SIZE - positionOfAD) / UDF_getADSize(desc_flags); //[LL] ??? if (numberOfADs > maxNumberOfADs) numberOfADs = maxNumberOfADs; //TBD: and what to do with other AD ??? if (numberOfADs == 0) { numberOfADs = 1; } /* We now need to add the partition location to each of the * addresses */ for (countAD = 0; countAD < numberOfADs; countAD++) { /* do not exceed the file entry *//* if ((UDF_EXT_ATTR_OFFSET + lengthExtendedAttr + (countAD * index8or10) + 5) >= 1024)*/ if ((positionOfAD + (countAD * UDF_getADSize(desc_flags)) + 5) >= 204
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -