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

📄 ide-pc.c

📁 udf文件系统工具软件
💻 C
字号:
/*	ide-pc.c * * PURPOSE *	Execute most MMC commands on a ATAPI-Packet command CD(re)writer through IOCTL CDROM_SEND_PACKET *	Where similar routines and structures are defined in linux/ cdrom.h this program *	maintains structures strictly as defined MMC to facilitate the interface with the CDwriter *	at the expense of a simple user interface. * * CONTACTS *	E-mail regarding this program should be addressed to *		e.fennema@dataweb.nl * * COPYRIGHT *	This file is distributed under the terms of the GNU General Public *	License (GPL). Copies of the GPL can be obtained from: *		ftp://prep.ai.mit.edu/pub/gnu/GPL *	Each contributing author retains all rights to their own work. * *	(C) 2001 Enno Fennema * * HISTORY * *	16 Aug 01  ef  Created. */#include <stdio.h>#include <string.h>#include <stdarg.h>#include <errno.h>#include <sys/ioctl.h>#include <sys/types.h>		/* for u_char etc. */#include <linux/cdrom.h>#include <unistd.h>		/* sleep() */#include "bswap.h"#include "ide-pc.h"typedef struct cdrom_generic_command CGC;static int rv;			// -1 if ioctl failed, else equal statstatic struct request_sense sense_data;void fail(char *fmt, ...) {    va_list	args;    va_start(args, fmt);     vfprintf(stderr, fmt, args);    exit(1);}struct request_sense *get_sense_data() {    return &sense_data;}char*get_sense_string() {    static char str[128];    sprintf(str, "Stat %d Err %02X  Key %02Xx; ASC %02Xx; ASCQ %02Xx; Info %02X%02X%02X%02Xx",	rv, sense_data.error_code, sense_data.sense_key, sense_data.asc, sense_data.ascq, 	sense_data.information[0], sense_data.information[1], sense_data.information[2], sense_data.information[3]);    return str;}void initpc(CGC *pc) {    memset(pc,0,sizeof(*pc));    memset(&sense_data, 0 , sizeof(sense_data));    pc->sense=&sense_data;    pc->data_direction = CGC_DATA_NONE;    pc->timeout = 2500;}intblank(int fd, int type, int start){    CGC pc;    initpc(&pc);    pc.cmd[0]=GPCMD_BLANK;    pc.cmd[1]= type & 7;    *(u_int*)&pc.cmd[2] = cpu_to_be32(start);		/* blank track tail : lba to start blanking							 * blank track : track number to blank */    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}intclose_track_session(int fd, int close_track, int track){    CGC pc;    initpc(&pc);    pc.cmd[0] = GPCMD_CLOSE_TRACK;    pc.cmd[2] = close_track ? 0x01 : 0x02;    pc.cmd[5] = track;    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}intformat(int fd, int session_grow, int size){    struct {	u_char	flh_rsrv;	u_char	flh_imm;	u_short	flh_fdlen;	u_int	id;	u_char	fd_sg;	u_char	fd_rsrv[3];	u_int	fd_size;    }	f;			    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_WRITE;    memset(&f, 0, sizeof(f));    pc.buffer= (void*)&f;    pc.buflen= sizeof(f);    pc.cmd[0] = GPCMD_FORMAT_UNIT;    pc.cmd[1] = 0x17;				/* Format Parameter List present; format 0x7 */    f.flh_fdlen = cpu_to_be16(8);    f.fd_sg = session_grow;    f.fd_size = cpu_to_be32(size);    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}intset_cdspeed(int fd, int readspeed, int writespeed){    CGC pc;    initpc(&pc);    pc.cmd[0]=GPCMD_SET_SPEED;    *(u_short*) &pc.cmd[2] = cpu_to_be16(readspeed);    *(u_short*) &pc.cmd[4] = cpu_to_be16(writespeed);    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}intsynchronize_cache(int fd){    CGC pc;    initpc(&pc);    pc.cmd[0] = GPCMD_FLUSH_CACHE;    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}inttest_unit_ready(int fd){    CGC pc;    initpc(&pc);		 		/* Test Unit Ready command = 0x00 */    /*	kernel returns -1 when CHECK_CONDITION status returned     *	sense data is valid and gives further info     */    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}int getDriveState(int fd ) {    int	rv;     rv = test_unit_ready(fd);    if( rv ) sleep(2);				/* wait a bit longer */    rv = test_unit_ready(fd);    if( rv < 0 )	return DS_NOT_READY;    if( rv == 0 ) 	return DS_OPERATIONAL;    if( sense_data.sense_key == 2 && sense_data.asc == 0x04 && sense_data.ascq == 0x04 )	return DS_OPERATIONAL;    if( sense_data.sense_key == 2 && sense_data.asc == 0x3A &&  sense_data.ascq == 2 )	return DS_TRAY_OPEN;        return DS_NO_DISC;}intinquiry(int fd, struct cdrom_inquiry *inq){    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_READ;    pc.cmd[0]=GPCMD_INQUIRY;    pc.cmd[4]=sizeof(struct cdrom_inquiry);    pc.buffer= (void*)inq;    pc.buflen= sizeof(struct cdrom_inquiry);    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}    intmediumRemoval(int fd, int allow){    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_NONE;    pc.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;    pc.cmd[4] = allow;    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}    intread_reccapacity(int fd, struct cdrom_reccapacity *reccap){    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_READ;    pc.cmd[0]=GPCMD_READ_CDVD_CAPACITY;    pc.buffer=(void*)reccap;    pc.buflen=sizeof(struct cdrom_reccapacity);    rv = ioctl(fd, CDROM_SEND_PACKET, &pc);    reccap->lastblock  = be32_to_cpu(reccap->lastblock);    reccap->blocksize = be32_to_cpu(reccap->blocksize);    return rv;}intread_buffercapacity(int fd, struct cdrom_buffercapacity *bufcap){    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_READ;    pc.cmd[0] = 0x5C;				// READ BUFFER CAPACITY    *(u_short*)&pc.cmd[7] = cpu_to_be16(sizeof(struct cdrom_buffercapacity));    pc.buffer=(void*)bufcap;    pc.buflen=sizeof(struct cdrom_buffercapacity);    rv = ioctl(fd, CDROM_SEND_PACKET, &pc);    bufcap->totalBufferLength  = be32_to_cpu(bufcap->totalBufferLength);    bufcap->freeBufferLength = be32_to_cpu(bufcap->freeBufferLength);    return rv;}intreserve_track(int fd, int size){    CGC pc;    initpc(&pc);    pc.cmd[0]=GPCMD_RESERVE_RZONE_TRACK;		/* 0x53 */    *(u_int*)&pc.cmd[5] = cpu_to_be32(size);    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}intstartStopUnit(int fd, int action){    CGC pc;    initpc(&pc);    pc.cmd[0] = GPCMD_START_STOP_UNIT;    pc.cmd[4] = action;    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}intread_discinfo(int fd, struct cdrom_discinfo *di){    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_READ;    pc.cmd[0]=GPCMD_READ_DISC_INFO;    *(u_short*) &pc.cmd[7] = cpu_to_be16( sizeof(struct cdrom_discinfo) );    pc.buffer=(void*)di;    pc.buflen=sizeof(struct cdrom_discinfo);    rv = ioctl(fd, CDROM_SEND_PACKET, &pc);    di->data_length = be16_to_cpu(di->data_length);    di->disc_id = be32_to_cpu(di->disc_id);    return rv;}intread_header(int fd, struct cdrom_header *hd, u_int block){    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_READ;    pc.cmd[0]=GPCMD_READ_HEADER;    *(u_int*)&pc.cmd[2] = cpu_to_be32( block);    *(u_short*)&pc.cmd[7] = cpu_to_be16( sizeof(struct cdrom_header) );    pc.buffer=(void*)hd;    pc.buflen=sizeof(struct cdrom_header);    rv = ioctl(fd, CDROM_SEND_PACKET, &pc);    hd->lba = be32_to_cpu(hd->lba);    return rv;}intread_trackinfo(int fd, struct cdrom_trackinfo *ti, int trackno){    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_READ;    pc.cmd[0]=GPCMD_READ_TRACK_RZONE_INFO;    pc.cmd[1]=1;    *(u_int*)&pc.cmd[2] = cpu_to_be32( trackno );    *(u_short*)&pc.cmd[7] = cpu_to_be16( sizeof(struct cdrom_trackinfo) );	/* 28; if higher data underrun error */    pc.buffer=(void*)ti;    pc.buflen=sizeof(struct cdrom_trackinfo);    rv = ioctl(fd, CDROM_SEND_PACKET, &pc);    ti->data_length = be16_to_cpu(ti->data_length);    ti->trk_start = be32_to_cpu(ti->trk_start);    ti->nwa = be32_to_cpu(ti->nwa);    ti->free_blks = be32_to_cpu(ti->free_blks);    ti->fixpkt_size = be32_to_cpu(ti->fixpkt_size);    ti->trk_size = be32_to_cpu(ti->trk_size);    return rv;}intreadCD(int fd, int sectortype, int lba, int n, char* buf){    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_READ;    pc.cmd[0]=GPCMD_READ_CD;    pc.cmd[1]=sectortype << 2;			/* Sector type per MCC table 31 */    *(int*) &pc.cmd[2] = cpu_to_be32(lba);    pc.cmd[8]=n;				/* read n blocks */    pc.cmd[9]=0x10;				/* user data only */    pc.buffer=buf;    pc.buflen=n * 2048;    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}intwriteCD(int fd, int lba, int nblks, char* buf){    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_WRITE;    pc.cmd[0] = GPCMD_WRITE_10;    pc.cmd[1] = 0;				/* DPO 0x10; FUA 0x08 */    *(u_int*)  &pc.cmd[2] = cpu_to_be32(lba);    *(u_short*)&pc.cmd[7] = cpu_to_be16(nblks);    pc.buffer = buf;    pc.buflen = nblks * 2048;    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}#ifdef MMC2	// VERIFY and WRITE_AND_VERIFY are new in MMC2 and not supported by my HP8100intverify(int fd, int lba, int nblocks){    CGC pc;    initpc(&pc);    pc.cmd[0] = GPCMD_VERIFY_10;    pc.cmd[1] = 0;    *(u_int*) &pc.cmd[2] = cpu_to_be32(lba);    pc.cmd[8] = (u_char) nblocks;    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}#endif/* *	mode_sense *	Returns 8 byte header followed by actual mode page. The HP 8100 recognizes: *	 1 - Read Error Recovery page *		In MtFuji this is called Read/Write Error recovery mode page *		The separate Verify Error Recovery Mode page of SCSI-2 draft has gone. *		The HP8100 recovers a change mask of 01 06 36 FF 00 00 00 00  *		This would mean retry count 0 to 255 acceptable *		and TB, RC, PER and DTE bits settable. Not the DCR bit. *		Could these also affect a verify operation. MtFuji VERIFY says no. *	 5 - Write parameters page *	 8 - Media supported mode page *	 D - CD-ROM page: Inactivity time, seconds/minute, frames/second *	 E - CD-ROM Audio Control page *	1D - Timeout and protect (MtFuji 12.11.3.5) *	2A - CD Capabilities mode page *	2F - ASCII message ? : '(c) 1997-1998 HP, license available' */intmode_select(int fd, u_char *buffer){    CGC pc;    int len = 2 + be16_to_cpu(((mode_hdr*)buffer)->data_length);    initpc(&pc);    pc.data_direction = CGC_DATA_WRITE;    pc.cmd[0] = GPCMD_MODE_SELECT_10;	    pc.cmd[1] = 0x10;					// PF bit    pc.buffer = buffer;    pc.buflen = len;    *(u_short*) &pc.cmd[7] = cpu_to_be16(len);    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}intmode_sense(int fd, u_char **buffer, u_char **mode, u_char pageno, int pgctl){    CGC pc;    mode_hdr h;    int len, offset;    memset(&h, 0x00, sizeof(mode_hdr));    initpc(&pc);    pc.data_direction = CGC_DATA_READ;    pc.cmd[0] = GPCMD_MODE_SENSE_10;    pc.cmd[2] = (pgctl<<6) + (pageno & 0x3F);    *(u_short*) &pc.cmd[7] = cpu_to_be16(sizeof(mode_hdr));    pc.buffer = (void *)&h;    pc.buflen = sizeof(mode_hdr);    rv = ioctl(fd, CDROM_SEND_PACKET, &pc);    if( rv ) {	printf("mode_sense(1): stat %d\n", rv);	return rv;    }    len = 2 + be16_to_cpu(h.data_length);    offset = 8 + be16_to_cpu(h.block_desc_length);    *buffer = (u_char*) calloc(len, sizeof(u_char));    *mode = &(*buffer)[offset];    pc.buffer = *buffer;    pc.buflen = len;    *(u_short*) &pc.cmd[7] = cpu_to_be16(len);    return ioctl(fd, CDROM_SEND_PACKET, &pc);}// MMC-2 feature not supported by my HP 8100 CD-Writer#ifdef MMC2intget_configuration(int fd, u_char* buffer, int size, u_char feature){    int i, realsize;    CGC pc;    initpc(&pc);    pc.data_direction = CGC_DATA_READ;    pc.cmd[0] = 0x46;				// GET CONFIGURATION    *(u_short*) &pc.cmd[2] = cpu_to_be16(feature);    *(u_short*) &pc.cmd[7] = cpu_to_be16(8);		// only to see how much will be returned    pc.buffer=(void*)buffer;    if( size < 8 ) return -EINVAL;    pc.buflen = 8;    rv = ioctl(fd, CDROM_SEND_PACKET, &pc);    if( rv )	return rv;    realsize = be32_to_cpu((int)buffer[0]) + 4;    if( realsize < size ) {	pc.buflen = realsize;	*(u_short*) &pc.cmd[7] = cpu_to_be16(realsize);    } else {	pc.buflen = size;	*(u_short*) &pc.cmd[7] = cpu_to_be16(size);    }    return rv = ioctl(fd, CDROM_SEND_PACKET, &pc);}#endif		// MMC2intget_writeparams(int fd, u_char **buffer, struct cdrom_writeparams **wp, int pgctl){    rv = mode_sense(fd, buffer, (u_char**) wp, 0x05, pgctl);    (*wp)->pkt_size = be32_to_cpu((*wp)->pkt_size);    (*wp)->audio_pause = be16_to_cpu((*wp)->audio_pause);    return rv;}intset_writeparams(int fd, u_char *buffer, struct cdrom_writeparams *wp){    wp->pkt_size = cpu_to_be32(wp->pkt_size);    wp->audio_pause = cpu_to_be16(wp->audio_pause);    rv = mode_select(fd, buffer);    wp->pkt_size = be32_to_cpu(wp->pkt_size);    wp->audio_pause = be16_to_cpu(wp->audio_pause);    return rv;}intget_capabilities(int fd, u_char **buffer, struct cdrom_capabilities **cap, int pgctl){    rv = mode_sense(fd, buffer, (u_char**) cap, GPMODE_CAPABILITIES_PAGE, pgctl);    (*cap)->max_read_speed  = be16_to_cpu((*cap)->max_read_speed);    (*cap)->num_vol_levels  = be16_to_cpu((*cap)->num_vol_levels);    (*cap)->buffer_size     = be16_to_cpu((*cap)->buffer_size);    (*cap)->cur_read_speed  = be16_to_cpu((*cap)->cur_read_speed);    (*cap)->max_write_speed = be16_to_cpu((*cap)->max_write_speed);    (*cap)->cur_write_speed = be16_to_cpu((*cap)->cur_write_speed);    return rv;}

⌨️ 快捷键说明

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