private void GenPrimaryVolumeDescriptor() // ( 8.4 ) { PrimaryVolumeDescriptor = this.generator.Index / LogicalBlockSize; var pvd = new FieldValidator(this.generator); pvd.Byte(1, 1); // Volume Descriptor Type ( 8.4.1 ) pvd.AString("CD001", 2, 6); // Standard Identifier ( 8.4.2 ) pvd.Byte(1, 7); // Volume Descriptor Version ( 8.4.3 ) pvd.Zero(8, 8); // Unused Field ( 8.4.4 ) pvd.AString("?", 9, 40); // System Identifier ( 8.4.5 ) pvd.DString(this.volumeLabel, 41, 72); // Volume Identifier ( 8.4.6 ) pvd.Zero(73, 80); // Unused Field ( 8.4.7 ) pvd.IntLSBMSB((TotalSize + LogicalBlockSize - 1) / LogicalBlockSize, 81, 88); // Volume Space Size ( 8.4.8 ) pvd.Zero(89, 120); // Unused Field ( 8.4.9 ) pvd.ShortLSBMSB(1, 121, 124); // Volume Set Size ( 8.4.10 ) pvd.ShortLSBMSB(1, 125, 128); // Volume Sequence Number ( 8.4.11 ) pvd.ShortLSBMSB(LogicalBlockSize, 129, 132); // Logical Block Size ( 8.4.12 ) pvd.IntLSBMSB(PathTableSize, 133, 140); // Path Table Size ( 8.4.13 ) pvd.IntLSB(LPathTable, 141, 144); // L Path Table ( 8.4.14 ) pvd.IntLSB(0, 145, 148); // Optional L Path Table ( 8.4.15 ) pvd.IntMSB(MPathTable, 149, 152); // M Path Table ( 8.4.16 ) pvd.IntMSB(0, 153, 156); // Optional M Path Table ( 8.4.17 ) pvd.BeginField(157); DirectoryRecord(".", this.isoRoot, 1); // Directory Record for Root Directory ( 8.4.18 ) pvd.EndField(190); pvd.DupByte(0x20, 191, 318); // Volume Set Identifier ( 8.4.19 ) pvd.DupByte(0x20, 319, 446); // Publisher Identifier ( 8.4.20 ) pvd.DupByte(0x20, 447, 574); // Data Preparer ( 8.4.21 ) pvd.DupByte(0x20, 575, 702); // Application Identifier ( 8.4.22 ) pvd.DupByte(0x20, 703, 739); // Copyright File Identifier ( 8.4.23 ) pvd.DupByte(0x20, 740, 776); // Abstract File Identifier ( 8.4.24 ) pvd.DupByte(0x20, 777, 813); // Bibliographic File Identifier ( 8.4.25 ) System.DateTime now = System.DateTime.Now; pvd.AnsiDateTime(now, 814, 830); // Volume Creation Date and Time ( 8.4.26 ) pvd.AnsiDateTime(now, 831, 847); // Volume Modification Date and Time ( 8.4.27 ) pvd.Zero(848, 864); // Volume Expiration Date and Time ( 8.4.28 ) pvd.Zero(865, 881); // Volume Effective Date and Time ( 8.4.29 ) pvd.Byte(1, 882); // File Structure Version ( 8.4.30 ) pvd.Zero(883, 883); // Reserved ( 8.4.31 ) pvd.Zero(884, 1395); // Application Use ( 8.4.32 ) pvd.Zero(1396, 2048); // Reserved for Future Standardization ( 8.4.33 ) }
private string DirectoryRecordEx(byte[] fileName, string realName, IsoEntry e, byte root, bool secondPass) { byte[] /*b_fi,*/ b_su = null; /*if (fileName == ".") { b_fi = new byte[] { 0 }; realName = ""; } else if (fileName == "..") { b_fi = new byte[] { 1 }; realName = ""; } else b_fi = generator.Ascii.GetBytes(fileName);*/ byte LEN_FI = (byte)fileName.Length; byte LEN_DR = (byte)(33 + LEN_FI); bool fi_padding = ((LEN_DR & 1) != 0); if (fi_padding) LEN_DR++; // as much as I HATE to do it, I have to generate this data in both passes for now. // I don't yet understand enough about what and how many DR entries have to be made to figure out how to do it "right" byte LEN_SU = 0; #if ROCKRIDGE if (root != 1) // don't generate susp on PVD's root entry... { b_su = Susp(ref realName, e, root == 2, secondPass, (byte)(255 - LEN_DR)); if (b_su.Length > 255) throw new NotImplementedException("can't yet handle SUSP > 255 bytes"); LEN_SU = (byte)b_su.Length; } else realName = ""; #endif LEN_DR += LEN_SU; var dr = new FieldValidator(this.generator); dr.Byte(LEN_DR, 1); // Length of Directory Record ( 9.1.1 ) dr.Byte(0, 2); // Extended Attribute Record Length ( 9.1.2 ) dr.IntLSBMSB(e.DataBlock, 3, 10); // Location of Extent ( 9.1.3 ) #if true // in this test - I round the data length up to the next multiple of 2048, didn't help fix my booting problem though... dr.IntLSBMSB(((e.DataLength - 1) / 2048 + 1) * 2048, 11, 18); // Data Length ( 9.1.4 ) #else dr.IntLSBMSB(e.DataLength, 11, 18); // Data Length ( 9.1.4 ) #endif dr.BinaryDateTime(System.DateTime.Now, 19, 25); // Recording Date and Time ( 9.1.5 ) byte flags = 0; if (e.IsFile) { IsoFile f = (IsoFile)e; if ((f.fileInfo.Attributes & FileAttributes.Hidden) != 0) flags |= 1; // hidden } else { // TODO FIXME - not supporting hidden folders right now //IsoFolder f = (IsoFolder)e; //if ((f.dirInfo.Attributes & DirectoryAttributes.Hidden) != 0) // flags |= 1; // hidden } if (e.IsFolder) flags |= 2; // directory #if false // I'm disabling this because analysing of a working ISO never sets this bit... if (real_name.Length == 0) flags |= 128; // final #endif dr.Byte(flags, 26); // flags ( 9.1.6 ) dr.Byte(0, 27); // File Unit Size ( 9.1.7 ) dr.Byte(0, 28); // Interleave Gap Size ( 9.1.8 ) dr.ShortLSBMSB(1, 29, 32); // Volume Sequence Number ( 9.1.9 ) dr.Byte(LEN_FI, 33); // Length of File Identifier ( 9.1.10 ) dr.Bytes(fileName, 34, 33 + LEN_FI); if (fi_padding) dr.Zero(34 + LEN_FI, 34 + LEN_FI); if (LEN_SU > 0) dr.Bytes(b_su, LEN_DR - LEN_SU + 1, LEN_DR); return realName; }
private string DirectoryRecordEx(byte[] fileName, string realName, IsoEntry e, byte root, bool secondPass) { byte[] /*b_fi,*/ b_su = null; /*if (fileName == ".") * { * b_fi = new byte[] { 0 }; * realName = ""; * } * else if (fileName == "..") * { * b_fi = new byte[] { 1 }; * realName = ""; * } * else * b_fi = generator.Ascii.GetBytes(fileName);*/ byte LEN_FI = (byte)fileName.Length; byte LEN_DR = (byte)(33 + LEN_FI); bool fi_padding = ((LEN_DR & 1) != 0); if (fi_padding) { LEN_DR++; } // as much as I HATE to do it, I have to generate this data in both passes for now. // I don't yet understand enough about what and how many DR entries have to be made to figure out how to do it "right" byte LEN_SU = 0; #if ROCKRIDGE if (root != 1) // don't generate susp on PVD's root entry... { b_su = Susp(ref realName, e, root == 2, secondPass, (byte)(255 - LEN_DR)); if (b_su.Length > 255) { throw new NotImplementedException("can't yet handle SUSP > 255 bytes"); } LEN_SU = (byte)b_su.Length; } else { realName = ""; } #endif LEN_DR += LEN_SU; var dr = new FieldValidator(this.generator); dr.Byte(LEN_DR, 1); // Length of Directory Record ( 9.1.1 ) dr.Byte(0, 2); // Extended Attribute Record Length ( 9.1.2 ) dr.IntLSBMSB(e.DataBlock, 3, 10); // Location of Extent ( 9.1.3 ) #if true // in this test - I round the data length up to the next multiple of 2048, didn't help fix my booting problem though... dr.IntLSBMSB(((e.DataLength - 1) / 2048 + 1) * 2048, 11, 18); // Data Length ( 9.1.4 ) #else dr.IntLSBMSB(e.DataLength, 11, 18); // Data Length ( 9.1.4 ) #endif dr.BinaryDateTime(System.DateTime.Now, 19, 25); // Recording Date and Time ( 9.1.5 ) byte flags = 0; if (e.IsFile) { IsoFile f = (IsoFile)e; if ((f.fileInfo.Attributes & FileAttributes.Hidden) != 0) { flags |= 1; // hidden } } else { // TODO FIXME - not supporting hidden folders right now //IsoFolder f = (IsoFolder)e; //if ((f.dirInfo.Attributes & DirectoryAttributes.Hidden) != 0) // flags |= 1; // hidden } if (e.IsFolder) { flags |= 2; // directory } #if false // I'm disabling this because analysing of a working ISO never sets this bit... if (real_name.Length == 0) { flags |= 128; // final } #endif dr.Byte(flags, 26); // flags ( 9.1.6 ) dr.Byte(0, 27); // File Unit Size ( 9.1.7 ) dr.Byte(0, 28); // Interleave Gap Size ( 9.1.8 ) dr.ShortLSBMSB(1, 29, 32); // Volume Sequence Number ( 9.1.9 ) dr.Byte(LEN_FI, 33); // Length of File Identifier ( 9.1.10 ) dr.Bytes(fileName, 34, 33 + LEN_FI); if (fi_padding) { dr.Zero(34 + LEN_FI, 34 + LEN_FI); } if (LEN_SU > 0) { dr.Bytes(b_su, LEN_DR - LEN_SU + 1, LEN_DR); } return(realName); }