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

📄 dvd+rw-mediainfo.cpp

📁 最新的linux下dvd刻录软件,支持DVD+RW、DVD-RW光盘刻录。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * DVD Media Info utility by Andy Polyakov <appro@fy.chalmers.se>. * * This code is in public domain. */#include <stdio.h>#include <stddef.h>#include <stdlib.h>#include <string.h>#include "transport.hxx"#ifdef _WIN32#define LLU "I64u"#else#define LLU "llu"#endifint main(int argc,char *argv[]){ Scsi_Command	cmd;  unsigned char	header[48],inq[128],*page2A=NULL;  char		cmdname[64];  int		i,j,ntracks,err,dvd_dash=0,dvd_plus=0,		plus_mediaid_printed=0,page2A_printed=0,dvd_ram_spare=0;  unsigned short profile,		dvd_0E=0,dvd_10=0,dvd_11=0,dvd_0A=0,dvd_C0=0,		prf_23=0,prf_24=0,prf_38=0;  int		_1x=1385,blu_ray=0;    if (argc<2)	fprintf (stderr,"usage: %s /dev/dvd\n",argv[0]),	exit (FATAL_START(EINVAL));    if (!cmd.associate(argv[1]))	fprintf (stderr,"%s: unable to open: ",argv[1]),	perror (NULL),	exit (FATAL_START(errno));    cmd[0] = 0x12;	// INQUIRY    cmd[4] = 36;    cmd[5] = 0;    if ((err=cmd.transport(READ,inq,36)))	sperror ("INQUIRY",err),	exit (FATAL_START(errno));    if ((inq[0]&0x1F) != 5)	fprintf (stderr,":-( not an MMC unit!\n"),	exit (FATAL_START(EINVAL));    if (argc>1)	printf ("INQUIRY:                [%.8s][%.16s][%.4s]\n",		inq+8,inq+16,inq+32);#if 0    wait_for_unit(cmd);#else    // consume sense data, most commonly "MEDIUM MAY HAVE CHANGED"...    cmd[0] = 0;		// TEST UNIT READY    cmd[5] = 0;    if ((err=cmd.transport()) == -1)	sperror ("TEST UNIT READY",err),	exit (FATAL_START(errno));#endif    if (argc>2) do    { unsigned char *pages;      int len,n;      static int pagecode=0x3F;	printf ("MODE SENSE[#%02Xh]:\n",pagecode);	cmd[0] = 0x5A;		// MODE SENSE	cmd[1] = 0x08;		// "Disable Block Descriptors"	cmd[2] = pagecode;	// initially "All Pages"	cmd[8] = 12;	cmd[9] = 0;	if ((err=cmd.transport(READ,header,12)))	    sprintf (cmdname,"MODE SENSE#%02X",pagecode),	    sperror (cmdname,err),	    exit(errno);	if (header[6]<<8|header[7])	    fprintf (stderr,":-( \"DBD\" is not respected\n"),	    exit(errno);	len=(header[0]<<8|header[1])+2;	if (len < (8+2+header[9]))	{   if (pagecode == 0x3F)	    {	pagecode = 0x5;		continue;	    }	    len = 8+2+header[9];	}	if (!(pages=(unsigned char *)malloc(len))) exit(1);	cmd[0] = 0x5A;	cmd[1] = 0x08;	cmd[2] = pagecode;	cmd[7] = len>>8;	cmd[8] = len;	cmd[9] = 0;	cmd.transport(READ,pages,len);	for(i=8+(pages[6]<<8|pages[7]);i<len;)	{   if (pages[i] == 0)	break;	    if (pages[i] == 0x2A) page2A_printed=1;	    printf (" %02X:",pages[i++]);	    n=pages[i++];	    for (j=0;j<n;j++)	    {	if (j && j%16==0) printf("\n");		printf ("%c%02x",(j%16)?' ':'\t',pages[i++]);	    }	    printf("\n");	}	if (i<len)	{   printf (" RES:");	    for (len-=i,j=0;j<len;j++)	    {	if (j && j%16==0) printf("\n");		printf ("%c%02x",(j%16)?' ':'\t',pages[i++]);	    }	    printf ("\n");	}   	free(pages);	break;    } while (1);    { int len,n;	page2A=header, len=36;	while (1)	{   cmd[0] = 0x5A;	// MODE SENSE(10)	    cmd[1] = 0x08;	// "Disable Block Descriptors"	    cmd[2] = 0x2A;	// "Capabilities and Mechanical Status"	    cmd[7] = len>>8;	    cmd[8] = len;	    cmd[9] = 0;	    if ((err=cmd.transport(READ,page2A,len)))		sperror ("MODE SENSE#2A",err),		exit (errno);	    if (page2A[6]<<8|page2A[7])		fprintf (stderr,":-( \"DBD\" is not respected\n");	    else if (len<((page2A[0]<<8|page2A[1])+2) || len<(8+2+page2A[9]))	    {	len=(page2A[0]<<8|page2A[1])+2;		if (len < (8+2+page2A[9]))		    len = 8+2+page2A[9];		page2A=(unsigned char *)malloc(len);		continue;	    }	    if (!(page2A[8+(page2A[6]<<8|page2A[7])+2]&8))		fprintf (stderr,":-( not a DVD unit\n"),		exit (FATAL_START(EINVAL));	    if (page2A==header) page2A=NULL;	    else if (argc>2 && !page2A_printed)	    {	printf("MODE SENSE[#2A]:\n");		for(i=8+(page2A[6]<<8|page2A[7]);i<len;)		{   printf (" %02X:",page2A[i++]);		    n=page2A[i++];		    for (j=0;j<n;j++)		    {	if (j && j%16==0) printf("\n");			printf ("%c%02x",(j%16)?' ':'\t',page2A[i++]);		    }		    printf("\n");		}	    }	    break;	}    }    cmd[0] = 0x46;	// GET CONFIGURATION    cmd[1] = 1;    cmd[8] = 8;    cmd[9] = 0;    if ((err=cmd.transport(READ,header,8)))    {	if (err!=0x52000)	// "IVALID COMMAND OPERATION CODE"	    sperror ("GET CONFIGURATION",err),	    perror (NULL),	    exit(FATAL_START(errno));	profile=0x10;	// non MMC3 DVD-ROM unit?	goto legacy;    }    profile=header[6]<<8|header[7];    do    { unsigned char *profiles;      int len,n;	len=header[2]<<8|header[3];	len+=4;	if (!(profiles=(unsigned char *)malloc(len))) exit(1);	cmd[0] = 0x46;	cmd[1] = 1;	cmd[6] = len>>16;	cmd[7] = len>>8;	cmd[8] = len;	cmd[9] = 0;	cmd.transport(READ,profiles,len);	printf ("GET [CURRENT] CONFIGURATION:\n");	for(i=8;i<len;)	{   unsigned short p=profiles[i]<<8|profiles[i+1];	    n=profiles[i+3]; i+=4;	    if      (p==0x23)	prf_23=n+4;	    else if (p==0x24)	prf_24=n+4;	    else if (p==0x38)	prf_38=n+4;	    if (argc<=2)	    {	i+=n; continue;   }	    printf (" %04X%c",p,':');	    for (j=0;j<n;j++)	    {	if (j && j%16==0) printf("\n");		printf ("%c%02x",(j%16)?' ':'\t',profiles[i++]);	    }	    printf("\n");	}	free(profiles);    } while(0);    if (profile==0)	fprintf (stderr,":-( no media mounted, exiting...\n"),	exit(FATAL_START(ENOMEDIUM));    if ((profile&0xF0) != 0x10 && (profile&0xF0) != 0x20 &&	(profile&0xF0) != 0x40)	fprintf (stderr,":-( non-DVD media mounted, exiting...\n"),	exit (FATAL_START(EMEDIUMTYPE));    { const char *str;	switch (profile)	{   case 0x10:	str="DVD-ROM";				break;	    case 0x11:	str="DVD-R Sequential";			break;	    case 0x12:	str="DVD-RAM";				break;	    case 0x13:	str="DVD-RW Restricted Overwrite";	break;	    case 0x14:	str="DVD-RW Sequential";		break;	    case 0x15:	str="DVD-R Dual Layer Sequential";	break;	    case 0x16:	str="DVD-R Dual Layer Jump";		break;	    case 0x1A:	str="DVD+RW";				break;	    case 0x1B:	str="DVD+R";				break;	    case 0x2A:	str="DVD+RW Double Layer";		break;	    case 0x2B:	str="DVD+R Double Layer";		break;	    case 0x40:	str="BD-ROM";				break;	    case 0x41:	str=prf_38?"BD-R SRM+POW":"BD-R SRM";	break;	    case 0x42:	str="BD-R RRM";				break;	    case 0x43:	str="BD-RE";				break;	    default:	str="unknown";				break;	}	printf (" Mounted Media:         %Xh, %s\n",profile,str);	if (str[3]=='-' && str[6]!='M')	dvd_dash=0x10;	if (str[3]=='+')		dvd_plus=0x11;    }    if ((profile&0xF0) == 0x40)	_1x=4495, blu_ray=1;    do    { unsigned int   len,j;      unsigned char *p;	cmd[0] = 0xAD;	cmd[1] = blu_ray;	// Media Type	cmd[7] = 0xFF;	cmd[9] = 4;	cmd[11] = 0;	if ((err=cmd.transport(READ,header,4)))	{   if (argc>2)		sperror (blu_ray?"READ BD STRUCTURE#FF":"READ DVD STRUCTURE#FF",err);	    break;	}	len = (header[0]<<8|header[1]) + 2;	if (!(p = (unsigned char *)malloc(len))) break;	cmd[0] = 0xAD;	cmd[1] = blu_ray;	// Media Type	cmd[7] = 0xFF;	cmd[8] = len>>8;	cmd[9] = len;	cmd[11] = 0;	if ((err=cmd.transport(READ,p,len)))	    break;	for (j=4;j<len;j+=4)	    switch (p[j])	    {	case 0x0A:  dvd_0A=(p[j+2]<<8|p[j+3])+2;    break;		case 0x0E:  dvd_0E=(p[j+2]<<8|p[j+3])+2;    break;		case 0x10:  dvd_10=(p[j+2]<<8|p[j+3])+2;    break;		case 0x11:  dvd_11=(p[j+2]<<8|p[j+3])+2;    break;		case 0xC0:  dvd_C0=(p[j+2]<<8|p[j+3])+2;    break;	    }	if (argc<=2) break;	printf ("READ %s STRUCTURE[#FF]:\n",blu_ray?"BD":"DVD");	for (j=4;j<len;j+=4)	printf(" STRUCTURE#%02x           %02x:%d\n",p[j],p[j+1],p[j+2]<<8|p[j+3]);    } while (0);    if (blu_ray) do    { unsigned char di[128];      unsigned int  len;      unsigned char format=0;	cmd[0] = 0xAD;	cmd[1] = blu_ray;	// Media Type	cmd[7] = format;	cmd[9] = 4;	cmd[11] = 0;	if ((err=cmd.transport(READ,header,4)))	{   if (argc>2)		sprintf (cmdname,"READ BD STRUCTURE#%02x",format),		sperror (cmdname,cmd.sense());	    break;	}	len = (header[0]<<8|header[1]) + 2;	if (len>sizeof(di)) len=sizeof(di);	cmd[0] = 0xAD;	cmd[1] = blu_ray;	// Media Type	cmd[7] = format;	cmd[8] = len>>8;	cmd[9] = len;	cmd[11] = 0;	if ((err=cmd.transport(READ,&di,len)))	    break;	if (argc>2)	{   printf ("READ BD STRUCTURE[#%02xh]:",format);	    for (j=0;j<(int)len;j++)		printf("%c%02x",j?' ':'\t',di[j]);	    printf("\n");	}	if (di[4+0]=='D' && di[4+1]=='I')	printf (" Media ID:              %6.6s/%-3.3s\n",di+4+100,di+4+106);    } while (0);    else if (dvd_0E || dvd_11) do    { union { unsigned char _e[4+40],_11[4+256]; } dvd;      unsigned int  len;      unsigned char format=dvd_plus?0x11:0x0E;	cmd[0] = 0xAD;	cmd[7] = format;	cmd[9] = 4;	cmd[11] = 0;	if ((err=cmd.transport(READ,header,4)))	{   if (argc>2)		sprintf (cmdname,"READ DVD STRUCTURE#%02x",format),		sperror (cmdname,cmd.sense());	    break;	}	len = (header[0]<<8|header[1]) + 2;	if (len>sizeof(dvd)) len=sizeof(dvd);	cmd[0] = 0xAD;	cmd[7] = format;	cmd[8] = len>>8;	cmd[9] = len;	cmd[11] = 0;	if ((err=cmd.transport(READ,&dvd,len)))	    break;	if (argc>2)	{   printf ("READ DVD STRUCTURE[#%02xh]:",format);	    for (j=0,i=dvd_dash?sizeof(dvd._e):sizeof(dvd._11);j<i;j++)		printf("%c%02x",j?' ':'\t',dvd._11[j]);	    printf("\n");	}	if (!dvd_plus && dvd_0E && dvd._e[4+16]==3 && dvd._e[4+24]==4)	printf (" Media ID:              %6.6s%-6.6s\n",dvd._e+4+17,dvd._e+4+25);	if (dvd_plus && dvd_11)	printf (" Media ID:              %.8s/%.3s\n",dvd._11+23,dvd._11+31),	plus_mediaid_printed=1;    } while (0);    if (page2A) do    { int len,hlen,v,n=0;      unsigned char *p;	len  = (page2A[0]<<8|page2A[1])+2;	hlen = 8+(page2A[6]<<8|page2A[7]);	if (len<(hlen+30)) break;	// no "Current Write Speed"        p = page2A+hlen;	v = p[28]<<8|p[29];	// Check Write Speed descriptors for sanity. Some DVD+units	// return CD-R descriptors here, which has no meaning in the	// context of interest.	if (v<1352)	break;	if (len>=(hlen+32))	{   n = (p[30]<<8|p[31])*4;	    for (i=0;i<n;i+=4)		if ((p[32+i+2]<<8|p[32+i+3]) < 1352) break;	    if (i<n) break;	}	printf (" Current Write Speed:   %.1fx%d=%dKB/s\n",(double)v/_1x,_1x,v);	if (len<(hlen+32)) break;	// no "Write Speed Descriptors"	for (i=0;i<n;i+=4)	v = p[32+i+2]<<8|p[32+i+3],	printf (" Write Speed #%d:        %.1fx%d=%dKB/s\n",i/4,(double)v/_1x,_1x,v);    } while (0);    do    { unsigned char d[8+16],*p;      unsigned int  len,rv,wv,i;	cmd[0]=0xAC;		// GET PERFORMANCE	cmd[1]=4;		// ask for "Overall Write Performance"	cmd[9]=1;		// start with one descriptor	cmd[10]=0;		// ask for descriptor in effect	cmd[11]=0;	if ((err=cmd.transport(READ,d,sizeof(d))))	{   if (argc>2)		sperror ("GET CURRENT PERFORMACE",err);	    break;	}	len = (d[0]<<24|d[1]<<16|d[2]<<8|d[3])-4;	if (len%16)	// insane length	{   if (argc>2)		fprintf (stderr,":-( insane GET PERFORMANCE length %u\n",len);	    break;	}	len+=8;	if (len < sizeof(d))	{   if (argc>2)		fprintf (stderr,":-( empty GET CURRENT PERFORMACE descriptor\n");	    break;	}	if (len == sizeof(d))	    p = d;	else	// ever happens?	{ unsigned int n=(len-8)/16;	    p = (unsigned char *)malloc(len);	// will leak...	    cmd[0]=0xAC;	// GET PERFORMANCE	    cmd[1]=4;		// ask for "Overall Write Performance"	    cmd[8]=n>>8;	    cmd[9]=n;		// real number of descriptors	    cmd[10]=0;		// ask for descriptor in effect	    cmd[11]=0;	    if ((err=cmd.transport(READ,p,len)))	    {	sperror ("GET CURRENT PERFORMANCE",err);		break;	    }	}	if (argc>2)	{   printf ("GET CURRENT PERFORMANCE:\t");	    for (i=4;i<len;i++) printf ("%02x ",p[i]);	    printf ("\n");	}	if ((p[4]&2) == 0)	    fprintf (stderr,":-( reported write performance might be bogus\n");	if (argc<=2) printf ("GET [CURRENT] PERFORMANCE:\n");	for (p+=8,len-=8,i=0;len;p+=16,len-=16,i++)	{   rv=p[4]<<24 |p[5]<<16 |p[6]<<8 |p[7],	    wv=p[12]<<24|p[13]<<16|p[14]<<8|p[15];	    if (rv==wv)		printf (" %-23s%.1fx%d=%uKB/s@[%u -> %u]\n",			i==0?"Write Performance:":"",			(double)rv/_1x,_1x,rv,			p[0]<<24|p[1]<<16|p[2]<<8 |p[3],			p[8]<<24|p[9]<<16|p[10]<<8|p[11]);	    else		printf (" %-23s%.1fx%d=%uKB/s@%u -> %.1fx%d=%uKB/s@%u\n",			i==0?"Write Performance:":"",			(double)rv/_1x,_1x,rv,p[0]<<24|p[1]<<16|p[2]<<8 |p[3],			(double)wv/_1x,_1x,wv,p[8]<<24|p[9]<<16|p[10]<<8|p[11]);	}    } while (0);    do    { unsigned char d[8+16],*p;      unsigned int  len,rv,wv,i;	cmd[0]=0xAC;		// GET PERFORMANCE	cmd[9]=1;		// start with one descriptor	cmd[10]=0x3;		// ask for "Write Speed Descriptor"	cmd[11]=0;	if ((err=cmd.transport(READ,d,sizeof(d))))	{   if (argc>2)		sperror ("GET PERFORMACE",err);	    break;	}	len = (d[0]<<24|d[1]<<16|d[2]<<8|d[3])-4;	if (len%16)	// insage length	{   if (argc>2)		fprintf (stderr,":-( insane GET PERFORMANCE length %u\n",len);	    break;	}	len+=8;	if (len < sizeof(d))	{   fprintf (stderr,":-( empty GET PERFORMACE descriptor\n");	    break;	}	if (len == sizeof(d))	    p = d;	else	{ unsigned int n=(len-8)/16;	    p = (unsigned char *)malloc(len);	// will leak...	    cmd[0]=0xAC;	// GET PERFORMANCE	    cmd[8]=n>>8;	    cmd[9]=n;		// real number of descriptors	    cmd[10]=0x3;	// ask for "Write Speed Descriptor"	    cmd[11]=0;	    if ((err=cmd.transport(READ,p,len)))	    {	sperror ("GET PERFORMANCE",err);		break;	    }	}	if (argc>2)	{   printf ("GET PERFORMANCE:\t");	    for (i=8;i<len;i++) printf ("%02x ",p[i]);	    printf ("\n");	}	for (p+=8,len-=8,i=0;len;p+=16,len-=16,i++)	rv=p[8]<<24 |p[9]<<16 |p[10]<<8|p[11],	wv=p[12]<<24|p[13]<<16|p[14]<<8|p[15],	printf (" Speed Descriptor#%d:    %02x/%u R@%.1fx%d=%uKB/s W@%.1fx%d=%uKB/s\n",		i,p[0],p[4]<<24|p[5]<<16|p[6]<<8|p[7],		(double)rv/_1x,_1x,rv,(double)wv/_1x,_1x,wv);    } while (0);legacy:

⌨️ 快捷键说明

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