private void GenContinuationBlock() { ContinuationBlock = generator.Index / LogicalBlockSize; ContinuationLength = -generator.Index; // HACK ALERT: we will add the final offset when done, and that will give us the length // ER - Extensions Reference - see P1281 section 5.5 byte[] b_id = generator.Ascii.GetBytes("RRIP_1991A"); // I can't find documentation anywhere for these values, but they came from an ISO I analyzed. byte[] b_des = generator.Ascii.GetBytes("THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS"); byte[] b_src = generator.Ascii.GetBytes("PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION."); var er = new FieldValidator(generator); er.Byte((byte)'E', 1); er.Byte((byte)'R', 2); System.Diagnostics.Debug.Assert((9 + b_id.Length + b_des.Length + b_src.Length) < 256); er.Byte((byte)(8 + b_id.Length + b_des.Length + b_src.Length), 3); er.Byte(1, 4); // version er.Byte((byte)b_id.Length, 5); er.Byte((byte)b_des.Length, 6); er.Byte((byte)b_src.Length, 7); er.Byte(1, 8); // extension version ( got this value from peeking at another ISO file ) er.Bytes(b_id, 9, 9 + b_id.Length - 1); er.Bytes(b_des, 9 + b_id.Length, 9 + b_id.Length + b_des.Length - 1); er.Bytes(b_src, 9 + b_id.Length + b_des.Length, 9 + b_id.Length + b_des.Length + b_src.Length - 1); ContinuationLength += generator.Index; generator.FinishBlock(); }
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(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 analyzing 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 void GenPathTableEx(IsoFolder parentFolder, IsoFolder thisFolder, bool lsb) { var di = new FieldValidator(generator); // Path table record ( ECMA-119 section 9.4 ) byte[] b_di = generator.IsoName(thisFolder.Name, true); di.Byte((byte)b_di.Length, 1); di.Byte(0, 2); // Extended Attribute Record Length if (lsb) { di.IntLSB(thisFolder.DataBlock, 3, 6); // Location of Extent di.ShortLSB(parentFolder.PathTableEntry, 7, 8); // Parent Directory Number } else { di.IntMSB(thisFolder.DataBlock, 3, 6); // Location of Extent di.ShortMSB(parentFolder.PathTableEntry, 7, 8); // Parent Directory Number } di.Bytes(b_di, 9, 8 + b_di.Length); // Directory Identifier if ((b_di.Length & 1) != 0) di.Byte(0, 9 + b_di.Length); // optional padding if LEN_DI is odd foreach (KeyValuePair<string, IsoEntry> it in thisFolder.entries) if (it.Value.IsFolder) GenPathTableEx(thisFolder, (IsoFolder)it.Value, lsb); }