📄 wrudf-cdrw.c
字号:
} 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 + -