Beispiel #1
0
		public void AddEntry(string path, IsoEntry e)
		{
			var tmp = path.IndexOf('/');
			if (tmp >= 0) {
				string subpath = path.Substring(tmp + 1).Trim();
				path = path.Substring(0, tmp).Trim();
			}
		}
Beispiel #2
0
        public void AddEntry(string path, IsoEntry e)
        {
            var tmp = path.IndexOf('/');

            if (tmp >= 0)
            {
                string subpath = path.Substring(tmp + 1).Trim();
                path = path.Substring(0, tmp).Trim();
            }
        }
        private void susp_rr_rr(MemoryStream m, IsoEntry e)         // IEEE P1282 Rock Ridge Protocol Identifier ( ? - I can't find this documented, but analysis of iso files reveals it's existence )
        {
            int start = (int)m.Length;

            m.WriteByte((byte)'R');
            m.WriteByte((byte)'R');
            m.WriteByte(5);             // LEN_RR
            m.WriteByte(1);             // Version
            m.WriteByte(e.RrFlags);     // flags
            System.Diagnostics.Debug.Assert((m.Length - start) == 5);
        }
        /// <summary>
        ///  This function is responsible for generating directory records. However, since more than one directory
        ///  record may be required to get all the information out, it defers the actual directory record generation
        ///  to a sub-function DirectoryRecordEx().
        /// </summary>
        /// <param Name="name">The real folder Name</param>
        /// <param Name="e">object containing info about the folder</param>
        /// <param Name="root">1==PVD's root entry, 2==root's "." entry, 0==everything else ( special stuff needs to happen for the root entries )</param>
        private void DirectoryRecord(string name, IsoEntry e, byte root)
        {
            byte[] fileName = this.generator.IsoName(name, true);
            string cont     = DirectoryRecordEx(fileName, name, e, root, false);

#if ROCKRIDGE
            while (cont.Length > 0)
            {
                cont = DirectoryRecordEx(fileName, cont, e, 0, true);
            }
#endif
        }
        private string susp_rr_nm(MemoryStream m, string name, byte available, IsoEntry e)         // IEEE P1282 Alternate Name ( 4.1.4 )
        {
            int start = (int)m.Length;

            if (m.Length > available)
            {
                throw new Exception("buffer overflow - internal design error");
            }

            available -= (byte)m.Length;
            string cont  = "";
            byte   flags = 0;

            if (name == ".")
            {
                flags |= 2;
            }
            else if (name == "..")
            {
                flags |= 4;
            }
            else if (name.Length > (available - 5))
            {
                flags |= 1;                 // need another entry...
                cont   = name.Substring(available - 5);
                name   = name.Substring(0, available - 5);
            }

            e.RrFlags |= 0x08;
            m.WriteByte((byte)'N');
            m.WriteByte((byte)'M');
            m.WriteByte((byte)(name.Length + 5));
            m.WriteByte(1);             // version?
            m.WriteByte(flags);
            m.Write(this.generator.Ascii.GetBytes(name), 0, name.Length);
            System.Diagnostics.Debug.Assert((m.Length - start) == (name.Length + 5));
            return(cont);
        }
        /// <summary>
        /// add a file to the ISO ( common implementation - called by AddFile() and AddBootFile() )
        /// </summary>
        private IsoFile AddFileEx(string path, FileInfo fileInfo)
        {
            string key;

            string[]  ar = NormalizePath(path).Split('/');
            int       i;
            IsoFolder f = this.isoRoot;

            for (i = 0; i < ar.Length - 1; i++)
            {
                key = ar[i].Trim().ToLower();
                if (!f.entries.ContainsKey(key))
                {
                    var subf = new IsoFolder();
                    subf.Name      = ar[i].Trim();
                    f.entries[key] = subf;
                }
                IsoEntry e = f.entries[key];
                if (e.IsFile)
                {
                    throw new Exception("cannot create directory \"" + ar[i].Trim() + "\", a file by that Name already exists");
                    //return;
                }
                f = (IsoFolder)e;
            }
            var x = new IsoFile(fileInfo);

            x.Name = ar[i].Trim();
            key    = ar[i].Trim().ToLower();
            if (f.entries.ContainsKey(key))
            {
                //throw new Exception("file or folder by that Name already exists");
                return((IsoFile)f.entries[key]);                // just don't add it for now...
            }
            f.entries[key] = x;

            return(x);
        }
        /// <summary>
        /// create directory in ISO file
        /// </summary>
        public void MkDir(string path)
        {
            IsoFolder f = this.isoRoot;

            string[] ar = NormalizePath(path).Split('/');
            for (int i = 0; i < ar.Length; i++)
            {
                string key = ar[i].Trim().ToLower();
                if (!f.entries.ContainsKey(key))
                {
                    var subf = new IsoFolder();
                    subf.Name      = ar[i].Trim();
                    f.entries[key] = subf;
                }
                IsoEntry e = f.entries[key];
                if (e.IsFile)
                {
                    //throw new Exception("cannot create directory \"" + ar[i].Trim() + "\", a file by that Name already exists");
                    return;                     // already exists - silently fail for now
                }
                f = (IsoFolder)e;
            }
        }
        private byte[] Susp(ref string name, IsoEntry e, bool root, bool secondPass, byte available)         // IEEE P1282 SUSP
        {
            MemoryStream m    = new MemoryStream();
            bool         dots = (name == "." || name == "..");

            if (!secondPass)
            {
                if (root)
                {
                    susp_base_sp(m);
                    susp_base_ce(m);
                }
                if (e.RrFlags != 0)
                {
                    susp_rr_rr(m, e);
                }
            }

            // TODO FIXME - write and generate susp_rr_tf() - timestamps...
            if (dots)
            {
                name = "";
            }
            else if (name.Length > 0)
            {
                name = susp_rr_nm(m, name, available, e);
            }

            if ((m.Length & 1) != 0)
            {
                m.WriteByte(0);                                  // padding
            }
            byte[] b = m.GetBuffer();
            Array.Resize(ref b, (int)m.Length);
            return(b);
        }
Beispiel #9
0
		private string susp_rr_nm(MemoryStream m, string name, byte available, IsoEntry e) // IEEE P1282 Alternate Name ( 4.1.4 )
		{
			int start = (int)m.Length;
			if (m.Length > available)
				throw new Exception("buffer overflow - internal design error");

			available -= (byte)m.Length;
			string cont = "";
			byte flags = 0;
			if (name == ".")
				flags |= 2;
			else if (name == "..")
				flags |= 4;
			else if (name.Length > (available - 5)) {
				flags |= 1; // need another entry...
				cont = name.Substring(available - 5);
				name = name.Substring(0, available - 5);
			}

			e.RrFlags |= 0x08;
			m.WriteByte((byte)'N');
			m.WriteByte((byte)'M');
			m.WriteByte((byte)(name.Length + 5));
			m.WriteByte(1); // version?
			m.WriteByte(flags);
			m.Write(this.generator.Ascii.GetBytes(name), 0, name.Length);
			System.Diagnostics.Debug.Assert((m.Length - start) == (name.Length + 5));
			return cont;
		}
Beispiel #10
0
		private void susp_rr_rr(MemoryStream m, IsoEntry e) // IEEE P1282 Rock Ridge Protocol Identifier ( ? - I can't find this documented, but analysis of iso files reveals it's existence )
		{
			int start = (int)m.Length;
			m.WriteByte((byte)'R');
			m.WriteByte((byte)'R');
			m.WriteByte(5); // LEN_RR
			m.WriteByte(1); // Version
			m.WriteByte(e.RrFlags); // flags
			System.Diagnostics.Debug.Assert((m.Length - start) == 5);
		}
Beispiel #11
0
		private byte[] Susp(ref string name, IsoEntry e, bool root, bool secondPass, byte available) // IEEE P1282 SUSP
		{
			MemoryStream m = new MemoryStream();
			bool dots = (name == "." || name == "..");

			if (!secondPass) {
				if (root) {
					susp_base_sp(m);
					susp_base_ce(m);
				}
				if (e.RrFlags != 0)
					susp_rr_rr(m, e);
			}

			// TODO FIXME - write and generate susp_rr_tf() - timestamps...
			if (dots)
				name = "";
			else if (name.Length > 0)
				name = susp_rr_nm(m, name, available, e);

			if ((m.Length & 1) != 0) m.WriteByte(0); // padding
			byte[] b = m.GetBuffer();
			Array.Resize(ref b, (int)m.Length);
			return b;
		}
Beispiel #12
0
		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;
		}
Beispiel #13
0
		/// <summary>
		///  This function is responsible for generating directory records. However, since more than one directory
		///  record may be required to get all the information out, it defers the actual directory record generation
		///  to a sub-function DirectoryRecordEx().
		/// </summary>
		/// <param Name="name">The real folder Name</param>
		/// <param Name="e">object containing info about the folder</param>
		/// <param Name="root">1==PVD's root entry, 2==root's "." entry, 0==everything else ( special stuff needs to happen for the root entries )</param>
		private void DirectoryRecord(string name, IsoEntry e, byte root)
		{
			byte[] fileName = this.generator.IsoName(name, true);
			string cont = DirectoryRecordEx(fileName, name, e, root, false);
#if ROCKRIDGE
			while (cont.Length > 0) {
				cont = DirectoryRecordEx(fileName, cont, e, 0, true);
			}
#endif
		}
        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);
        }