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

📄 wrudf.c

📁 linux下的DVD格式udf文件读取库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	wrudf.c * *	Maintains a UDF filing system * */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <sys/resource.h>#include "wrudf.h"#define WRUDF_VERSION 	"0.0.5"char	*devicename;			/* "/dev/cdrom" or disk image filename */int	device;				/* the file descriptor */int	devicetype;enum MEDIUM medium;int	ignoreReadError;		/* used while reading VRS which may be absent on open CDR */#ifdef _GNU_SOURCEchar	*line;#define	GETLINE(prompt) readLine(prompt);#elsechar	line[256];#define GETLINE(prompt) printf(prompt);	fgets(line, 256, stdin); *strchr(line, '\n') = 0;#endifint	cmndc;int	cmndvSize;char**	cmndv;#define FOUND_BEA01	1#define FOUND_NSR02	1<<1#define FOUND_TEA01	1<<2#define FOUND_PVD	1<<8#define FOUND_LVD	1<<9#define FOUND_PD	1<<10#define FOUND_USD	1<<11 uint32_t	found;uint32_t	options;Directory	*rootDir, *curDir;timestamp	timeStamp;regid		entityWRUDF = { 0, "-wrudf (" WRUDF_VERSION ")", "\x04\x05"};extent_ad	extentMainVolDescSeq;extent_ad	extentRsrvVolDescSeq;extent_ad	extentNextVolDescSeq;extent_ad	extentLogVolIntegritySeq;uint32_t	integrityDescBlocknumber;		/* where to write LVID when finished */extent_ad	extentLogVolIntegrityDesc;		/* (continuation) extent for current LVIDs */extern	uint64_t  CDRuniqueID;				/* in wrudf-cdr.c ex VAT FE */struct partitionDesc		*pd;			/* for the writeable partition */uint16_t			virtualPartitionNum  = 0xFFFF;uint32_t			*vat;uint32_t			newVATindex;uint32_t			maxVATindex;uint32_t			prevVATlbn;struct logicalVolDesc		*lvd;struct unallocSpaceDesc		*usd;struct spaceBitmapDesc		*spaceMap;struct logicalVolIntegrityDesc	*lvid;struct fileSetDesc		*fsd;int    				usedSparingEntries;struct sparingTable		*st;int	spaceMapDirty, usdDirty, sparingTableDirty;char* readLine(char* prompt) {    if( line ) {	free(line);    }    return line = readline(prompt);}void initialise(char *devicename) {    uint32_t			i, len, blkno, lastblk, size;    long_ad			*fsdAd;    short_ad			*adSpaceMap;    struct sparablePartitionMap *spm;    char			zeroes[5];    char                        fsdOut[91];    int                         fsdLen;    struct generic_desc 	*p;    struct volStructDesc	*vsd;    initIO(devicename);    memset(zeroes, 0, 5);    /* read Volume Recognition Sequence */    ignoreReadError = 1;    for( blkno = 16; blkno < 256; blkno++ ) {	vsd = readSingleBlock(blkno);	if( vsd == NULL || memcmp(vsd->stdIdent, zeroes, 5) == 0 )	    break;	if( strncmp(vsd->stdIdent, "BEA01", VSD_STD_ID_LEN) == 0 ) {	    found |= FOUND_BEA01;	    continue;	}	if( strncmp(vsd->stdIdent, "NSR02", VSD_STD_ID_LEN) == 0 ) {	    found |= FOUND_NSR02;	    continue;	}	if( strncmp(vsd->stdIdent, "TEA01", 5) == 0 ) {	    found |= FOUND_TEA01;	    continue;	}    }    ignoreReadError = 0;    if( !(found & FOUND_BEA01) || !(found & FOUND_NSR02) || !(found & FOUND_TEA01) )	printf("No UDF VRS\n");    p = NULL;    if( medium == CDR ) {	p = readSingleBlock(512);	if( p == NULL || p->descTag.tagIdent != TAG_IDENT_AVDP )	    fail("No AVDP at block 512 on CDR disc\n");    }    if( !p ) { 	p = readTaggedBlock(256, ABSOLUTE);	if( p->descTag.tagIdent != TAG_IDENT_AVDP ) {	    p = readTaggedBlock(trackSize - 1, ABSOLUTE);	    if( p->descTag.tagIdent != TAG_IDENT_AVDP ) {		p = readTaggedBlock(trackSize - 256, ABSOLUTE);		if( p->descTag.tagIdent != TAG_IDENT_AVDP )		    fail("No AVDP at block 256, N-256 or N-1 \n");	    }		}    }    extentMainVolDescSeq = ((struct anchorVolDescPtr*)p)->mainVolDescSeqExt;    extentRsrvVolDescSeq = ((struct anchorVolDescPtr*)p)->reserveVolDescSeqExt;    /* read Volume Descriptor Sequence */    blkno = extentMainVolDescSeq.extLocation;    len = extentMainVolDescSeq.extLength;    for( i = 0; i < len; blkno++, i += 2048 ) {	int	inMainSeq = 1;	if( (p = readTaggedBlock(blkno, ABSOLUTE)) == NULL ) {	    if( !inMainSeq ) 		fail("Volume Descriptor Sequences read failure\n");	    blkno = extentRsrvVolDescSeq.extLocation;	    len = extentRsrvVolDescSeq.extLength;	    inMainSeq = 0;	    i = 0;	}	switch( p->descTag.tagIdent ) {	case TAG_IDENT_PVD:	    found |= FOUND_PVD;	    break;	case TAG_IDENT_VDP:	    blkno = ((struct volDescPtr*)p)->nextVolDescSeqExt.extLocation - 1;	    len   = ((struct volDescPtr*)p)->nextVolDescSeqExt.extLength;	    i = (uint32_t) -2048;	    break;	case TAG_IDENT_IUVD:	    break;	case TAG_IDENT_PD:	    /* must have one (re)writeable partition */	    /* may have at most one RDONLY partition */	    switch( ((struct partitionDesc *)p)->accessType ) {	    case PD_ACCESS_TYPE_READ_ONLY:		break;	    case PD_ACCESS_TYPE_REWRITABLE:	    case PD_ACCESS_TYPE_WRITE_ONCE:		found |= FOUND_PD;		if( !pd )		    pd  = (struct partitionDesc*) calloc(512, 1);		if( p->volDescSeqNum > pd->volDescSeqNum )		    memcpy(pd, p, 512);		break;	    default:		printf("What to do with an accesstype %d partition?\n", 		    ((struct partitionDesc*)p)->accessType);		break;	    }	    break;	case TAG_IDENT_LVD:	    found |= FOUND_LVD;	    if( !lvd )		lvd  = (struct logicalVolDesc*) calloc(512, 1);	    if( p->volDescSeqNum > lvd->volDescSeqNum )		memcpy(lvd, p, 512);	    break;	case TAG_IDENT_USD:	    found |= FOUND_USD;	    if( !usd )		usd = (struct unallocSpaceDesc*) calloc(512, 1);	    if( p->volDescSeqNum > usd->volDescSeqNum )		memcpy(usd, p, 512);	    break;	case TAG_IDENT_TD:	    i = len;	    break;	default:	    printf("Unexpected tag ID %04X\n in Volume Descriptor Sequence block %d", p->descTag.tagIdent, blkno);	}    }    if( (found & FOUND_LVD) == 0 )	fail("No LVD found \n");    if( lvd->logicalBlockSize != 2048 )	fail("Blocksize not 2048\n");    spm  = (struct sparablePartitionMap*)lvd->partitionMaps;    for( i = 0; i < lvd->numPartitionMaps; i++ ) {	if( spm->partitionMapType == 2 ) {	    if( strncmp( spm->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)) == 0 ) {		int	j;		if( spm->sizeSparingTable > 2048 )		    fail("Cannot handle SparingTable > 2048 bytes");		st = (struct sparingTable*)malloc(2048);		p = readTaggedBlock(spm->locSparingTable[0], ABSOLUTE);		memcpy(st, p, spm->sizeSparingTable);		/* if #1 fails, try #2; should pick copy with highest sequenceNum */		for( j = usedSparingEntries = 0; j < (spm->sizeSparingTable >> 3); j++ ) {		     if( st->mapEntry[j].origLocation < 0xFFFFFFF0 )			 usedSparingEntries++;		}	    } else if( strncmp( spm->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)) == 0 )		virtualPartitionNum = i;	}	(char*)spm += spm->partitionMapLength;    }    if( medium == CDR ) {	if( virtualPartitionNum != 0xFFFF )	    readVATtable();	else 	    fail("No Virtual Partition Map on CDR\n");    }    if( medium != CDR && (found & FOUND_USD) == 0 )	fail("Did not find Unallocated Space Descriptor\n");    /* Read Fileset Descriptor Sequence */    fsdAd = (long_ad*) lvd->logicalVolContentsUse;    for( i = 0; i < (fsdAd->extLength >> 11); i++ ) {	blkno = pd->partitionStartingLocation + fsdAd->extLocation.logicalBlockNum + i;	if( !(p = readTaggedBlock(blkno, ABSOLUTE)) ) 	    exit(1);	switch( p->descTag.tagIdent ) {	case TAG_IDENT_TD:	    i = fsdAd->extLength;	    break;	case TAG_IDENT_FSD:	    if( fsd && (lvd->volDescSeqNum > p->volDescSeqNum) )		break;	    fsd = (struct fileSetDesc*)malloc(512);	    memcpy(fsd, p, 512);	    break;	default:	    printf("Unxpected tag id %d, where File Set Desc(256) expected\n", p->descTag.tagIdent);	}    }    if( !fsd )	fail("No File Set Descriptor\n");    /* load Spacemap extent */    adSpaceMap = (short_ad*) &((struct partitionHeaderDesc*)pd->partitionContentsUse)->unallocSpaceBitmap;    if( adSpaceMap->extLength != 0 ) {	blkno = adSpaceMap->extPosition;	len = adSpaceMap->extLength;	spaceMap = (struct spaceBitmapDesc*) malloc((len + 2047) & ~2047);	for( i = 0; i < len; i += 2048 ) {	    p = readBlock(blkno, 0);	    memcpy( (uint8_t*)spaceMap + i, (uint8_t*) p, 2048);	    freeBlock(blkno++, 0);	}	if( spaceMap->descTag.tagIdent != TAG_IDENT_SBD )	    fail("SpaceBitmap not found\n");    }    if (fsdLen = decode_utf8(fsd->fileSetIdent, fsdOut, fsd->fileSetIdent[31]))        fsdOut[fsdLen] = '\0';    printf("You are going to update fileset '%s'\nProceed (y/N) : ", &fsdOut[1]);    readLine(NULL);    if( (line[0] | ' ') != 'y' )	fail("wrudf terminated\n");    /* Read Logical Volume Integrity sequence */    blkno = lvd->integritySeqExt.extLocation;    lastblk = blkno + (lvd->integritySeqExt.extLength >> 11);    extentLogVolIntegrityDesc = lvd->integritySeqExt;    for(   ; blkno < lastblk; blkno++ ) {	if( !(p = readTaggedBlock(blkno, ABSOLUTE))  ) 	    fail("Read failure in Integrity Sequence, blk %d\n", blkno);	switch( p->descTag.tagIdent ) {	case TAG_IDENT_TD:	    blkno = lastblk;	    break;	case TAG_IDENT_LVID:	    size = sizeof(struct logicalVolIntegrityDesc) + sizeof(struct logicalVolIntegrityDescImpUse)		+ 2 * sizeof(uint32_t) * ((struct logicalVolIntegrityDesc*)p)->numOfPartitions;	    if( !lvid )		lvid = (struct logicalVolIntegrityDesc*) malloc(size);	    integrityDescBlocknumber = blkno;	    memcpy(lvid, p, size);	    if( lvid->nextIntegrityExt.extLocation ) {		extentLogVolIntegrityDesc = lvid->nextIntegrityExt;		blkno = lvid->nextIntegrityExt.extLocation;		lastblk = blkno + (lvid->nextIntegrityExt.extLength >> 11);		blkno--;					/* incremented again in for statement */	    }	    break;	default:	    printf("Unxpected tag %X in Integrity Sequence; blk %d\n", p->descTag.tagIdent, blkno);	    blkno = lastblk;	    break;	}    }    if( !lvid || lvid->descTag.tagIdent != TAG_IDENT_LVID  )	fail("No Logical Volume Integrity Descriptor\n");    if( medium == CDR && lvid->integrityType == LVID_INTEGRITY_TYPE_CLOSE )	fail("CDR volume has been closed\n");    if( medium == CDR )	// take from VAT FileEntry	((struct logicalVolHeaderDesc*)lvid->logicalVolContentsUse)->uniqueID = CDRuniqueID;        curDir = rootDir = (Directory*)malloc(sizeof(Directory));    memset(rootDir, 0, sizeof(Directory));    rootDir->dataSize = 4096;    rootDir->data = (uint8_t*)malloc(4096);

⌨️ 快捷键说明

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