⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wrudf-desc.c

📁 linux下的DVD格式udf文件读取库
💻 C
字号:
/*	wrudf-desc.c   * * PURPOSE *	Routines to create/find/insert/delete FileIdentDesc's and FileEntries. *   * CONTACTS *	E-mail regarding this program to *		e.fennema@dataweb.nl * * COPYRIGHT *	This file is distributed under the terms of the GNU General Public *	License (GPL). Copies of the GPL can be obtained from: *		ftp://prep.ai.mit.edu/pub/gnu/GPL * *	(C) 2001 Enno Fennema * * HISTORY *  	16 Aug 01  ef  Created. */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include "wrudf.h"/*	removeFID() * *	Physically remove a FileIdentDesc from the directory */intremoveFID(Directory *dir, struct fileIdentDesc *fid) {    uint32_t lenFID = (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3;    uint32_t lenMove;    dir->fe.informationLength -= lenFID;    lenMove = dir->fe.informationLength - ((uint8_t*)fid - dir->data);    memcpy(fid, (uint8_t*)fid + lenFID, lenMove);    dir->dirDirty = 1;    return 0;}/*	deleteFID() * *	Remove an FID from the directory *	If fileLinkCount now zero, deallocate FileEntry and any data extents */int deleteFID(Directory * dir, struct fileIdentDesc * fid){    int		rv;    struct fileEntry *fe;    rv = CMND_OK;//    if( fid->icb.extLocation.partitionReferenceNum != pd->partitionNumber )//	return NOT_IN_RW_PARTITION;    fe = readTaggedBlock(fid->icb.extLocation.logicalBlockNum, fid->icb.extLocation.partitionReferenceNum);    /* check permission */    freeBlock(fid->icb.extLocation.logicalBlockNum, fid->icb.extLocation.partitionReferenceNum);    if( fe->fileLinkCount > 1 ) {	fe->fileLinkCount--;	setChecksum(fe);	if( medium == CDRW ) 	    dirtyBlock(fid->icb.extLocation.logicalBlockNum, fid->icb.extLocation.partitionReferenceNum);	else	    vat[fid->icb.extLocation.logicalBlockNum] = writeCDR(fe);    } else {	if( medium == CDR ) {	    if( fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY )		dir->fe.fileLinkCount--;	    vat[fid->icb.extLocation.logicalBlockNum] = 0xFFFFFFFF;		} else {	    if( fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY ) {		dir->fe.fileLinkCount--;		((struct logicalVolIntegrityDescImpUse*)		    (lvid->impUse + 2 * sizeof(uint32_t) * lvid->numOfPartitions))->numDirs--;	    } else {		((struct logicalVolIntegrityDescImpUse*)		    (lvid->impUse + 2 * sizeof(uint32_t) * lvid->numOfPartitions))->numFiles--;	    }	    /* free file data */	    switch( fe->icbTag.flags & ICBTAG_FLAG_AD_MASK ) {	    case ICBTAG_FLAG_AD_IN_ICB:		break;	    case ICBTAG_FLAG_AD_SHORT:		freeShortExtents((short_ad*)(fe->allocDescs + fe->lengthExtendedAttr));		break;	    case ICBTAG_FLAG_AD_LONG:		freeLongExtents((long_ad*)(fe->allocDescs + fe->lengthExtendedAttr));		break;	    default:		printf("UDF does not use Extended Alloc Descs\n");		rv = CMND_FAILED;	    }	/* free the File Entry itself */	markBlock(FREE, fid->icb.extLocation.logicalBlockNum);	}    }    removeFID(dir, fid);    dir->dirDirty = 1;    return rv;}struct fileIdentDesc* findFileIdentDesc(Directory *dir, char* name) {    int			i;    uint8_t		*data;    struct fileIdentDesc *fid;    char                uName[256];    int                 uLen;    uLen = encode_utf8(uName, "", name, 256);    data = dir->data;    for( i = 0; i < dir->fe.informationLength; 	 i += (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3 ) {	fid = (struct fileIdentDesc*)(data + i);	if( fid->descTag.tagIdent == TAG_IDENT_TE )	    return NULL;	if( fid->descTag.tagIdent == TAG_IDENT_IE ) {	    printf("Indirect Entry not yet implemented\n");	    continue;	}	if( fid->descTag.tagIdent != TAG_IDENT_FID )	    fail("Unknown tag id %08X in directory\n", fid->descTag.tagIdent);	// check CRC	if( fid->fileCharacteristics == FID_FILE_CHAR_PARENT)	    continue;	if( fid->lengthFileIdent == uLen	    && memcmp( fid->fileIdent, uName, fid->lengthFileIdent) == 0 )	    return fid;    }    return NULL;}/* *	Return pointer to new FileEntry in a 2k allocated block to be free'd when no longer required. *	Only basic data is filled in.  */struct fileEntry* makeFileEntry() {    struct fileEntry *fe = (struct fileEntry*) calloc(2048, 1);    updateTimestamp(0,0);    fe->descTag.tagIdent = TAG_IDENT_FE;    fe->descTag.descVersion = 2;    fe->descTag.tagSerialNum = lvd->descTag.tagSerialNum;    fe->icbTag.strategyType = 4;    fe->icbTag.numEntries = 1;    fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR;    /* User has all permission; Group/Others Read/Exec */    fe->permissions = FE_PERM_U_READ | FE_PERM_U_WRITE | FE_PERM_U_DELETE | FE_PERM_U_CHATTR | FE_PERM_U_EXEC |	FE_PERM_G_READ | FE_PERM_G_EXEC | FE_PERM_O_READ | FE_PERM_O_EXEC;    fe->fileLinkCount = 1;    fe->accessTime = timeStamp;    fe->modificationTime = timeStamp;    fe->attrTime = timeStamp;    fe->impIdent = entityWRUDF;    fe->uniqueID = ((struct logicalVolHeaderDesc*)lvid->logicalVolContentsUse)->uniqueID++;    return fe;}/* *	Return pointer to new FileIdentDesc in an allocated block to be free'd when no longer required. *	Does NOT fill: descTag.checksum, descTag.tagLocation, icbTag.characteristics, icb */struct fileIdentDesc*makeFileIdentDesc(char* name) {    char uName[256];    int uLen;    struct fileIdentDesc *fid;    fid = (struct fileIdentDesc*) calloc(512,1);    fid->descTag.tagIdent = TAG_IDENT_FID;    fid->descTag.descVersion = 2;    fid->descTag.tagSerialNum = lvd->descTag.tagSerialNum;    fid->fileVersionNum = 1;    fid->icb.extLength = 2048;    if( name[0] != 0 ) {				/* FID to parent directory has no name */	memset(&uName, 0, 256);        uLen = encode_utf8(uName, "", name, 256);	fid->lengthFileIdent = uLen;	memcpy(fid->fileIdent + fid->lengthOfImpUse, uName, fid->lengthFileIdent);    }    return fid;} int insertFileIdentDesc(Directory *dir, struct fileIdentDesc* fid) {    uint32_t		lenFid;        lenFid = (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3;    fid->descTag.descCRCLength = lenFid - sizeof(tag);    setChecksum(fid);    if( dir->fe.informationLength + lenFid > dir->dataSize ) {	if( !(dir->data = realloc(dir->data, dir->dataSize + 2048)) ) {	    fail("Realloc directory data failed\n");	}	dir->dataSize += 2048;    }        memcpy(dir->data + dir->fe.informationLength, fid, lenFid);    dir->fe.informationLength += lenFid;    dir->dirDirty = 1;    return CMND_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -