📄 cdrwtool.c
字号:
cgc.cmd[1] |= (USE_IMMED << 4); if ((ret = wait_cmd(fd, &cgc, NULL, CGC_DATA_NONE, WAIT_BLANK)) < 0) { perror("blank disc"); return ret; } print_completion_info(fd); return 0;}int format_disc(int fd, struct cdrw_disc *disc){ struct cdrom_generic_command cgc; unsigned char buffer[16]; int ret; memset(&cgc, 0, sizeof(cgc)); memset(buffer, 0, sizeof(buffer)); cgc.cmd[0] = GPCMD_FORMAT_UNIT; cgc.cmd[1] = 1 << 4 | 7; cgc.buflen = 16; /* format list header */ buffer[0] = 0; buffer[1] = 0; /* FOV: 0 (use defaults) */ buffer[1] |= (USE_IMMED << 1); buffer[2] = 0; buffer[3] = 8; /* bytes 4 through 7 are the initialization pattern, which * we just ignore. no use for CD-RW drives. */ /* format descriptor */ buffer[8] = 0x00; /* session and grow bits (7 and 6) */ buffer[9] = 0; buffer[10] = 0; buffer[11] = 0; buffer[12] = (disc->offset >> 24) & 0xff; buffer[13] = (disc->offset >> 16) & 0xff; buffer[14] = (disc->offset >> 8) & 0xff; buffer[15] = disc->offset & 0xff; if ((ret = wait_cmd(fd, &cgc, buffer, CGC_DATA_WRITE, WAIT_BLANK)) < 0) { perror("format disc"); return ret; } print_completion_info(fd); return 0;}int read_disc_info(int fd, disc_info_t *di){ struct cdrom_generic_command cgc; int ret; memset(&cgc, 0, sizeof(cgc)); memset(di, 0, sizeof(disc_info_t)); cgc.cmd[0] = GPCMD_READ_DISC_INFO; cgc.cmd[8] = cgc.buflen = 2; if ((ret = wait_cmd(fd, &cgc, (unsigned char *)di, CGC_DATA_READ, WAIT_PC)) < 0) { perror("read disc info"); return ret; } cgc.buflen = be16_to_cpu(di->length) + sizeof(di->length); if (cgc.buflen > sizeof(disc_info_t)) cgc.buflen = sizeof(disc_info_t); cgc.cmd[8] = cgc.buflen; if ((ret = wait_cmd(fd, &cgc, (unsigned char *)di, CGC_DATA_READ, WAIT_PC)) < 0) { perror("read disc info"); return ret; } return 0;}int read_track_info(int fd, track_info_t *ti, int trackno){ struct cdrom_generic_command cgc; int ret; memset(&cgc, 0, sizeof(cgc)); memset(ti, 0, sizeof(track_info_t)); cgc.cmd[0] = GPCMD_READ_TRACK_RZONE_INFO; cgc.cmd[1] = 1; cgc.cmd[5] = trackno; cgc.cmd[8] = cgc.buflen = 28; if ((ret = wait_cmd(fd, &cgc, (unsigned char *) ti, CGC_DATA_READ, WAIT_PC)) < 0) { perror("read track info"); return ret; } return 0;}int reserve_track(int fd, struct cdrw_disc *disc){ struct cdrom_generic_command cgc; int ret; memset(&cgc, 0, sizeof(cgc)); cgc.cmd[0] = GPCMD_RESERVE_RZONE_TRACK; cgc.cmd[5] = (disc->reserve_track >> 24) & 0xff; cgc.cmd[6] = (disc->reserve_track >> 16) & 0xff; cgc.cmd[7] = (disc->reserve_track >> 8) & 0xff; cgc.cmd[8] = disc->reserve_track & 0xff; if ((ret = wait_cmd(fd, &cgc, NULL, CGC_DATA_NONE, WAIT_BLANK)) < 0) { perror("reserve track"); return ret; } return 0;}int close_track(int fd, unsigned int track){ struct cdrom_generic_command cgc; int ret; memset(&cgc, 0, sizeof(cgc)); cgc.cmd[0] = GPCMD_CLOSE_TRACK; cgc.cmd[1] = USE_IMMED; cgc.cmd[2] = 1; /* bit 2 is close session/border */ cgc.cmd[4] = (track >> 8) & 0xff; cgc.cmd[5] = track & 0xff; if ((ret = wait_cmd(fd, &cgc, NULL, CGC_DATA_NONE, WAIT_BLANK)) < 0) { perror("close track"); return ret; } print_completion_info(fd); return 0;}int close_session(int fd, unsigned int track){ struct cdrom_generic_command cgc; int ret; memset(&cgc, 0, sizeof(cgc)); cgc.cmd[0] = GPCMD_CLOSE_TRACK; cgc.cmd[1] = USE_IMMED; cgc.cmd[2] = 2; /* bit 2 is close session/border */ cgc.cmd[4] = (track >> 8) & 0xff; cgc.cmd[5] = track & 0xff; if ((ret = wait_cmd(fd, &cgc, NULL, CGC_DATA_NONE, WAIT_BLANK)) < 0) { perror("close session"); return ret; } print_completion_info(fd); return 0;}int read_buffer_cap(int fd, struct cdrw_disc *disc){ struct cdrom_generic_command cgc; struct { unsigned int pad; unsigned int buffer_size; unsigned int buffer_free; } __attribute((packed)) buf; int ret; memset(&cgc, 0, sizeof(cgc)); memset(&buf, 0, sizeof(buf)); cgc.cmd[0] = 0x5c; cgc.cmd[8] = cgc.buflen = 12; if ((ret = wait_cmd(fd, &cgc, (unsigned char *)&buf, CGC_DATA_READ, WAIT_PC))) return ret; disc->buffer = be32_to_cpu(buf.buffer_size); printf("%uKB internal buffer\n", disc->buffer >> 10); return 0;}int set_cd_speed(int fd, int speed){ struct cdrom_generic_command cgc; printf("setting write speed to %ux\n", speed); memset(&cgc, 0, sizeof(cgc)); cgc.cmd[0] = 0xbb; /* read speed */ cgc.cmd[2] = 0xff; cgc.cmd[3] = 0xff; /* write speed */ cgc.cmd[4] = ((0xb0 * speed) >> 8) & 0xff; cgc.cmd[5] = (0xb0 * speed) & 0xff; return wait_cmd(fd, &cgc, NULL, CGC_DATA_NONE, WAIT_PC);}void cdrom_close(int fd){ /* enable locking */ if (ioctl(fd, CDROM_LOCKDOOR, 0) < 0) printf("can't unlock door\n"); ioctl(fd, CDROM_SET_OPTIONS, CDO_LOCK);}int cdrom_open_check(int fd){ int ret, attempts = 3; while (--attempts) { ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); if (ret < 0) return ret; if (ret == CDS_DISC_OK) break; } if (attempts == 0) return 1; /* drive should now be ready. check media */ ret = ioctl(fd, CDROM_DISC_STATUS); if (ret == CDS_AUDIO || ret < 0) return 1; /* disable locking */ if ((ret = ioctl(fd, CDROM_CLEAR_OPTIONS, CDO_LOCK)) < 0) return ret; if ((ret == ioctl(fd, CDROM_LOCKDOOR, 1)) < 0) { fprintf(stderr, "CD-ROM appears to already be opened\n"); return 1; } return 0;}void print_disc_info(disc_info_t *di){ printf("\terasable : %s\n", di->erasable ? "Yes" : "No"); printf("\tborder = %d\n", di->border); printf("\tDisc status = %d\n", di->status); printf("\tnumber of first track = %d\n", di->n_first_track); printf("\tnumber of sessions = %d\n", (di->n_sessions_m << 8) | di->n_sessions_l); printf("\tnumber of tracks = %d\n", (di->first_track_m << 8) | di->first_track_l); printf("\tstatus of last track = %d\n", (di->last_track_m << 8) | di->last_track_l); printf("\turu = %d\n", di->uru); printf("\tdid_v = %d\n", di->did_v); printf("\tdbc_v = %d\n", di->dbc_v); printf("\tdisc type = %d\n", di->disc_type); printf("\tdisc_id = %u\n", be32_to_cpu(di->disc_id)); printf("\tlead_in = %02d:%02d:%02d (%u)\n", di->lead_in_m, di->lead_in_s, di->lead_in_f, msf_to_lba(di->lead_in_m, di->lead_in_s, di->lead_in_f)); printf("\tlead_out = %02d:%02d:%02d (%u)\n", di->lead_out_m, di->lead_out_s, di->lead_out_f, msf_to_lba(di->lead_out_m, di->lead_out_s, di->lead_out_f)); printf("\tOPC entries = %u\n", di->opc_entries); printf("\n");}void print_track_info(track_info_t *ti){ printf("\ttrack_number = %d\n", (ti->track_number_m << 8) | ti->track_number_l); printf("\tsession_number = %d\n", (ti->session_number_m << 8) | ti->session_number_l); printf("\tdamage = %d\n", ti->damage); printf("\tcopy = %d\n", ti->copy); printf("\ttrack_mode = %d\n", ti->track_mode); printf("\tRt = %d\n", ti->rt); printf("\tblank = %d\n", ti->blank); printf("\tpacket = %d\n", ti->packet); printf("\tfp = %d\n", ti->fp); printf("\tdata_mode = %d\n", ti->data_mode); printf("\tlra_v = %d\n", ti->lra_v); printf("\tnwa_v = %d\n", ti->nwa_v); printf("\ttrack_start = %u\n", be32_to_cpu(ti->track_start)); printf("\tnext_writable = %u\n", be32_to_cpu(ti->next_writable)); printf("\tlast_recorded = %u\n", be32_to_cpu(ti->last_recorded)); printf("\tfree_blocks = %u\n", be32_to_cpu(ti->free_blocks)); printf("\tpacket_size = %u\n", be32_to_cpu(ti->packet_size)); printf("\ttrack_size = %u (%uKB)\n", be32_to_cpu(ti->track_size), be32_to_cpu(ti->track_size) * 2);}int print_disc_track_info(int fd){ int ret, i; track_info_t ti; disc_info_t di; memset(&di, 0, sizeof(disc_info_t)); memset(&ti, 0, sizeof(track_info_t)); if ((ret = read_disc_info(fd, &di)) < 0) return ret; printf("\nDISC INFO:\n"); print_disc_info(&di); /* Assumes no more than 256 tracks ;) */ printf("TRACK INFO:\n"); for (i = di.n_first_track; i <= di.last_track_l; i++) { if ((ret = read_track_info(fd, &ti, i)) < 0) return ret; printf("\nTrack %d\n", i); print_track_info(&ti); } return 0;}void make_write_page(write_params_t *w, struct cdrw_disc *disc){ switch (disc->write_type) { case WRITE_MODE1: { w->data_block = 0x8; w->session_format = 0x00; break; } case WRITE_MODE2: { w->data_block = 0xa; w->session_format = 0x20; break; } } w->packet_size = disc->packet_size; w->fpacket = disc->fpacket; w->link_size = disc->link_size; w->border = disc->border; w->track_mode = w->track_mode | 0x3;}void print_params(write_params_t *wp){ fprintf(stdout, "writing %s packets\n", wp->fpacket ? "fixed" : "variable"); fprintf(stdout, "border type\t: %d\n", wp->border); fprintf(stdout, "track mode\t: %d\n", wp->track_mode); fprintf(stdout, "data block type\t: %d\n", wp->data_block); fprintf(stdout, "session format\t: %d\n", wp->session_format); fprintf(stdout, "packet size\t: %lu\n", wp->packet_size);}void cdrw_init_disc(struct cdrw_disc *disc){ disc->fpacket = 1; disc->packet_size = PACKET_BLOCK; disc->write_type = WRITE_MODE2; disc->speed = DEFAULT_SPEED;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -