📄 dvd+rw-mediainfo.cpp
字号:
} 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@%.1fx1385=%uKB/s W@%.1fx1385=%uKB/s\n", i,p[0],p[4]<<24|p[5]<<16|p[6]<<8|p[7], rv/1385.0,rv,wv/1385.0,wv); } while (0);legacy: 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,err); } else do { unsigned char book=header[4]; const char *brand; unsigned int phys_start,phys_end; 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 DVD+R DL BOUNDARY INFORMATION",err); break; } if ((s[0]<<8|s[1]) < 10) { fprintf (stderr,":-( insane DVD+R DL BI 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==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); cmd[0] = 0x51; // READ DISC INFORMATION cmd[8] = 32; cmd[9] = 0; if ((err=cmd.transport(READ,header,32))) sperror ("READ DISC INFORMATION",err), exit (1); { 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 (header[2]&0x10 && (profile==0x12 || 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; } printf(" %s:\t\t%u*%u=",type[formats[8]&3], capacity=formats[4]<<24|formats[5]<<16|formats[6]<<8|formats[7], blocksize=formats[9]<<16|formats[10]<<8|formats[11]); 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 (1); } if ((profile==0x1B || profile==0x2B) && (header[6]&0x80)==0 && (header[0]<<8|header[1])>=38) { if (len==32) { len=40; 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 (" 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]); } 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], 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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -