📄 dvd+rw-mediainfo.cpp
字号:
if (!blu_ray) do { unsigned char book=header[4]; const char *brand; unsigned int phys_start,phys_end; header[4]=0; cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[7] = dvd_dash; cmd[9] = 36; cmd[11] = 0; if ((err=cmd.transport(READ,header,36))) { if (dvd_dash) { dvd_dash=0; goto legacy; } if (err!=0x52400 || argc>2) sprintf (cmdname,"READ DVD STRUCTURE#%X",dvd_dash), sperror (cmdname,cmd.sense()); break; } printf("READ DVD STRUCTURE[#%Xh]:",dvd_dash<0?0:dvd_dash); if (argc>2) for (j=0;j<20-4;j++) printf("%c%02x",j?' ':'\t',header[4+j]); printf("\n"); switch(book&0xF0) { case 0x00: brand="-ROM"; break; case 0x10: brand="-RAM"; break; case 0x20: brand="-R"; break; case 0x30: brand="-RW"; break; case 0x90: brand="+RW"; break; case 0xA0: brand="+R"; break; case 0xE0: brand="+R DL"; break; default: brand=NULL; break; } printf (" Media Book Type: %02Xh, ",book); if (brand) printf ("DVD%s book [revision %d]\n", brand,book&0xF); else printf ("unrecognized value\n"); if (header[4+1]&0xF0) dvd_ram_spare=5120; else dvd_ram_spare=12800; if (dvd_plus && !plus_mediaid_printed) printf (" Media ID: %.8s/%.3s\n",header+23,header+31); phys_start = header[4+5]<<16, phys_start |= header[4+6]<<8, phys_start |= header[4+7]; if ((header[4+2]&0x60)==0) // single-layer phys_end = header[4+9]<<16, phys_end |= header[4+10]<<8, phys_end |= header[4+11]; else phys_end = header[4+13]<<16, phys_end |= header[4+14]<<8, phys_end |= header[4+15]; if (phys_end>0) phys_end -= phys_start; if (phys_end>0) phys_end += 1; printf (" %s %u*2KB=%"LLU"\n", dvd_dash>=0?"Legacy lead-out at:":"Last border-out at:", phys_end,phys_end*2048LL); if (dvd_dash<=0) break; cmd[0] = 0xAD; cmd[7] = 0; dvd_dash=-1; cmd[9] = 20; cmd[11] = 0; if ((err=cmd.transport(READ,header,20))) { sperror ("READ DVD-R STRUCTURE",err); break; } } while (1); if (profile==0x10 && (header[4]&0xF0)==0) printf ("DVD-ROM media detected, exiting...\n"), exit(0); if (profile==0x2B) do { unsigned char s[4+8]; cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[7] = 0x20; // "DVD+R Double Layer Boundary Information" cmd[9] = sizeof(s); cmd[11] = 0; if ((err=cmd.transport(READ,s,sizeof(s)))) { sperror ("READ LAYER BOUNDARY INFORMATION",err); break; } if ((s[0]<<8|s[1]) < 10) { fprintf (stderr,":-( insane LBI structure length\n"); break; } printf ("DVD+R DOUBLE LAYER BOUNDARY INFORMATION:\n"); printf (" L0 Data Zone Capacity: %u*2KB, can %s be set\n", s[8]<<24|s[9]<<16|s[10]<<8|s[11], s[4]&0x80?"no longer":"still"); } while (0); if (profile==0x16) do { unsigned char s[4+8]; // Layer Jump specific structures. Note that growisofs doesn't // perform Layer Jump recordings, see web-page for details... cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[7] = 0x21; // "DVD-R DL Shifted Middle Area Start Address" cmd[9] = sizeof(s); cmd[11] = 0; if ((err=cmd.transport(READ,s,sizeof(s)))) argc>2 ? sperror ("READ SHIFTED MIDDLE AREA START ADDRESS",err) : (void)0; else if ((s[0]<<8|s[1]) < 10) fprintf (stderr,":-( insane SMASA structure length\n"); else { printf ("DVD-R DL SHIFTED MIDDLE AREA START ADDRESS:\n"); printf (" Shifted Middle Area: %u*2KB, can %s be set\n", s[8]<<24|s[9]<<16|s[10]<<8|s[11], s[4]&0x80?"no longer":"still"); } cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[7] = 0x22; // "DVD-R DL Jump Interval Size" cmd[9] = sizeof(s); cmd[11] = 0; if ((err=cmd.transport(READ,s,sizeof(s)))) argc>2 ? sperror ("READ JUMP INTERVAL SIZE",err) : (void)0; else if ((s[0]<<8|s[1]) < 10) fprintf (stderr,":-( insane JIS structure length\n"); else { printf ("DVD-R DL JUMP INTERVAL SIZE:\n"); printf (" Jump Interval Size: %u*2KB\n", s[8]<<24|s[9]<<16|s[10]<<8|s[11]); } cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[7] = 0x23; // "DVD-R DL Manual Layer Jump Address" cmd[9] = sizeof(s); cmd[11] = 0; if ((err=cmd.transport(READ,s,sizeof(s)))) argc>2 ? sperror ("READ MANUAL LAYER JUMP ADDRESS",err) : (void)0; else if ((s[0]<<8|s[1]) < 10) fprintf (stderr,":-( insane MLJA structure length\n"); else { printf ("DVD-R DL MANUAL LAYER JUMP ADDRESS:\n"); printf (" Manual Layer Jump: %u*2KB\n", s[8]<<24|s[9]<<16|s[10]<<8|s[11]); } cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[7] = 0x24; // "DVD-R DL Remapping Address" cmd[9] = sizeof(s); cmd[11] = 0; if ((err=cmd.transport(READ,s,sizeof(s)))) argc>2 ? sperror ("READ REMAPPING ADDRESS",err) : (void)0; else if ((s[0]<<8|s[1]) < 10) fprintf (stderr,":-( insane RA structure length\n"); else { printf ("DVD-R DL REMAPPING ADDRESS:\n"); printf (" Remapping Jump: %u*2KB\n", s[8]<<24|s[9]<<16|s[10]<<8|s[11]); } } while (0); if (profile==0x12 && dvd_0A) do { unsigned char s[16]; unsigned int a,b; if (dvd_0A>sizeof(s)) dvd_0A=sizeof(s); cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[7] = 0x0A; // "DVD-RAM Spare Area Information" cmd[8] = dvd_0A>>8; cmd[9] = dvd_0A; cmd[11] = 0; if ((err=cmd.transport(READ,s,dvd_0A))) { sperror ("READ DVD-RAM SPARE INFORMATION",err); break; } if (dvd_0A<8) break; printf ("DVD-RAM SPARE AREA INFORMATION:\n"); a = s[ 4]<<24|s[ 5]<<16|s[ 6]<<8|s[ 7]; b = dvd_ram_spare; printf (" Primary SA: %u/%u=%.1f%% free\n",a,b,(a*100.0)/b); if (dvd_0A<16) break; a = s[ 8]<<24|s[ 9]<<16|s[10]<<8|s[11]; b = s[12]<<24|s[13]<<16|s[14]<<8|s[15]; printf (" Supplementary SA: %u/%u=%.1f%% free\n",a,b,(a*100.0)/b); } while (0); if (profile==0x12 && dvd_C0) do { unsigned char s[8]; if (dvd_C0>sizeof(s)) dvd_C0=sizeof(s); cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[7] = 0xC0; // "Write Protection Status" cmd[8] = dvd_C0>>8; cmd[9] = dvd_C0; cmd[11] = 0; if ((err=cmd.transport(READ,s,dvd_C0))) { sperror ("READ WRITE PROTECTION STATUS",err); break; } if (dvd_C0<8) break; printf ("DVD-RAM WRITE PROTECTION STATUS:\n"); if (s[4]&0x04) printf (" Write protect tab on cartridge is set to protected\n"); if (s[4]&0x01) printf (" Software Write Protection until Power down is on\n"); printf (" Persistent Write Protection is %s\n",s[4]&0x02?"on":"off"); } while (0); if (blu_ray && dvd_0A) do { unsigned char s[16]; unsigned int a,b; if (dvd_0A>sizeof(s)) dvd_0A=sizeof(s); cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[1] = blu_ray; cmd[7] = 0x0A; // "BD Spare Area Information" cmd[8] = dvd_0A>>8; cmd[9] = dvd_0A; cmd[11] = 0; if ((err=cmd.transport(READ,s,dvd_0A))) { if (err!=0x33100 || argc>2) sperror ("READ BD SPARE INFORMATION",err); break; } a = s[ 8]<<24|s[ 9]<<16|s[10]<<8|s[11]; b = s[12]<<24|s[13]<<16|s[14]<<8|s[15]; if (dvd_0A<16 || b==0) break; printf ("BD SPARE AREA INFORMATION:\n"); printf (" Spare Area: %u/%u=%.1f%% free\n",a,b,(a*100.0)/b); } while (0); if (blu_ray && prf_38) do { unsigned char pow[16]; cmd[0] = 0x51; // READ DISC INFORMATION cmd[1] = 0x10; // "POW Resources Information" cmd[8] = sizeof(pow); cmd[9] = 0; if ((err=cmd.transport(READ,pow,sizeof(pow)))) { sperror ("READ ROW RESOURCES INFORMATION",err); break; } printf ("POW RESOURCES INFORMATION:\n"); printf (" Remaining Replacements:%u\n",pow[ 4]<<24|pow[ 5]<<16|pow[ 6]<<8|pow[ 7]); printf (" Remaining Map Entries: %u\n",pow[ 8]<<24|pow[ 9]<<16|pow[10]<<8|pow[11]); printf (" Remaining Updates: %u\n",pow[12]<<24|pow[13]<<16|pow[14]<<8|pow[15]); } while(0); if (blu_ray && argc>2) do { unsigned char *p,*pac,*s; unsigned int len; cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[1] = blu_ray; cmd[7] = 0x30; // "Physical Access Control (PAC)" cmd[9] = 4; cmd[11] = 0; if ((err=cmd.transport(READ,header,4))) { if (err!=0x33100 || argc>2) sperror ("READ BD PAC LIST",err); break; } len = (header[0]<<8|header[1])+2; if (!(p = (unsigned char *)malloc(len))) break; cmd[0] = 0xAD; // READ DVD STRUCTURE cmd[1] = blu_ray; cmd[7] = 0x30; // "Physical Access Control (PAC)" cmd[8] = len>>8; cmd[9] = len; cmd[11] = 0; if ((err=cmd.transport(READ,p,len))) { sperror ("READ BD PAC LIST",err); break; } printf ("BD WRITTEN PAC HEADERS:\n"); for (pac=p+4;pac<p+len;pac+=384) { printf (" %3.3s.%02x: ",pac,pac[3]); for (i=4;i<16;i++) printf ("%02x ",pac[i]); for (i=0,s=pac+16;i<pac[15];i++,s+=8) printf ("%u:%u ",s[0]<<24|s[1]<<16|s[2]<<8|s[3], s[4]<<24|s[5]<<16|s[6]<<8|s[7]); printf ("\n"); } } while (0); cmd[0] = 0x51; // READ DISC INFORMATION cmd[8] = 32; cmd[9] = 0; if ((err=cmd.transport(READ,header,32))) sperror ("READ DISC INFORMATION",cmd.sense()), exit (errno); { static const char *session_state[]={ "empty", "incomplete", "reserved/damaged","complete" }, *disc_status[]={ "blank", "appendable", "complete", "other" }, *bg_format[]={ "blank", "suspended", "in progress", "complete" }; printf ("READ DISC INFORMATION:"); if (argc>2) for (j=0;j<16;j++) printf("%c%02x",j?' ':'\t',header[j]); printf ("\n"); printf (" Disc status: %s\n",disc_status[header[2]&3]); printf (" Number of Sessions: %d\n",header[9]<<8|header[4]); printf (" State of Last Session: %s\n",session_state[(header[2]>>2)&3]); if ((header[2]&3)!=2) printf (" \"Next\" Track: %d\n",header[10]<<8|header[5]); printf (" Number of Tracks: %d",ntracks=header[11]<<8|header[6]); if (header[7]&3) printf ("\n BG Format Status: %s",bg_format[header[7]&3]); if ((header[7]&3) == 2) { unsigned char sense[18]; cmd[0] = 0x03; // REQUEST SENSE cmd[4] = sizeof(sense); cmd[5] = 0; if (!cmd.transport (READ,sense,sizeof(sense)) && sense[15]&0x80) printf (", %.1f%% complete",(sense[16]<<8|sense[17])/655.36); } printf ("\n"); while (prf_23 || profile==0x12 || (header[2]&0x10 && argc>2)) { unsigned char formats[260]; int len; unsigned int capacity,blocksize; static const char *type[] = { "reserved", "unformatted", "formatted", "no media" }; printf ("READ FORMAT CAPACITIES:\n"); cmd[0] = 0x23; // READ FORMAT CAPACITIES cmd[8] = 12; cmd[9] = 0; if ((err=cmd.transport(READ,formats,12))) { sperror ("READ FORMAT CAPACITIES",err); break; } len = formats[3]; if (len&7 || len<16) { fprintf (stderr,":-( allocation length isn't sane %d\n",len); break; } 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); break; } if (len != formats[3]) { fprintf (stderr,":-( parameter length inconsistency\n"); break; } if (blu_ray) blocksize=2048; else blocksize=formats[9]<<16|formats[10]<<8|formats[11]; printf(" %s:\t\t%u*%u=",type[formats[8]&3], capacity=formats[4]<<24|formats[5]<<16|formats[6]<<8|formats[7], blocksize); printf("%"LLU"\n",(unsigned long long)capacity*blocksize); for(i=12;i<len;i+=8) { printf(" %02Xh(%x):\t\t%u*%u=",formats[i+4]>>2, formats[i+5]<<16|formats[i+6]<<8|formats[i+7], capacity=formats[i]<<24|formats[i+1]<<16|formats[i+2]<<8|formats[i+3], blocksize); printf("%"LLU"\n",(unsigned long long)capacity*blocksize); } break; } } if (argc<=2 && profile==0x12) ntracks=0; for (i=1;i<=ntracks;i++) { static const char *dash_track_state[]={ "complete", "complete incremental", "blank", "invisible incremental", "partial", "partial incremental", "reserved", "reserved incremental"}; static const char *plus_track_state[]={ "invisible", "blank", "partial/complete", "reserved" }; int len=32; while (len) { cmd[0] = 0x52; // READ TRACK INFORMATION cmd[1] = 1; cmd[2] = i>>24; cmd[3] = i>>16; cmd[4] = i>>8; cmd[5] = i; cmd[8] = len; cmd[9] = 0; if ((err=cmd.transport(READ,header,len))) { if (i<ntracks) { i=ntracks; continue; } sperror ("READ TRACK INFORMATION",err), exit (errno); } if ((profile==0x1B || profile==0x2B) && (header[6]&0x80)==0 && (header[0]<<8|header[1])>=38) { if (len==32) { len=40; continue; } else { break; } } else if ((profile==0x15 || profile==0x16) && (header[5]&0xC0) && (header[0]<<8|header[1])>=46) { if (len==32) { len=48; continue; } else { break; } } len = 0; } printf ("READ TRACK INFORMATION[#%d]:",i); if (argc>2) for (j=0;j<16;j++) printf("%c%02x",j?' ':'\t',header[j]); printf ("\n"); if ((profile&0x0F)==0x0B) // DVD+R { printf (" Track State: %s\n", plus_track_state[header[6]>>6]); } else { printf (" Track State: %s%s", ((header[6]>>5)==1 && (header[7]&1))?"in":"", dash_track_state[header[6]>>5]); if (header[5]&0x20) printf(",damaged"); printf ("\n"); } printf (" Track Start Address: %u*2KB\n", header[8]<<24|header[9]<<16|header[10]<<8|header[11]); if (header[7]&1) printf (" Next Writable Address: %u*2KB\n", header[12]<<24|header[13]<<16|header[14]<<8|header[15]); printf (" Free Blocks: %u*2KB\n", header[16]<<24|header[17]<<16|header[18]<<8|header[19]); if (header[6]&0x10) printf (" Fixed Packet Size: %u*2KB\n", header[20]<<24|header[21]<<16|header[22]<<8|header[23]); printf (header[5]&0x40? // check upon LJ bit " Zone End Address: %u*2KB\n": " Track Size: %u*2KB\n", header[24]<<24|header[25]<<16|header[26]<<8|header[27]); if (header[7]&2) printf (" Last Recorded Address: %u*2KB\n", header[28]<<24|header[29]<<16|header[30]<<8|header[31]); if (len>=40) printf (" ROM Compatibility LBA: %u\n", header[36]<<24|header[37]<<16|header[38]<<8|header[39]); if (len>=48 && header[5]&0xC0) // check upon LJRS bits printf (" LJRS field: %u\n",header[5]>>6), printf (" Next Layer Jump: %u\n", header[40]<<24|header[41]<<16|header[42]<<8|header[43]), printf (" Last Layer Jump: %u\n", header[44]<<24|header[45]<<16|header[46]<<8|header[47]); } do { unsigned char *toc,*p; int len,sony; cmd[0] = 0x43; // READ TOC cmd[6] = 1; cmd[8] = 12; cmd[9] = 0; if ((err=cmd.transport (READ,header,12))) { if (argc>2) sperror ("READ TOC",err); break; } len = (header[0]<<8|header[1])+2; toc = (unsigned char *)malloc (len); printf ("FABRICATED TOC:"); if (argc>2) printf ("\t\t%u %x %x",header[0]<<8|header[1],header[2],header[3]); printf ("\n"); cmd[0] = 0x43; // READ TOC cmd[6] = header[2]; // "First Track Number" cmd[7] = len>>8; cmd[8] = len; cmd[9] = 0; if ((err=cmd.transport (READ,toc,len))) { sperror ("READ TOC",err); break; } for (p=toc+4,i=4;i<len-8;i+=8,p+=8) printf (" Track#%-3u: %02x@%u\n", p[2],p[1],p[4]<<24|p[5]<<16|p[6]<<8|p[7]); printf (" Track#%-2X : %02x@%u\n", p[2],p[1],p[4]<<24|p[5]<<16|p[6]<<8|p[7]); cmd[0] = 0x43; // READ TOC cmd[2] = 1; // "Session info" cmd[8] = 12; cmd[9] = 0; if ((err=cmd.transport (READ,header,12))) { if (argc>2) sperror ("GET SESSION INFO",err); break; } len = header[4+4]<<24|header[4+5]<<16|header[4+6]<<8|header[4+7]; printf (" Multi-session Info: #%u@%u\n",header[4+2],len); cmd[0] = 0x43; // READ TOC cmd[8] = 12; cmd[9] = 0x40; // "SONY Vendor bit" if ((err=cmd.transport (READ,header,12))) { if (argc>2) sperror ("GET SONY SESSION INFO",err); break; } sony = header[4+4]<<24|header[4+5]<<16|header[4+6]<<8|header[4+7]; if (len != sony) printf (" SONY Session Info: #%u@%u\n",header[4+2],sony); } while (0); do { unsigned int ccity,bsize; cmd[0] = 0x25; // READ CAPACITY cmd[9] = 0; if ((err=cmd.transport (READ,header,8))) { if (argc>2) sperror ("READ CAPACITY",err); break; } ccity = header[0]<<24|header[1]<<16|header[2]<<8|header[3]; if (ccity) ccity++; bsize = header[4]<<24|header[5]<<16|header[6]<<8|header[7]; printf ("READ CAPACITY: %u*%u=%"LLU"\n", ccity,bsize, (unsigned long long)ccity*bsize); } while (0); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -