Ejemplo n.º 1
0
		/// <summary>
		/// writes a file out to cd. Generate the Boot Info Table if necessary
		/// </summary>
		/// <param Name="f">the file to write</param>
		/// <param Name="primaryVolumeDescriptor">the PVD block, passed in case we need to generate the Boot Info Table</param>
		public void WriteFile(IsoFile f, int primaryVolumeDescriptor)
		{
			if (f.fileInfo.Length > 0xffffffff)
				throw new NotImplementedException(">4G files not implemented");

			int bytes = (int)f.fileInfo.Length;
			if (this.fs == null)
			{
				this.Index += bytes;
				return;
			}

			// TODO FIXME - create smaller reusable buffer and read fixed-size chunks at a time...
			byte[] b = new byte[bytes];

			using (FileStream stream = f.fileInfo.OpenRead())
			{
				if (bytes != stream.Read(b, 0, bytes))
					throw new Exception("number of bytes read from file != reported length of file: " + f.fileInfo.Name);
			}

			if (f.BootInfoTable)
			{
				uint checksum = CalculateChecksum(b);

				// TODO FIXME - this is TERRIBLE. This should be implemented at a higher level, and
				// doing it here requires passing the primaryVolumeDescriptor to every call of WriteFile()
				// The reason it is here is because this is the only place where the file actually gets
				// pulled into memory and I didn't want to modify the boot image on-disk like mkisofs does.
				Bytes(b, 0, 8);
				Bytes(ConvertTo.Int2LSB(primaryVolumeDescriptor));
				Bytes(ConvertTo.Int2LSB(f.DataBlock));
				Bytes(ConvertTo.Int2LSB((int)f.fileInfo.Length));
				Bytes(ConvertTo.Int2LSB((int)checksum));
				DupByte(0, 40); // reserved
				Bytes(b, 64, bytes - 64);
			}
			else
				Bytes(b);
		}
Ejemplo n.º 2
0
		private void GenBootCatalog(IsoFile f)
		{
			BootCatalog = generator.Index / LogicalBlockSize;

			// write validation entry first... see El Torito section 2.1
			var ve = new FieldValidator(generator);
			ve.Byte(1, 1); // Header ID, must be 0x01
			ve.Byte(0, 2); // 0 == x86 - TODO FIXME: 1 == PowerPC, 2 == Mac, see El Torito figure 2
			ve.DupByte(0, 3, 4); // Reserved
			ve.DupByte(0, 5, 0x1C); // Manufacturer/Developer of CD-ROM, see El Torito figure 2
			ve.ShortLSB(0x55AA, 0x1D, 0x1E); // checksum - TODO FIXME - allow custom Manufacturer string - calculate checksum dynamically
			ve.Byte(0x55, 0x1F); // 1st Key Byte
			ve.Byte(0xAA, 0x20); // 2nd Key Byte

			// initial/default entry... see El Torito section 2.2 and figure 3
			var ide = new FieldValidator(generator);
			ide.Byte(0x88, 1); // 0x88 = bootable, 0x00 = not bootable

			// TODO FIXME - this is extremely hackish... fix me...
			ide.Byte(0, 2); // no emulation
			/*if ( f.fileInfo.Length <= 1182720 )
				ide.Byte(1, 2); // 1.2 meg diskette
			else if ( f.fileInfo.Length <= 1440 * 1024 )
				ide.Byte(2,2); // 1.44 meg diskette
			else if ( f.fileInfo.Length <= 2880 * 1024 )
				ide.Byte(3,2); // 2.88 meg diskette
			else
				ide.Byte(4,2);*/

			// Hard Disk ( drive 80 )

			ide.ShortLSB(0, 3, 4); // Load Segment - 0 == default of 0x7C0
			ide.Byte(0, 5); // System Type, according to El Torito figure 3 this MUST be a copy of the "System Type" from the boot image. In practice this appears to not be the case.
			ide.Byte(0, 6); // Unused, must be 0
			if (bootLoadSize == 0)
				bootLoadSize = (short)((f.fileInfo.Length - 1) / 0x200 + 1);
			ide.ShortLSB(bootLoadSize, 7, 8); // Sector Count
			ide.IntLSB(boot.DataBlock, 9, 12); // Logical Block of boot image
			ide.Zero(13, 32); // unused

			generator.FinishBlock();
		}
Ejemplo n.º 3
0
		private void GenFile(IsoFile f)
		{
			f.DataBlock = generator.Index / LogicalBlockSize;
			f.DataLength = (int)f.fileInfo.Length;
			generator.WriteFile(f, PrimaryVolumeDescriptor);
			generator.FinishBlock();
		}
Ejemplo n.º 4
0
		/// <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 = 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;
		}