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

📄 wrudf-cmnd.c

📁 linux下的DVD格式udf文件读取库
💻 C
📖 第 1 页 / 共 3 页
字号:
 *	irrespective whether they were embedded or separately in allocated extents. *	updateDirectory() will embed or write in separate extents as appropriate. */Directory * readDirectory(Directory *parentDir, long_ad* icb, char *name) {    char	*p;    uint32_t	len;    Directory	*dir;    if( parentDir == NULL ) 	dir = rootDir;    else {	dir = parentDir->child;	if( dir == NULL ) {	    parentDir->child = dir = (Directory*)malloc(sizeof(Directory));	    memset(dir, 0, sizeof(Directory));	    dir->parent = parentDir;	    dir->dataSize = 4096;	    dir->data = (uint8_t*)malloc(4096);	    if( dir->name ) free(dir->name);	    dir->name = malloc(strlen(name) + 1);	    strcpy(dir->name, name);	} else 	    if( dir->icb.extLocation.logicalBlockNum == icb->extLocation.logicalBlockNum		&& dir->icb.extLocation.partitionReferenceNum == icb->extLocation.partitionReferenceNum )		return dir;		// already the one requested    }    if( dir->dirDirty )	updateDirectory(dir);    dir->icb = *icb;    if( name[0] ) {	if( dir->name ) free(dir->name);	dir->name = malloc(strlen(name) + 1);	strcpy(dir->name, name);    }    p = readTaggedBlock(icb->extLocation.logicalBlockNum, icb->extLocation.partitionReferenceNum);    memcpy(&dir->fe, p, 2048);    if( (dir->fe.icbTag.flags & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_IN_ICB ) {	memcpy(dir->data, dir->fe.allocDescs + dir->fe.lengthExtendedAttr, dir->fe.lengthAllocDescs);	memset(dir->fe.allocDescs + dir->fe.lengthExtendedAttr, 0, dir->fe.lengthAllocDescs);    } else {	if( dir->fe.informationLength > dir->dataSize ) {	    len = (dir->fe.informationLength + 2047) & ~2047;	    dir->data = realloc(dir->data, len);	    if( !dir->data ) {		printf("Realloc directory data failed\n");		return NULL;	    }	    dir->dataSize = len;	}	readExtents(dir->data, (dir->fe.icbTag.flags & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_SHORT,	    dir->fe.allocDescs + dir->fe.lengthExtendedAttr);	if( medium == CDRW ) {	    if( (dir->fe.icbTag.flags & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_SHORT )		freeShortExtents((short_ad*)(dir->fe.allocDescs + dir->fe.lengthExtendedAttr));	    else if( (dir->fe.icbTag.flags & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_LONG )		freeLongExtents((long_ad*)(dir->fe.allocDescs + dir->fe.lengthExtendedAttr));	}    }    printf("Read dir %s\n", dir->name);    return dir;}/*	updateDirectory() *	Extents and ICB AllocMask are unchanged since reading the directory from CD. *	Based on current informationLength will have to decide embedding or on output extents required *	and free any superfluous extents */int updateDirectory(Directory* dir) {    int		i;    struct fileIdentDesc *fid;    if( dir->child )	updateDirectory(dir->child);    if( !dir->dirDirty )	return CMND_OK;    if( sizeof(struct fileEntry) + dir->fe.lengthExtendedAttr + dir->fe.informationLength <= 2048 ) {			        /* fileIdentDescs embedded in directory ICB */	dir->fe.logicalBlocksRecorded = 0;	dir->fe.icbTag.flags = (dir->fe.icbTag.flags & ~ICBTAG_FLAG_AD_MASK) | ICBTAG_FLAG_AD_IN_ICB;	dir->fe.lengthAllocDescs = dir->fe.informationLength;	memcpy(dir->fe.allocDescs + dir->fe.lengthExtendedAttr, dir->data, dir->fe.lengthAllocDescs);	/* UDF2.00 2.2.1.3  - For a structure in virtual space, tagLocation is the virtual location */	for( i = 0; i < dir->fe.informationLength;	     i += (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3 ) 	{	    fid = (struct fileIdentDesc*) (dir->fe.allocDescs + i);	    fid->descTag.tagLocation = dir->icb.extLocation.logicalBlockNum;	    setChecksum(&fid->descTag);	}    } else {	/* get new extents for the directory data */	dir->fe.logicalBlocksRecorded = ((dir->fe.informationLength + 2047) & ~2047) >> 11;	if( medium == CDR ) {	    long_ad *ad;	    uint32_t	blkno;	    dir->fe.icbTag.flags = (dir->fe.icbTag.flags & ~ ICBTAG_FLAG_AD_MASK) | ICBTAG_FLAG_AD_LONG;	    ad = (long_ad*)(dir->fe.allocDescs + dir->fe.lengthExtendedAttr);	    ad->extLength = dir->fe.informationLength;	    ad->extLocation.logicalBlockNum  =  blkno = getNWA() + 1 - pd->partitionStartingLocation;	    ad->extLocation.partitionReferenceNum = pd->partitionNumber;	    *(uint32_t*)&((struct allocDescImpUse*)(ad->impUse))->impUse = (uint32_t) dir->fe.uniqueID;	    memset(ad + 1, 0, sizeof(long_ad));			/* necessary only if infolength multiple of 2048 */	    dir->fe.lengthAllocDescs = 2 * sizeof(long_ad);	    /* set tagLocation in all FIDs */	    for( i = 0; i < dir->fe.informationLength;		 i += (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3 ) 	    {		fid = (struct fileIdentDesc*) (dir->data + i);		fid->descTag.tagLocation = blkno + (i >> 11);		fid->descTag.descCRCLength = 		    ((sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3) - sizeof(tag);		setChecksum(fid);	    }	} else {	    uint32_t	*blocks, blkno, len;	    short_ad	*extent;	    extent =(short_ad*)(dir->fe.allocDescs + dir->fe.lengthExtendedAttr);	    dir->fe.lengthAllocDescs = getExtents(dir->fe.informationLength, extent);	    dir->fe.icbTag.flags = (dir->fe.icbTag.flags & ~ICBTAG_FLAG_AD_MASK) | ICBTAG_FLAG_AD_SHORT;	    /* find which blocks are to going be used to set tagLocations */	    blocks = (uint32_t*)malloc(dir->fe.logicalBlocksRecorded * sizeof(uint32_t));	    blkno = extent->extPosition;	    len = extent->extLength;	    for( i = 0; i < dir->fe.logicalBlocksRecorded; i++ ) {		blocks[i] = blkno;		if( len <= 2048 ) {		    extent++;		    blkno = extent->extPosition;		    len = extent->extLength;		} else {		    len -= 2048;		    blkno++;		}	    }	    /* set tagLocation */	    for( i = 0; i < dir->fe.informationLength;		 i += (sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3 ) 	    {		fid = (struct fileIdentDesc*) (dir->data + i);		fid->descTag.tagLocation = blocks[i >> 11];		fid->descTag.descCRCLength = 		    ((sizeof(struct fileIdentDesc) + fid->lengthOfImpUse + fid->lengthFileIdent + 3) & ~3) - sizeof(tag);		setChecksum(fid);	    }	    free(blocks);	}    }    dir->fe.descTag.descCRCLength = 	sizeof(struct fileEntry) + dir->fe.lengthExtendedAttr + dir->fe.lengthAllocDescs - sizeof(tag);    setChecksum(&dir->fe);    if( medium == CDRW ) {	/* write the directory fileEntry */	writeBlock(dir->icb.extLocation.logicalBlockNum, dir->icb.extLocation.partitionReferenceNum, &dir->fe);	if( dir->fe.logicalBlocksRecorded  ) {	    /* write any directory data */	    writeExtents(dir->data, 1, (short_ad*)(dir->fe.allocDescs + dir->fe.lengthExtendedAttr));	}    } else {		/* medium == CDR */	int retries;	retries = 0;	for( ;; ) {					/* loop only when verify failed */	    uint32_t	pbn;	    /* write the directory fileEntry */	    pbn = writeCDR(&dir->fe);	    vat[((long_ad*)&dir->icb)->extLocation.logicalBlockNum] = pbn - pd->partitionStartingLocation;	    if( dir->fe.logicalBlocksRecorded )		for( i = 0; i < dir->fe.informationLength; i += 2048 )		    writeCDR(dir->data + i);	    if( verifyCDR(&dir->fe) == 0 )		break;	    if( ++retries > 3 ) {		printf("updateDirectory: '%s' failed\n", dir->name);		return CMND_FAILED;	    }	}    }    dir->dirDirty = 0;    printf("Wrote dir %s\n", dir->name);    return CMND_OK;}/*	Create subdirectory called 'name' in 'dir'  */Directory * makeDir(Directory *dir, char* name ) {    int			rv;    Directory		*newDir;    struct fileEntry	*fe;    struct fileIdentDesc *backFid, *forwFid;    short_ad		allocDescs[2];    /* back reference to parent in new directory */    backFid = makeFileIdentDesc("");    backFid->icb = dir->icb;    backFid->fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;    backFid->descTag.descCRCLength = ((sizeof(struct fileIdentDesc) + 3) & ~3) - sizeof(tag);    fe = makeFileEntry();    fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY;    fe->icbTag.flags = ICBTAG_FLAG_AD_IN_ICB;    fe->informationLength = (sizeof(struct fileIdentDesc) + 3) & ~3;    /* forward reference to new directory in parent directory */    forwFid = makeFileIdentDesc(name);    forwFid->fileCharacteristics = FID_FILE_CHAR_DIRECTORY;    *(uint32_t*)(&( (struct allocDescImpUse*)forwFid->icb.impUse)->impUse) = (uint32_t) fe->uniqueID;    if( medium == CDR ) {	fe->descTag.tagLocation = newVATentry();	forwFid->icb.extLocation.logicalBlockNum = fe->descTag.tagLocation;	forwFid->icb.extLocation.partitionReferenceNum = virtualPartitionNum;    } else {	if(  getExtents( 2048, allocDescs) != 16 )	    fail("makeDir: Could not get File Entry extent\n");	markBlock(ALLOC, allocDescs[0].extPosition);	fe->descTag.tagLocation = allocDescs[0].extPosition;	backFid->descTag.tagLocation = allocDescs[0].extPosition;	forwFid->icb.extLocation.logicalBlockNum = allocDescs[0].extPosition;	forwFid->icb.extLocation.partitionReferenceNum = pd->partitionNumber;	setChecksum(&backFid->descTag);	fe->descTag.descCRCLength = sizeof(struct fileEntry) + fe->lengthAllocDescs - sizeof(tag);	setChecksum(fe);    }    rv = insertFileIdentDesc(dir, forwFid);    dir->fe.fileLinkCount++;    dir->dirDirty = 1;    /* setup directory structure for new directory */    newDir = dir->child;    if( newDir != NULL ) 	updateDirectory(newDir);    else {	newDir = (Directory*)malloc(sizeof(Directory));	memset(newDir, 0, sizeof(Directory));	newDir->parent = dir;	newDir->dataSize = 4096;	newDir->data = (uint8_t*)malloc(4096);	dir->child = newDir;    }        memset(newDir->data, 0, newDir->dataSize);    newDir->name = malloc(strlen(name)+1);    strcpy(newDir->name, name);    newDir->icb = forwFid->icb;    memcpy(&newDir->fe, fe, 2048);    memcpy(newDir->data, backFid, fe->informationLength);    newDir->dirDirty = 1;    ((struct logicalVolIntegrityDescImpUse*)	(lvid->impUse + 2 * sizeof(uint32_t) * lvid->numOfPartitions))->numDirs++;    free(backFid);    free(forwFid);    free(fe);    return newDir;}/*	analyzeDest() * *	The last argument in a command is the destination for copying or the object *	to act on. The argument consists of / separated components  *	eg. /src/test/udf/wrudf.h or /src/test/iso/ *	or just a single component eg. . or / or wrudf.c * *	All but the last component must be existing directories and curDir points to *	the last directopry in that chain, eg. udf, otherwise result DIR_INVALID. * *	When the last component does not exist, return result DOES_NOT_EXIST. *	name --> last component eg. wrudf.h or iso * *	If the last component identifies a directory return EXISTING_DIR or DELETED_DIR, *	*fid = NULL, *name = last component name eg. iso. * *	If the last component is a file  return EXISTING_FILE or DELETED_FILE. *	*fid points to FID entry in curDir with name equal the last component. *	*name --> last component name eg. wrudf.h */enum RV analyzeDest(char* arg, struct fileIdentDesc** fid, char** name) {    int		len;    char 	*comp, *endComp;    if( arg[0] == '/' ) {	curDir = rootDir;	comp = arg + 1;    } else {	comp = arg;    }    len = strlen(comp);    if( len > 1 && comp[len-1] == '/' )	comp[len-1] = 0;				/* remove any trailing slash */    for(  ; ( endComp = strchr(comp, '/') ) != NULL; comp = ++endComp ) {	*endComp = 0;	if( strcmp(comp, ".") == 0 )	    continue;	if( strcmp(comp, "..") == 0 ) {	    if( !curDir->parent )		return DIR_INVALID;	    curDir = curDir->parent;	    continue;	}		*fid = findFileIdentDesc(curDir, comp);	if( *fid == NULL )	    return DIR_INVALID;	if( ! (*fid)->fileCharacteristics & FID_FILE_CHAR_DIRECTORY )	    return DIR_INVALID;	if( (*fid)->fileCharacteristics & FID_FILE_CHAR_DELETED )	    return DIR_INVALID;//	curDir = readDirectory(curDir->child, &(*fid)->icb, comp); 	curDir = readDirectory(curDir, &(*fid)->icb, comp);     }    // final component    *name = comp;    if( comp[0] == 0 || strcmp(comp, ".") == 0 )	return EXISTING_DIR;

⌨️ 快捷键说明

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