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

📄 dvd+rw-format.cpp

📁 linux平台下的dvd刻录软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * DVD盧W format 4.10 by Andy Polyakov <appro@fy.chalmers.se>. * * Use-it-on-your-own-risk, GPL bless... * * For further details see http://fy.chalmers.se/~appro/linux/DVD+RW/. * * Revision history: * * 2.0: * - deploy "IMMED" bit in "FORMAT UNIT"; * 2.1: * - LP64 fix; * - USB workaround; * 3.0: * - C++-fication for better portability; * - SYSV signals for better portability; * - -lead-out option for improved DVD+RW compatibility; * - tested with SONY DRU-500A; * 4.0: * - support for DVD-RW formatting and blanking, tool name becomes *   overloaded... * 4.1: * - re-make it work under Linux 2.2 kernel; * 4.2: * - attempt to make DVD-RW Quick Format truly quick, upon release *   is verified to work with Pioneer DVR-x05; * - media reload is moved to growisofs where is actually belongs; * 4.3: * - -blank to imply -force; * - reject -blank in DVD+RW context and -lead-out in DVD-RW; * 4.4: * - support for -force=full in DVD-RW context; * - ask unit to perform OPC if READ DISC INFORMATION doesn't return *   any OPC descriptors; * 4.5: * - increase timeout for OPC, NEC multi-format derivatives might *   require more time to fulfill the OPC procedure; * 4.6: * - -force to ignore error from READ DISC INFORMATION; * - -force was failing under FreeBSD with 'unable to unmount'; * - undocumented -gui flag to ease progress indicator parsing for *   GUI front-ends; * 4.7: * - when formatting DVD+RW, Pioneer DVR-x06 remained unaccessible for *   over 2 minutes after dvd+rw-format exited and user was frustrated *   to poll the unit himself, now dvd+rw-format does it for user; * 4.8: * - DVD-RW format fails if preceeded by dummy recording; * - make sure we talk to MMC unit, be less intrusive; * - unify error reporting; * - permit for -lead-out even for blank DVD+RW, needed(?) for SANYO *   derivatives; * 4.9: * - permit for DVD-RW blank even if format descriptors are not present; * 4.10: * - add support for DVD-RAM; */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <sys/mman.h>#include <signal.h>#include <setjmp.h>#include <sys/wait.h>#include <errno.h>#include "transport.hxx"static void usage (char *prog){ fprintf (stderr,"- usage: %s [-force[=full]] [-lead-out|-blank[=full]]\n"		  "         [-ssa[=none|default|max]] /dev/cdrom\n",prog),  exit(1);}static volatile int *progress;static const char   *gui_action=NULL;extern "C" void alarm_handler (int no){ static int         i=0,len=1,old_progress=0;  static const char *str = "|/-\\",*backspaces="\b\b\b\b\b\b\b\b\b\b";  int new_progress = *progress;    if (gui_action)    {	fprintf (stderr,"* %s %.1f%%\n",gui_action,			100.0*new_progress/65536.0);	alarm(3);	return;    }    if (new_progress != old_progress)        len = fprintf (stderr,"%.*s%.1f%%",len,backspaces,				100.0*new_progress/65536.0) - len,	old_progress = new_progress;    else        fprintf (stderr,"\b%c",str[i]),	i++, i&=3;    alarm(1);}int main (int argc, char *argv[]){ Scsi_Command	cmd;  unsigned char	formats[260],dinfo[32],inq[128];  char		*dev=NULL,*p;  unsigned int	capacity,lead_out,mmc_profile,err;  int		force=0,full=0,compat=0,blank=0,ssa=0,do_opc=0,gui=0,len,i;  pid_t		pid;    fprintf (stderr,"* DVD盧W/-RAM format utility by <appro@fy.chalmers.se>, "		    "version 4.10.\n");    for (i=1;i<argc;i++) {	if (*argv[i] == '-')	    if (argv[i][1] == 'f')	// -format|-force	    {	force = 1;		if ((p=strchr(argv[i],'=')) && p[1]=='f') full=1;	    }	    else if (argv[i][1] == 'l')	// -lead-out		force = compat = 1;	    else if (argv[i][1] == 'b')	// -blank	    {	blank=0x11;		if ((p=strchr(argv[i],'=')) && p[1]=='f') blank=0x10;		force=1;	    }	    else if (argv[i][1] == 's')	// -ssa	    {	force=ssa=1;		if ((p=strchr(argv[i],'=')))		{   if (p[1]=='n')	ssa=-1;	// =none		    else if (p[1]=='d')	ssa=2;	// =default		    else if (p[3]=='x')	ssa=3;	// =max		    else		ssa=0;	// invalid		}	    }	    else if (argv[i][1] == 'g')	gui=1;	    else			usage(argv[0]);	else if (*argv[i] == '/')	    dev = argv[i];	else	    usage (argv[0]);    }    if (dev==NULL) usage (argv[0]);    if (!cmd.associate(dev))	fprintf (stderr,":-( unable to open(\"%s\"): ",dev), perror (NULL),	exit(1);    cmd[0] = 0x12;	// INQUIRY    cmd[4] = 36;    cmd[5] = 0;    if ((err=cmd.transport(READ,inq,36)))	sperror ("INQUIRY",err), exit (1);    if ((inq[0]&0x1F) != 5)	fprintf (stderr,":-( not an MMC unit!\n"),	exit (1);    cmd[0] = 0x46;		// GET CONFIGURATION    cmd[8] = 8;    cmd[9] = 0;    if ((err=cmd.transport(READ,formats,8)))	sperror ("GET CONFIGURATION",err), exit (1);    mmc_profile = formats[6]<<8|formats[7];    if (mmc_profile!=0x1A	&& mmc_profile!=0x14 && mmc_profile!=0x13	&& mmc_profile!=0x12)	fprintf (stderr,":-( mounted media doesn't appear to be "			"DVD盧W or DVD-RAM\n"),	exit (1);    /*     * First figure out how long the actual list is. Problem here is     * that (at least Linux) USB units absolutely insist on accurate     * cgc.buflen and you can't just set buflen to arbitrary value     * larger than actual transfer length.     */    int once=1;    do    {	cmd[0] = 0x23;		// READ FORMAT CAPACITIES	cmd[8] = 4;	cmd[9] = 0;	if ((err=cmd.transport(READ,formats,4)))	{   if (err==0x62800 && once)	// "MEDIUM MAY HAVE CHANGED"	    {	cmd[0] = 0;		// TEST UNIT READY		cmd[5] = 0;		cmd.transport();	// just swallow it...		continue;	    }	    sperror ("READ FORMAT CAPACITIES",err), exit (1);	}    } while (once--);    len = formats[3];    if (len&7 || len<8)	fprintf (stderr,":-( allocation length isn't sane\n"),	exit(1);    cmd[0] = 0x23;		// READ FORMAT CAPACITIES    cmd[7] = (4+len)>>8;	// now with real length...    cmd[8] = (4+len)&0xFF;    cmd[9] = 0;    if ((err=cmd.transport(READ,formats,4+len)))	sperror ("READ FORMAT CAPACITIES",err), exit (1);    if (len != formats[3])	fprintf (stderr,":-( parameter length inconsistency\n"),	exit(1);    if (mmc_profile==0x1A)	// DVD+RW    {	for (i=8;i<len;i+=8)	// look for "DVD+RW Full" descriptor	    if ((formats [4+i+4]>>2) == 0x26) break;    }    else if (mmc_profile==0x12)	// DVD-RAM    { unsigned int   v,ref;      unsigned char *f,descr=0x01;      int j;	switch (ssa)	{   case -1:	// no ssa		for (ref=0,i=len,j=8;j<len;j+=8)		{   f = formats+4+j;		    if ((f[4]>>2) == 0x00)		    {	v=f[0]<<24|f[1]<<16|f[2]<<8|f[3];			if (v>ref) ref=v,i=j;		    }		}		break;	    case 0:		i=8;	// just grab the first descriptor?		break;	    case 1:	// first ssa		for (i=8;i<len;i+=8)		    if ((formats[4+i+4]>>2) == 0x01) break;		break;	    case 2:	// default ssa		descr=0x00;	    case 3:	// max ssa		for (ref=0xFFFFFFFF,i=len,j=8;j<len;j+=8)		{   f = formats+4+j;		    if ((f[4]>>2) == descr)		    {	v=f[0]<<24|f[1]<<16|f[2]<<8|f[3];			if (v<ref) ref=v,i=j;		    }		}		break;	}    }    else			// DVD-RW    { int descr=full?0x10:0x15;	for (i=8;i<len;i+=8)	// look for "DVD-RW Quick" descriptor	    if ((formats [4+i+4]>>2) == descr) break;	if (descr==0x15 && i==len)	{   fprintf (stderr,":-( failed to locate \"Quick Format\" descriptor.\n");	    for (i=8;i<len;i+=8)// ... alternatively for "DVD-RW Full"		if ((formats [4+i+4]>>2) == 0x10) break;	}    }    if (i==len)    {	fprintf (stderr,":-( can't locate appropriate format descriptor\n");	if (blank)	i=0;	else		exit(1);    }    capacity = 0;    capacity |= formats[4+i+0], capacity <<= 8;    capacity |= formats[4+i+1], capacity <<= 8;    capacity |= formats[4+i+2], capacity <<= 8;

⌨️ 快捷键说明

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