Exemple #1
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="mainmode">main channel mode</param>
		/// <param name="submode">subchannel mode</param>
		/// <param name="c2mode">C2 errors report mode</param>
		/// <param name="exp">expected sector type</param>
		/// <param name="dap"></param>
		/// <param name="start"></param>
		/// <param name="length"></param>
		/// <param name="data">the memory area </param>
		/// <param name="timeout">timeout (in seconds)</param>
		/// <returns></returns>
		public CommandStatus ReadCDAndSubChannel(MainChannelSelection mainmode, SubChannelMode submode, C2ErrorMode c2mode, byte exp, bool dap, uint start, uint length, IntPtr data, int timeout)
		{
			if (m_logger != null)
			{
				string args = exp.ToString() + ", " + dap.ToString() + ", " + start.ToString() + ", " + length.ToString() + ", data";
				m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadCD(" + args + ")"));
			}

			int size = (4 * 588 +
				(submode == SubChannelMode.QOnly ? 16 : submode == SubChannelMode.RWMode ? 96 : 0) +
				(c2mode == C2ErrorMode.Mode294 ? 294 : c2mode == C2ErrorMode.Mode296 ? 296 : 0)) * (int) length;

			byte mode = (byte) (submode == SubChannelMode.QOnly ? 2 : submode == SubChannelMode.RWMode ? 4 : 0);

			if (exp != 1 && exp != 2 && exp != 3 && exp != 4 && exp != 5)
				return CommandStatus.NotSupported;

			using (Command cmd = new Command(ScsiCommandCode.ReadCd, 12, data, size, Command.CmdDirection.In, timeout))
			{
				byte b = (byte)((exp & 0x07) << 2);
				if (dap)
					b |= 0x02;
                byte byte9 = (byte)(mainmode == MainChannelSelection.UserData ? 0x10 : mainmode == MainChannelSelection.F8h ? 0xF8 : 0);
				if (c2mode == C2ErrorMode.Mode294)
					byte9 |= 0x02;
				else if (c2mode == C2ErrorMode.Mode296)
					byte9 |= 0x04;
				cmd.SetCDB8(1, b);
				cmd.SetCDB32(2, start);
				cmd.SetCDB24(6, length);
				cmd.SetCDB8(9, byte9); // User data + possibly c2 errors
				cmd.SetCDB8(10, mode);          // Subchannel
                CommandStatus st = SendCommand(cmd);
				if (st != CommandStatus.Success)
					return st;
			}

			return CommandStatus.Success;
		}
Exemple #2
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus StartStopUnit(bool immd, PowerControl pc, StartState state)
        {
            if (m_logger != null)
            {
                string args = immd.ToString() + ", " + pc.ToString() + ", " + state.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.StartStopUnit(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.StartStopUnit, 6, 0, Command.CmdDirection.None, 30))
            {
                if (immd)
                    cmd.SetCDB8(1, 1) ;

                byte b = (byte)(((byte)pc << 4) | ((byte)state)) ;
                cmd.SetCDB8(4, b) ;

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }
            return CommandStatus.Success; 
        }
Exemple #3
0
        /// <summary>
        /// This method requests that the SCSI device transfer data from the given buffer to the device
        /// </summary>
        /// <param name="force">If true, the data is forced from the media and cannot be read from the cache</param>
        /// <param name="streaming">If true, this is a streaming read</param>
        /// <param name="lba">The starting logical address for the data</param>
        /// <param name="sector_size">the size of the sector data in bytes</param>
        /// <param name="length">The length of the data to write in sectors</param>
        /// <param name="data">The data buffer to received the data</param>
        /// <returns></returns>
        public CommandStatus Write(bool force, bool streaming, int lba, int sector_size, int length, ref byte[] data)
        {
            if (m_logger != null)
            {
                string args = force.ToString() + ", " + streaming.ToString() + ", " + lba.ToString() + ", " + length.ToString() + ", buffer";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Write(" + args + ")"));
            }

            Debug.Assert(length == data.GetLength(0) * sector_size);

            fixed (byte *bptr = &data[0])
            {
                IntPtr bufptr = new IntPtr(bptr);
                if (streaming || length > 65535)
                {
                    using (Command cmd = new Command(ScsiCommandCode.Write12, 12, bufptr, length * sector_size, Command.CmdDirection.Out, 5 * 60))
                    {
                        if (force)
                            cmd.SetCDB8(1, 4);              // Set the FUA bit

                        cmd.SetCDB32(2, lba);
                        cmd.SetCDB32(6, length);

                        if (streaming)
                            cmd.SetCDB8(10, 0x80);          // Set the streaming bit

                        CommandStatus st = SendCommand(cmd);
                        if (st != CommandStatus.Success)
                            return st;
                    }
                }
                else
                {
                    using (Command cmd = new Command(ScsiCommandCode.Write, 10, bufptr, length * sector_size, Command.CmdDirection.Out, 5 * 60))
                    {
                        if (force)
                            cmd.SetCDB8(1, 4);              // Set the FUA bit

                        cmd.SetCDB32(2, lba);
                        cmd.SetCDB16(7, (ushort)length);

                        CommandStatus st = SendCommand(cmd);
                        if (st != CommandStatus.Success)
                            return st;
                    }
                }
            }

            return CommandStatus.Success;
        }
Exemple #4
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus SendOpcInformation(bool doopc, object o)
        {
            if (m_logger != null)
            {
                string args = doopc.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SendOpcInformation(" + args + ")"));
            }

            ushort len = 0;

            if (o != null)
                throw new Exception("SendOpcInformation() - non-null OPC information not supported");

            using (Command cmd = new Command(ScsiCommandCode.SendOpcInformation, 10, len, Command.CmdDirection.Out, 60))
            {
                if (doopc)
                    cmd.SetCDB8(1, 1);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }
            return CommandStatus.Success;
        }
Exemple #5
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus SetStreaming(SpeedDescriptor desc)
        {
            if (m_logger != null)
            {
                string args = "desc";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SetStreaming(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.SetStreaming, 12, 28, Command.CmdDirection.Out, 2))
            {
                cmd.SetCDB8(8, 0);          // Performance Descriptor
                cmd.SetCDB16(9, 28);        // Length of the performance descriptor

                byte b = 0;
                if (desc.Exact)
                    b |= 0x02;
                int wrc = (int)(desc.WRC) ;
                b |= (byte)(wrc << 3);
                cmd.SetBuffer8(0, b);               // Control info, byte 0

                cmd.SetBuffer32(4, 0);                          // Start LBA
                cmd.SetBuffer32(8, (uint)desc.EndLBA);                // End LBA
                cmd.SetBuffer32(12, (uint)desc.ReadSpeed);            // Read size
                cmd.SetBuffer32(16, 1000);                      // Read time
                cmd.SetBuffer32(20, (uint)desc.WriteSpeed);           // Write size
                cmd.SetBuffer32(24, 1000);                      // Write time

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }

            return CommandStatus.Success;
        }
Exemple #6
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus ReadTrackInformation(ReadTrackType type, uint addr, out TrackInformation info)
        {
            info = null;

            if (m_logger != null)
            {
                string args = "info";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadTrackInformation(" + args + ")"));
            }
            using (Command cmd = new Command(ScsiCommandCode.ReadTrackInformation, 10, 48, Command.CmdDirection.In, 5 * 60))
            {
                cmd.SetCDB8(1, (byte)type);
                cmd.SetCDB32(2, addr);
                cmd.SetCDB16(7, 40);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                info = new TrackInformation(cmd.GetBuffer(), cmd.BufferSize);
            }
            return CommandStatus.Success;
        }
Exemple #7
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus Scan(ScanDirection dir, uint lba, ScanType type)
        {
            if (m_logger != null)
            {
                string args = dir.ToString() + ", " + lba.ToString() + ", " + type.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Scan(" + args + ")"));
            }

            if (type == ScanType.Reserved)
                throw new Exception("type parameter is of type Reserved");

            using (Command cmd = new Command(ScsiCommandCode.Scan, 12, 0, Command.CmdDirection.None, 10))
            {
                if (dir == ScanDirection.Reverse)
                    cmd.SetCDB8(1, 0x10);
                cmd.SetCDB32(2, lba);
                cmd.SetCDB8(9, (byte)((byte)type << 6));

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }

            return CommandStatus.Success;
        }
Exemple #8
0
        /// <summary>
        /// This method reads the PAC data for a blu-ray disk
        /// </summary>
        /// <param name="pacid">the pac id of the pac to read</param>
        /// <param name="pacfmt">the format of the pac to read</param>
        /// <param name="data">return storage for the pac data</param>
        /// <returns></returns>
        public CommandStatus ReadDiskStructurePac(uint pacid, byte pacfmt, out byte [] data)
        {
            data = null;

            if (m_logger != null)
            {
                string args = "out byte[] data";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDvdStructurePac(" + args + ")"));
            }

            ushort len = 4;
            using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, len, Command.CmdDirection.In, 60))
            {
                cmd.SetCDB24(2, pacid);
                cmd.SetCDB8(6, pacfmt);
                cmd.SetCDB8(7, 0x30);            // Read PAC data
                cmd.SetCDB16(8, len);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                len = (ushort)(cmd.GetBuffer16(0) + 2);
                if (len == 2)
                {
                    data = new byte[0];
                    return CommandStatus.Success;
                }
                Debug.Assert(len < 8192);
            }

            using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, len, Command.CmdDirection.In, 60))
            {
                cmd.SetCDB24(2, pacid);
                cmd.SetCDB8(6, pacfmt);
                cmd.SetCDB8(7, 0x30);         // Read manufacturing information
                cmd.SetCDB16(8, len);          // Up to 2k of data

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                len = (ushort)(cmd.GetBuffer16(0) + 2);
                data = new byte[len];
                Marshal.Copy(cmd.GetBuffer(), data, 0, len);
            }

            return CommandStatus.Success;
        }
Exemple #9
0
        /// <summary>
        /// Return the data from a ReadDvdStructure request as a series of bytes.
        /// </summary>
        /// <param name="format">the format of the read dvd structure request</param>
        /// <param name="data">the AACS volume identifier</param>
        /// <returns>status of command execution</returns>
        private CommandStatus ReadDiskStructureReturnBytes(byte format, out byte[] data)
        {
            data = null;

            if (m_logger != null)
            {
                string args = "out byte[] data";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDvdStructureAACSVolumeIdentifier(" + args + ")"));
            }

            ushort len = 4;
            using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, len, Command.CmdDirection.In, 60))
            {
                cmd.SetCDB8(7, format);         // Read manufacturing information
                cmd.SetCDB16(8, len);          // Up to 2k of data

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                len = cmd.GetBuffer16(0);
                if (len == 0)
                {
                    data = new byte[0];
                    return CommandStatus.Success;
                }
                Debug.Assert(len < 8192);
            }

            using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, len, Command.CmdDirection.In, 60))
            {
                cmd.SetCDB8(7, format);         // Read manufacturing information
                cmd.SetCDB16(8, len);          // Up to 2k of data

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                len = cmd.GetBuffer16(0);
                data = new byte[len];
                Marshal.Copy(cmd.GetBuffer(), data, 0, len);
            }

            return CommandStatus.Success;
        }
Exemple #10
0
		/// <summary>
		/// Read the subchannel data from a series of sectors
		/// </summary>
		/// <param name="mode">subchannel mode</param>
		/// <param name="track">track number</param>
		/// <param name="data">output buffer</param>
		/// <param name="offs">output buffer offset</param>
		/// <param name="timeout">timeout (in seconds)</param>
		/// <returns></returns>
		public CommandStatus ReadSubChannel42(byte mode, int track, ref byte[] data, int offs, int timeout)
		{
			if (m_logger != null)
			{
				m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadSubChannel42()"));
			}

			if (mode != 1 && mode != 2 && mode != 3)
				throw new Exception("invalid read mode for ReadSubchannel42() call");

			int size = mode == 1 ? 16 : 24;
			if (offs + data.GetLength(0) < size)
				throw new Exception("data buffer is not large enough to hold the data requested");

			using (Command cmd = new Command(ScsiCommandCode.ReadSubChannel, 10, size, Command.CmdDirection.In, timeout))
			{
				// 42 00 40 01  00 00 00 00 10 00
				//cmd.SetCDB8(1, 2); // MSF
				cmd.SetCDB8(2, 64); // SUBQ
				cmd.SetCDB8(3, mode);
				cmd.SetCDB8(6, (byte)track);
				cmd.SetCDB16(7, (ushort)size);

				CommandStatus st = SendCommand(cmd);
				if (st != CommandStatus.Success)
					return st;

				Marshal.Copy(cmd.GetBuffer(), data, offs, size);
			}
			return CommandStatus.Success;
		}
Exemple #11
0
        /// <summary>
        /// Read the CD text information from the leadin using the ReadTocPmaAtip command form
        /// </summary>
        /// <param name="data"></param>
		/// <param name="_timeout"></param>
        /// <returns></returns>
        public CommandStatus ReadCDText(out byte [] data, int _timeout)
        {
            ushort len;

            if (m_logger != null)
            {
                string args = "info";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadCDText(" + args + ")"));
            }

            data = null;
			using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 4, Command.CmdDirection.In, _timeout))
            {
                cmd.SetCDB8(2, 5);                  // CDText info in leadin
                cmd.SetCDB16(7, 4);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                len = cmd.GetBuffer16(0);
                len += 2;

                if (len <= 4)
                {
                    data = new byte[len];
                    Marshal.Copy(cmd.GetBuffer(), data, 0, len);
                    return CommandStatus.Success;
                }
            }

			using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, len, Command.CmdDirection.In, _timeout))
            {
                cmd.SetCDB8(2, 5);                 // CDText info in leadin
                cmd.SetCDB16(7, len);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                data = new byte[len];
                Marshal.Copy(cmd.GetBuffer(), data, 0, len);
            }

            return CommandStatus.Success;
        }
Exemple #12
0
        /// <summary>
        /// Read the subchannel data from a series of sectors
        /// </summary>
        /// <param name="sector"></param>
        /// <param name="length"></param>
        /// <param name="data"></param>
        /// <param name="mode">the subchannel mode</param>
		/// <param name="timeout">timeout (in seconds)</param>
        /// <returns></returns>
        public CommandStatus ReadSubChannel(byte mode, uint sector, uint length, ref byte[] data, int timeout)
        {
            byte bytes_per_sector;

            if (m_logger != null)
            {
                string args = sector.ToString() + ", " + length.ToString() + ", data";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadSubChannel(" + args + ")"));
            }

            if (mode != 1 && mode != 2 && mode != 4)
                throw new Exception("invalid read mode for ReadSubchannel() call");

            bytes_per_sector = 96;
            if (mode == 2)
                bytes_per_sector = 16;

            if (data.GetLength(0) < length * bytes_per_sector)
                throw new Exception("data buffer is not large enough to hold the data requested");


            using (Command cmd = new Command(ScsiCommandCode.ReadCd, 12, (int)(length * bytes_per_sector), Command.CmdDirection.In, timeout))
            {
                byte b = (byte)(1 << 2);
                cmd.SetCDB8(1, b);
                cmd.SetCDB32(2, sector);            // The sector number to start with
                cmd.SetCDB24(6, length);            // The length in sectors
                cmd.SetCDB8(10, mode);                 // Corrected, de-interleaved P - W data

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                Marshal.Copy(cmd.GetBuffer(), data, 0, (int)(length * bytes_per_sector));
            }
            return CommandStatus.Success ;
        }
Exemple #13
0
        /// <summary>
        /// This method reads subheader CD data from a data mode 2 track
        /// </summary>
        /// <param name="sector">the sector # of the data to read</param>
        /// <param name="hdr">return subheader data</param>
        /// <returns></returns>
        public CommandStatus ReadCD(uint sector, out SubheaderData hdr)
        {
            hdr = null ;
            if (m_logger != null)
            {
                string args = sector.ToString() + ", out SubheaderData hdr";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadCD(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.ReadCd, 12, 4, Command.CmdDirection.In, 10))
            {
                cmd.SetCDB32(2, sector);
                cmd.SetCDB24(6, 1);
                cmd.SetCDB8(9, 0x40);          // Header data only

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                hdr = new SubheaderData(cmd.GetBuffer(), cmd.BufferSize);
            }

            return CommandStatus.Success;
        }
Exemple #14
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="submode">subchannel mode</param>
		/// <param name="start"></param>
		/// <param name="length"></param>
		/// <param name="data">the memory area </param>
		/// <param name="timeout">timeout (in seconds)</param>
		/// <returns></returns>
		public CommandStatus ReadCDDA(SubChannelMode submode, uint start, uint length, IntPtr data, int timeout)
		{
			if (m_logger != null)
			{
				string args = start.ToString() + ", " + length.ToString() + ", data";
				m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadCDDA(" + args + ")"));
			}

			byte mode = (byte)(submode == SubChannelMode.QOnly ? 1 : submode == SubChannelMode.RWMode ? 2 : 0);
			int size = 4 * 588 + (submode == SubChannelMode.QOnly ? 16 : submode == SubChannelMode.RWMode ? 96 : 0);

			using (Command cmd = new Command(ScsiCommandCode.ReadCDDA, 12, data, (int)length * size, Command.CmdDirection.In, timeout))
			{
				cmd.SetCDB8(1, 0 << 5); // lun
				cmd.SetCDB32(2, start);
				cmd.SetCDB24(7, length);
				cmd.SetCDB8(10, mode); // Subchannel

				CommandStatus st = SendCommand(cmd);
				if (st != CommandStatus.Success)
					return st;
			}

			return CommandStatus.Success;
		}
Exemple #15
0
        /// <summary>
        /// This method reads the ATIP information from a CD media
        /// </summary>
        /// <returns></returns>
        public CommandStatus ReadAtip(out AtipInfo info)
        {
            ushort len;
            info = null;

            if (m_logger != null)
            {
                string args = "info";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadAtip(" + args + ")"));
            }
            using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 32, Command.CmdDirection.In, 5 * 60))
            {
                cmd.SetCDB8(2, 4);
                cmd.SetCDB16(7, 32);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                len = cmd.GetBuffer16(0);
                len += 2;
            }

            if (len <= 4)
                return CommandStatus.Success;

            using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, len, Command.CmdDirection.In, 5 * 60))
            {
                cmd.SetCDB8(2, 4);
                cmd.SetCDB16(7, len);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                info = new AtipInfo(cmd.GetBuffer(), len);
            }

            return CommandStatus.Success;
        }
Exemple #16
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus ReadDiskStructure(uint addr, byte layer, byte format, ref byte [] data)
        {
            if (m_logger != null)
            {
                string args = string.Empty;
                args += "addr=" + addr.ToString();
                args += ", layer=" + layer.ToString();
                args += ", format=" + format.ToString();
                args += "ref byte[] data";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDvdStructure(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, 2048, Command.CmdDirection.In, 60))
            {
                cmd.SetCDB32(2, addr) ;         // Address = 0 
                cmd.SetCDB8(6, layer);          // Layer number = 0
                cmd.SetCDB8(7, format);         // Read manufacturing information
                cmd.SetCDB16(8, 2048);          // Up to 2k of data

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
                
                int len = data.GetLength(0);
                if (len > 2048)
                    len = 2048;
                Marshal.Copy(cmd.GetBuffer(), data, 0, len);
            }

            return CommandStatus.Success;
        }
Exemple #17
0
		/// <summary>
		/// This method reads the ATIP information from a CD media
		/// </summary>
		/// <returns></returns>
		public CommandStatus ReadPMA(out byte[] data)
		{
			ushort len;
			data = null;

			if (m_logger != null)
			{
				string args = "info";
				m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadFullToc(" + args + ")"));
			}
			using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 320, Command.CmdDirection.In, 5 * 60))
			{
				cmd.SetCDB8(1, 2);
				cmd.SetCDB8(2, 3);
				cmd.SetCDB16(7, 320);

				CommandStatus st = SendCommand(cmd);
				if (st != CommandStatus.Success)
					return st;

				len = cmd.GetBuffer16(0);
				len += 2;

				if (len <= 320)
				{
					data = new byte[len];
					Marshal.Copy(cmd.GetBuffer(), data, 0, len);
					return CommandStatus.Success;
				}
			}

			using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, len, Command.CmdDirection.In, 5 * 60))
			{
				cmd.SetCDB8(2, 3);
				cmd.SetCDB16(7, len);

				CommandStatus st = SendCommand(cmd);
				if (st != CommandStatus.Success)
					return st;

				//info = new AtipInfo(cmd.GetBuffer(), len);
				data = new byte[len];
				Marshal.Copy(cmd.GetBuffer(), data, 0, len);
			}

			return CommandStatus.Success;
		}
Exemple #18
0
        /// <summary>
        /// Query the media for the spare sectors available
        /// </summary>
        /// <param name="primary">the number of primary spare sectors available</param>
        /// <param name="sec_avail">the number of secondary spare sectors available</param>
        /// <param name="sec_total">the number of secondary spare sectors total</param>
        /// <returns></returns>
        public CommandStatus ReadDVDRamSpareAreaInfo(out uint primary, out uint sec_avail, out uint sec_total)
        {
            primary = 0;
            sec_avail = 0;
            sec_total = 0;

            if (m_logger != null)
            {
                string args = "out primary, out sec_avail, out sec_total";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDVDRamSpareAreaInfo(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, 2048, Command.CmdDirection.In, 60))
            {
                cmd.SetCDB8(7, 0x0a);         // Read manufacturing information
                cmd.SetCDB16(8, 16);          // Up to 2k of data

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                primary = cmd.GetBuffer32(4);
                sec_avail = cmd.GetBuffer32(8);
                sec_total = cmd.GetBuffer32(12);
            }

            return CommandStatus.Success;
        }
Exemple #19
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus RequestSense()
        {
            if (m_logger != null)
            {
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.RequestSense()"));
            }

            using (Command cmd = new Command(ScsiCommandCode.RequestSense, 6, 18, Command.CmdDirection.None, 5*60))
            {
                cmd.SetCDB8(4, 18);
                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                m_sense_info = new byte[18];
                Marshal.Copy(cmd.GetBuffer(), m_sense_info, 0, 18);
            }

            return CommandStatus.Success;
        }
Exemple #20
0
        /// <summary>
        /// Returns the size of layer 0 for DL media (DVD+R DL and DVD-R DL)
        /// </summary>
        /// <param name="isfixed">return value, if true size of L0 is changable</param>
        /// <param name="size">return value, the current size of L0</param>
        /// <returns>status of the command</returns>
        public CommandStatus ReadDvdLayer0Size(out bool isfixed, out uint size)
        {
            if (m_logger != null)
            {
                string args = "ReadDvdLayer0Size, out bool isfixed, out uint size";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDvdStructure(" + args + ")"));
            }

            size = 0;
            isfixed = false;

            using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, 12, Command.CmdDirection.In, 5 * 60))
            {
                cmd.SetCDB8(7, 0x20);         // Read manufacturing information
                cmd.SetCDB8(8, 12);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                if ((cmd.GetBuffer8(4) & 0x80) != 0)
                    isfixed = true;

                size = cmd.GetBuffer32(8);
            }

            return CommandStatus.Success;
        }
Exemple #21
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus SendCueSheet(byte [] sheet)
        {
            if (m_logger != null)
            {
                string args = sheet.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SendCueSheet(" + args + ")"));

                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 1, "Cue Sheet"));
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 1, "----------------------------------------------"));
                for (int i = 0; i < sheet.GetLength(0) / 8; i++)
                {
                    string s = "" ;

                    for (int j = 0; j < 8; j++)
                    {
                        if (j != 0)
                            s += " ";
                        s += sheet[i * 8 + j].ToString("x2");
                    }
                    m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 1, s));
                }
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 1, "----------------------------------------------"));
            }

            ushort len = (ushort)sheet.GetLength(0);
            using (Command cmd = new Command(ScsiCommandCode.SendCueSheet, 10, len, Command.CmdDirection.Out, 10))
            {
                cmd.SetCDB32(5, len);
                cmd.SetCDB8(5, 0);
                Marshal.Copy(sheet, 0, cmd.GetBuffer(), len);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }

            return CommandStatus.Success;
        }
Exemple #22
0
        /// <summary>
        /// Returns the start address of the Layer 0 middle zone (DVD+R DL, DVD-R DL)
        /// </summary>
        /// <param name="isfixed">return value, if true, the middle zone start is changeable</param>
        /// <param name="location">return value, the location of the L0 middle zone</param>
        /// <returns>status of the command</returns>
        public CommandStatus ReadDvdMiddleZoneStartAddr(out bool isfixed, out uint location)
        {
            if (m_logger != null)
            {
                string args = "ReadDvdMiddleZoneStartAddr, out bool isfixed, out uint size";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDvdStructure(" + args + ")"));
            }

            location = 0;
            isfixed = false;

            using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, 12, Command.CmdDirection.In, 5 * 60))
            {
                cmd.SetCDB8(7, 0x21);
                cmd.SetCDB8(8, 12);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                if ((cmd.GetBuffer8(4) & 0x80) != 0)
                    isfixed = true;

                location = cmd.GetBuffer32(8);
            }

            return CommandStatus.Success;
        }
Exemple #23
0
		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public CommandStatus SetCdSpeedDA(RotationalControl ctrl, ushort read, ushort write)
		{
			if (m_logger != null)
			{
				string args = ctrl.ToString() + ", " + read.ToString() + ", " + write.ToString();
				m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SetCdSpeed(" + args + ")"));
			}
			using (Command cmd = new Command((ScsiCommandCode)0xDA, 12, 0, Command.CmdDirection.None, 2))
			{
				cmd.SetCDB8(1, (byte)ctrl);
				cmd.SetCDB16(2, read);
				cmd.SetCDB16(4, write);

				CommandStatus st = SendCommand(cmd);
				if (st != CommandStatus.Success)
					return st;
			}
			return CommandStatus.Success;
		}
Exemple #24
0
        /// <summary>
        /// This method returns the remapping address (DVD-R DL(
        /// </summary>
        /// <param name="location">the remapping address</param>
        /// <returns>the command status</returns>
        public CommandStatus ReadDvdRemappingAddress(out uint location)
        {
            if (m_logger != null)
            {
                string args = "ReadDvdRemappingAddress, out uint size";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDvdStructure(" + args + ")"));
            }

            location = 0;

            using (Command cmd = new Command(ScsiCommandCode.ReadDvdStructure, 12, 12, Command.CmdDirection.In, 5 * 60))
            {
                cmd.SetCDB8(7, 0x24);
                cmd.SetCDB8(8, 12);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                location = cmd.GetBuffer32(8);
            }

            return CommandStatus.Success;
        }
Exemple #25
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus SetStreaming(RotationalControl rot, int startlba, int endlba, int readsize, int readtime, int writesize, int writetime)
        {
            if (m_logger != null)
            {
                string args = "desc";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SetStreaming(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.SetStreaming, 12, 28, Command.CmdDirection.Out, 60*5))
            {
                cmd.SetCDB8(8, 0);          // Performance Descriptor
                cmd.SetCDB16(9, 28);        // Length of the performance descriptor

                byte b = 0;
                int wrc = (int)rot;
                b |= (byte)(wrc << 3);
                cmd.SetBuffer8(0, b);               // Control info, byte 0

                cmd.SetBuffer32(4, (uint)startlba);             // Start LBA
                cmd.SetBuffer32(8, (uint)endlba);               // End LBA
                cmd.SetBuffer32(12, (uint)readsize);            // Read size
                cmd.SetBuffer32(16, (uint)readtime);            // Read time
                cmd.SetBuffer32(20, (uint)writesize);           // Write size
                cmd.SetBuffer32(24, (uint)writetime);           // Write time

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }

            return CommandStatus.Success;
        }
Exemple #26
0
        /// <summary>
        /// Send the layer boundary information to the drive.
        /// </summary>
        /// <param name="boundary">the location of the boundary between layers in blocks</param>
        /// <returns>the status of the command</returns>
        public CommandStatus SendDvdLayerBoundaryInformation(uint boundary)
        {
            if (m_logger != null)
            {
                string args = "SendDvdLayerBoundaryInformation, boundary=" + boundary.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SendDvdStructure(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.SendDvdStructure, 12, 12, Command.CmdDirection.Out, 5 * 60))
            {
                cmd.SetCDB8(7, 0x20);
                cmd.SetCDB16(8, 12);

                cmd.SetBuffer16(0, 10);
                cmd.SetBuffer32(8, boundary);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }

            return CommandStatus.Success;
        }
Exemple #27
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus SynchronizeCache(bool immd)
        {
            if (m_logger != null)
            {
                string args = "";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SynchronizeCache(" + args + ")"));
            }
            using (Command cmd = new Command(ScsiCommandCode.SyncronizeCache, 10, 0, Command.CmdDirection.None, 30 * 60))
            {
                if (immd)
                    cmd.SetCDB8(1, 2);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }
            return CommandStatus.Success;
        }
Exemple #28
0
        /// <summary>
        /// Read the table of contents from the disk
        /// </summary>
        /// <param name="track">the track or session to find the TOC for</param>
        /// <param name="toc">a list return value containins a list of table of content entryies</param>
        /// <param name="mode">time versus lba mode</param>
        /// <returns></returns>
        public CommandStatus ReadToc(byte track, bool mode, out IList<TocEntry> toc)
        {
            ushort len;
            toc = null;

            if (m_logger != null)
            {
                string args = "info";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadToc(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, 16, Command.CmdDirection.In, 5 * 60))
            {
                if (mode)
                    cmd.SetCDB8(1, 2);
                cmd.SetCDB8(6, track);
                cmd.SetCDB16(7, 16);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                len = cmd.GetBuffer16(0);
                len += 2;
            }

            using (Command cmd = new Command(ScsiCommandCode.ReadTocPmaAtip, 10, len, Command.CmdDirection.In, 5 * 60))
            {
                if (mode)
                    cmd.SetCDB8(1, 2);
                cmd.SetCDB8(6, track);
                cmd.SetCDB16(7, len);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                int offset = 4;
                toc = new List<TocEntry>();

                while (offset + 8 <= len)
                {
                    TocEntry entry = new TocEntry(cmd.GetBuffer(), offset, cmd.BufferSize, mode);
                    toc.Add(entry);

                    offset += 8;
                }
            }

            return CommandStatus.Success;
        }
Exemple #29
0
        /// <summary>
        /// Write data to the device into a memory buffer
        /// </summary>
        /// <param name="force">If true, the data is forced from the media and cannot be read from the cache</param>
        /// <param name="streaming">If true, this is a streaming read</param>
        /// <param name="lba">The starting logical address for the data</param>
        /// <param name="sector_size">the size of a sector in bytes</param>
        /// <param name="length">The length of the data to write in sectors</param>
        /// <param name="data">The buffer to receive the data</param>
        /// <returns></returns>
        public CommandStatus Write(bool force, bool streaming, int lba, int sector_size, int length, IntPtr data)
        {
            if (m_logger != null)
            {
                string args = force.ToString() + ", " + streaming.ToString() + ", " + lba.ToString() + ", " + length.ToString() + ", IntPtr, ";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Write(" + args + ")"));
            }

            if (streaming || length > 65535)
            {
                using (Command cmd = new Command(ScsiCommandCode.Write12, 12, data, length * sector_size, Command.CmdDirection.Out, 5 * 60))
                {
                    if (force)
                        cmd.SetCDB8(1, 4);          // Set the FUA bit

                    cmd.SetCDB32(2, lba);
                    cmd.SetCDB32(6, length);

                    if (streaming)
                        cmd.SetCDB8(10, 0x80);

                    CommandStatus st = SendCommand(cmd);
                    if (st != CommandStatus.Success)
                    {
                        m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 4, "Write failed at lba " + lba.ToString()));
                        return st;
                    }
                }
            }
            else
            {
                using (Command cmd = new Command(ScsiCommandCode.Write, 10, data, length * sector_size, Command.CmdDirection.Out, 5 * 60))
                {
                    if (force)
                        cmd.SetCDB8(1, 4);              // Set the FUA bit

                    cmd.SetCDB32(2, lba);
                    cmd.SetCDB16(7, (ushort)length);

                    CommandStatus st = SendCommand(cmd);
                    if (st != CommandStatus.Success)
                    {
                        m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 4, "Write failed at lba " + lba.ToString()));
                        return st;
                    }
                }
            }

            return CommandStatus.Success;
        }
Exemple #30
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="exp"></param>
        /// <param name="dap"></param>
        /// <param name="start"></param>
        /// <param name="length"></param>
        /// <param name="data">the memory area </param>
        /// <param name="size">the size of the memory area given by the data parameter</param>
        /// <returns></returns>
        public CommandStatus ReadCD(byte exp, bool dap, uint start, uint length, IntPtr data, int size)
        {
            if (m_logger != null)
            {
                string args = exp.ToString() + ", " + dap.ToString() + ", " + start.ToString() + ", " + length.ToString() + ", data, " + size.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadCD(" + args + ")"));
            }

            if (exp != 1 && exp != 2 && exp != 3 && exp != 4 && exp != 5)
                return CommandStatus.NotSupported;

            using (Command cmd = new Command(ScsiCommandCode.ReadCd, 12, data, size, Command.CmdDirection.In, 5 * 60))
            {
                byte b = (byte)((exp & 0x07) << 2);
                if (dap)
                    b |= 0x02;
                cmd.SetCDB8(1, b);
                cmd.SetCDB32(2, start);
                cmd.SetCDB24(6, length);
                cmd.SetCDB8(9, 0x10);           // User data only

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }

            return CommandStatus.Success;
        }