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

📄 wrudf-cdrw.c

📁 linux下的DVD格式udf文件读取库
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	setStrictRead(0);    } else { // DISK_IMAGE#ifdef DEBUG_SPARING						// force sparing on packets of disk image 	if( st ) {	    if( physical == 0x820 || physical == 0x880 ) 	// arbitrary 'bad' blocks		physical = newSparingTableEntry(pb->start);	}#endif	stat= lseek(device, 2048 * physical, SEEK_SET);	stat = write(device, pb->pkt, 32 * 2048);	if( stat < 0 )	    fail("writePacket: writeHD failed %m\n");    }    return stat;}struct packetbuf* findBuf(uint32_t blkno) {    struct packetbuf *b;    blkno &= ~31;    for(b = &pktbuf[0]; b < &pktbuf[MAXPKTBUFS]; b++ ) {	if( blkno == b->start )	    return b;    }    return NULL;}struct packetbuf* getFreePacketBuffer(uint32_t lbn, uint16_t part){    struct packetbuf	*b, *bFree, *bMustWrite;    uint32_t		blkno;    blkno = lbn + ( part == 0xFFFF ? 0 : pd->partitionStartingLocation );     bFree = bMustWrite = NULL;    for( b = &pktbuf[0]; b < &pktbuf[MAXPKTBUFS]; b++ ) {	if( (b->inuse | b->dirty) == 0 ) {	    bFree = b;	    break;	} else	    if( b->inuse == 0 )		bMustWrite = b;    }    if( !bFree && !bMustWrite ) {	printf("readBlock: Permission to panic, Sir!!!\n");	return NULL;    }    if( !bFree ) {	writePacket(bMustWrite);	bMustWrite->inuse = 0;	bMustWrite->dirty = 0;	bFree = bMustWrite;    }    bFree->start = blkno & ~31;    return bFree;}void* readBlock(uint32_t lbn, uint16_t part) {    struct packetbuf *b;    uint32_t	physical = getPhysical(lbn, part);    if( medium == CDR )	return readCDR(physical, ABSOLUTE);    b = findBuf(physical);    if( !b ) {	b = getFreePacketBuffer(lbn, part);	readPacket(b);    }    b->inuse |= 0x80000000 >> (lbn & 31);    return b->pkt + ((lbn & 31) << 11);}void* readSingleBlock(uint32_t pbn) {    int stat;    if( devicetype != DISK_IMAGE ) {	stat = readCD(device, sectortype, pbn, 1, blockBuffer);	if( stat ) {	    if( ! ignoreReadError )		printf("readSingleBlock: %s\n", get_sense_string());    	    return NULL;	} else 	    return blockBuffer;    } else {	stat = lseek(device, 2048 * pbn, SEEK_SET);	stat = read(device, blockBuffer, 2048);	if( stat != 2048 )	    return NULL;	else	    return blockBuffer;    }}void freeBlock(uint32_t lbn, uint16_t part) {    struct packetbuf	*b;    uint32_t			blkno;    if( medium == CDR ) return;    blkno = lbn + ( part == 0xFFFF ? 0 : pd->partitionStartingLocation );    b = findBuf(blkno);    if( !b )	fail("freeBlock failed on block %d\n", blkno);    b->inuse &=  ~(0x80000000 >> (blkno & 31));		/* turn off INUSE bit */}void dirtyBlock(uint32_t lbn, uint16_t part) {    struct packetbuf	*pb;    uint32_t			blkno;    blkno = lbn + ( part == 0xFFFF ? 0 : pd->partitionStartingLocation );    pb = findBuf(blkno);    if( !pb )	fail("dirtyBlock failed on block %d\n", blkno);    pb->dirty |=  0x80000000 >> (blkno & 31);		/* turn on DIRTY bit */}voidwriteBlock(uint32_t lbn, uint16_t part, void* src) {    char *p;    p = readBlock(lbn, part);    memcpy(p, src, 2048);    if( part != ABSOLUTE )	markBlock(ALLOC, lbn);    dirtyBlock(lbn, part);    freeBlock(lbn, part);}void* readTaggedBlock(uint32_t lbn, uint16_t partition) {    int		i;    uint32_t	blkno;    uint8_t	sum, *p;    struct generic_desc *block;    if( medium == CDR )	block = (struct generic_desc*) readCDR(lbn, partition);    else { 	block = (struct generic_desc*) readBlock(lbn, partition);	freeBlock(lbn,partition);	if( !block )	    return block;    }    if( block->descTag.tagIdent == 0x0000 ) {	/* ignore not ISO 13346 defined descriptors with 0 tags */	if( strncmp(((struct sparingTable*)block)->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)) != 0 ) {	    for( i = 0; i < 2048; i++ ) {		if( ((uint8_t*)block)[i] != 0 ) {		    printf("readTaggedBlock: Empty block %d not all zeroes\n", blkno);		    break;		}	    }	    return block;	}    }    for( i = 0, sum = 0, p = (uint8_t*)block; i< 16; i++ )	if( i != 4 )	    sum += *(p + i);    if( block->descTag.tagChecksum != sum )	fail("readTagged: Checksum error in block %d\n", blkno);    if( block->descTag.descCRC != udf_crc((uint8_t*)block + sizeof(tag), ((tag*)block)->descCRCLength, 0) )	fail("readTagged: CRC error in block %d\n", blkno);    return block;}intreadExtents(char* dest, int usesShort, void* extents) {    uint	len, blkno, partitionNumber;    char	*p;    long_ad	*lo;    short_ad	*sh;    if( usesShort ) {	sh = (short_ad*) extents;	len = sh->extLength;	blkno = sh->extPosition;	partitionNumber  = pd->partitionNumber;    } else {	lo = (long_ad*) extents;	len = lo->extLength;	blkno = lo->extLocation.logicalBlockNum;	partitionNumber = lo->extLocation.partitionReferenceNum;    }    for(;;) {	p = readBlock(blkno, partitionNumber);	memcpy(dest, p, 2048);	freeBlock(blkno, partitionNumber);	dest += 2048;	if( len < 2048 )	    break;	if( len == 0 ) {	    if( usesShort ) {		sh++;		len = sh->extLength;		blkno = sh->extPosition;	    } else {		lo++;		len = lo->extLength;		blkno = lo->extLocation.logicalBlockNum;		partitionNumber = lo->extLocation.partitionReferenceNum;	    }	    if( len == 0 )		break;	    continue;	}	len -= 2048;	blkno++;    }     return CMND_OK;}    intwriteExtents(char* src, int usesShort, void* extents) {    uint	len, blkno, partitionNumber;    long_ad	*lo;    short_ad	*sh;    if( usesShort ) {	sh = (short_ad*) extents;	len = sh->extLength;	blkno = sh->extPosition;	partitionNumber  = pd->partitionNumber;    } else {	lo = (long_ad*) extents;	len = lo->extLength;	blkno = lo->extLocation.logicalBlockNum;	partitionNumber = lo->extLocation.partitionReferenceNum;    }    for(;;) {	writeBlock(blkno, partitionNumber, src);	src += 2048;	if( len < 2048)	    break;	if( len == 2048 ) {	    if( usesShort ) {		sh++;		len = sh->extLength;		blkno = sh->extPosition;	    } else {		lo++;		len = lo->extLength;		blkno = lo->extLocation.logicalBlockNum;		partitionNumber = lo->extLocation.partitionReferenceNum;	    }	    if( len == 0 )		break;	    continue;	}	len -= 2048;	blkno++;    }    return CMND_OK;}    intinitIO(char *filename) {    struct packetbuf *pb;    int		rv;    struct stat filestat;    struct cdrom_discinfo  di;    u_char *buffer;    struct cdrom_writeparams *wp;    uint16_t	ident;    if( (rv = stat(filename, &filestat)) < 0 )	fail("initIO: stat on %s failed\n", filename);    if( S_ISREG(filestat.st_mode) ) {		/* disk image of a UDF volume */	devicetype = DISK_IMAGE;	if( !(device = open(filename, O_RDWR)) )	    fail("initIO: open %s failed\n", filename);	/* heuristically determine medium imitated on disk image based on VAT FileEntry in block 512 */	rv = lseek(device, 2048 * 512, SEEK_SET);	rv = read(device, &ident, 2);	medium = ident == TAG_IDENT_VDP ? CDR : CDRW;    }    if( (blockBuffer = malloc(2048)) == NULL )	fail("malloc blockBuffer failed\n");    if( devicetype == DISK_IMAGE )	return 0;    if( !(device = open(filename, O_RDONLY | O_NONBLOCK )) )	fail("initIO: open %s failed\n", filename);    rv = ioctl(device, CDROM_DRIVE_STATUS);    if( (rv != CDS_DISC_OK) && (rv != CDS_NO_INFO) )	fail("No disc or not ready\n");    if( read_discinfo(device, &di) )	fail("Read discinfo failed\n");    if( di.erasable == 0 ) {	medium = CDR;	printf("CDR disc\n");    } else {	medium = CDRW;	printf("CDRW disc\n");    }    lastTrack = di.trk1_lastsession;    if( read_trackinfo(device, &ti, lastTrack) )	/* last track 1 in last session writeable for UDF */	fail("Read discinfo failed\n");    if( medium == CDRW ) {	if( !ti.fixpkt ) {	    printf("Assume CDRW disc used as CDR\n");	    medium = CDR;	} else if ( ti.fixpkt_size != 32 )	    fail("CDRW not fixed 32 sector packets\n");    }    if( medium == CDRW ) {	for( pb = pktbuf, rv = 1; pb <= pktbuf + MAXPKTBUFS; pb++ ) {	    pb->start = 0xFFFFFFFF;	    pb->pkt = malloc(32*2048);	    pb->bufNum = rv++;	    if( pb->pkt == NULL )		fail("malloc packetBuffer failed\n");	}	if( (verifyBuffer = malloc(32 * 2048)) == NULL )	    fail("malloc verifyBuffer failed\n");    }    if( medium == CDR ) {	if( ti.rsrvd_trk || ! ti.packet || ti.fixpkt )	    fail("CDR disc last track reserved or not variable packet\n");	if( !ti.nwa_v )	    fail("Next writeable address invalid in track %d\n", ti.trk);    }    trackStart = ti.trk_start;    trackSize  = ti.trk_size;    if( ti.data_mode == 1 )	sectortype = 2;					/* for readCD() */    else if( ti.data_mode == 2 )	sectortype = 4;    else	fail("Neither Data Mode1 nor Mode2 on disc\n");    /* get read error recovery parameters page */    rv = mode_sense(device, &rerp_buffer, (void *)&rerp, GPMODE_R_W_ERROR_PAGE, PGCTL_CURRENT_VALUES);	    /* get cache parameters page */    rv = mode_sense(device, &cp_buffer, (void *)&cp, GPMODE_CACHE_PAGE, PGCTL_CURRENT_VALUES);    /* setup write params */    get_writeparams(device, &buffer, &wp, PGCTL_CURRENT_VALUES);    wp->write_type = 0;//    wp->trk_mode = 7;    wp->copy = 0;    wp->fp = medium == CDRW ? 1 : 0;    wp->test_write = 0;    wp->data_blk_type = ( ti.data_mode == 2 ? DB_XA_F1 : DB_ROM_MODE1);    wp->host_appl_code = 0;    wp->session_format = (ti.data_mode == 2 ? 0x20 : 0x00);    wp->pkt_size = medium == CDRW ? 32 : 0;    wp->subhdr0 = 0x00;    wp->subhdr1 = 0x00;    wp->subhdr2 = 0x08;    wp->subhdr3 = 0x00;    if( (rv = set_writeparams(device, buffer, wp)) )     {        free(buffer);	fail("Set write parameters failed\n");    }    else        free(buffer);    return 0;}	int closeIO(void) {    struct packetbuf *pb;    if( medium == CDRW ) {	for( pb = pktbuf; pb < pktbuf + MAXPKTBUFS; pb++ ) {	    if( pb->dirty && !pb->inuse )		writePacket(pb);	    if( pb->inuse || pb->dirty)		printf("PacketBuffet[%d] at %d inuse %08X  dirty %08X\n", 		    pb->bufNum, pb->start, pb->inuse, pb->dirty);	    free(pb->pkt);	}    }    if( blockBuffer ) free(blockBuffer);    if( verifyBuffer ) 	free(verifyBuffer);    if( devicetype != DISK_IMAGE )	synchronize_cache(device);	    close(device);    return 1;}

⌨️ 快捷键说明

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