Exemple #1
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="polled"></param>
        /// <param name="request"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public CommandStatus GetEventStatusNotification(bool polled, NotificationClass request, out EventStatusNotification result)
        {
            if (m_logger != null)
            {
                string args = polled.ToString() + ", " + request.ToString() + ", out result";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.GetEventStatusNotification(" + args + ")"));
            }

            ushort len = 0;
            result = null;

            using (Command cmd = new Command(ScsiCommandCode.GetEventStatusNotification, 10, 4, Command.CmdDirection.In, 10))
            {
                if (polled)
                    cmd.SetCDB8(1, 1);
                cmd.SetCDB8(4, (byte)request);
                cmd.SetCDB16(7, 4);

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

                byte n = cmd.GetBuffer8(2);
                if ((n & 0x80) != 0)
                {
                    // There are no events, just capture the header
                    result = new EventStatusNotification(cmd.GetBuffer(), cmd.BufferSize);
                    return CommandStatus.Success;
                }

                //
                // There are event notifications to be grabbed, allocate space for these
                //
                len = cmd.GetBuffer16(0);
                len += 4;               // For the length field
            }

            using (Command cmd = new Command(ScsiCommandCode.GetEventStatusNotification, 10, len, Command.CmdDirection.In, 10))
            {
                if (polled)
                    cmd.SetCDB8(1, 1);
                cmd.SetCDB8(4, (byte)request);
                cmd.SetCDB16(7, len);

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

                result = new EventStatusNotification(cmd.GetBuffer(), cmd.BufferSize);
            }

            return CommandStatus.Success;
        }
Exemple #2
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 #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 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 #5
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 #6
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus ReadFormatCapacities(bool all, out IList<CapacityDescriptor> caplist)
        {
            caplist = new List<CapacityDescriptor>();

            if (m_logger != null)
            {
                string args = all.ToString() + ", out caplist";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadFormatCapacities(" + args + ")"));
            }
            int len;

            using (Command cmd = new Command(ScsiCommandCode.ReadFormatCapacities, 10, 8, Command.CmdDirection.In, 60))
            {
                cmd.SetCDB16(7, 8);

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

                len = cmd.GetBuffer8(3) + 4;
            }
            using (Command cmd = new Command(ScsiCommandCode.ReadFormatCapacities, 10, len, Command.CmdDirection.In, 60))
            {
                cmd.SetCDB16(7, (ushort)len);

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

                int offset = 4;
                len = cmd.GetBuffer8(3) + 4;
                while (offset < len)
                {
                    caplist.Add(new CapacityDescriptor(cmd.GetBuffer(), offset, cmd.BufferSize));
                    offset += 8;
                }
            }
            return CommandStatus.Success;
        }
Exemple #7
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 #8
0
        /// <summary>
        /// This command requests that the SCSI device begins an audio playback operation.
        /// </summary>
        /// <param name="lba">The starting logical block address for the playback</param>
        /// <param name="length">The length of the disk to play</param>
        /// <returns></returns>
        public CommandStatus PlayAudio(uint lba, uint length)
        {
            if (m_logger != null)
            {
                string args = lba.ToString() + ", " + length.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.PlayAudio(" + args + ")"));
            }
            if (length > 65535)
            {
                using (Command cmd = new Command(ScsiCommandCode.PlayAudio12, 12, 0, Command.CmdDirection.None, 5))
                {
                    cmd.SetCDB32(2, lba);
                    cmd.SetCDB32(6, length);
                    CommandStatus st = SendCommand(cmd);
                    if (st != CommandStatus.Success)
                        return st;
                }
            }
            else
            {
                using (Command cmd = new Command(ScsiCommandCode.PlayAudio10, 10, 0, Command.CmdDirection.None, 5))
                {
                    cmd.SetCDB32(2, lba);
                    cmd.SetCDB16(7, (ushort)length);
                    CommandStatus st = SendCommand(cmd);
                    if (st != CommandStatus.Success)
                        return st;
                }
            }

            return CommandStatus.Success;
        }
Exemple #9
0
        /// <summary>
        /// This method requests that the SCSI device transfer data to the given 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="length">The length of the data to read</param>
        /// <param name="data">The data buffer to received the data</param>
        /// <returns></returns>
        public CommandStatus Read(bool force, bool streaming, uint lba, uint 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.Read(" + args + ")"));
            }

            if (streaming || length > 65535)
            {
                using (Command cmd = new Command(ScsiCommandCode.Read12, 12, (ushort)data.GetLength(0), Command.CmdDirection.In, 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;

                    Marshal.Copy(cmd.GetBuffer(), data, 0, data.GetLength(0));
                }
            }
            else
            {
                using (Command cmd = new Command(ScsiCommandCode.Read, 10, (ushort)data.GetLength(0), Command.CmdDirection.In, 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;

                    Marshal.Copy(cmd.GetBuffer(), data, 0, data.GetLength(0));
                }
            }

            return CommandStatus.Success;
        }
Exemple #10
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="save"></param>
        /// <param name="table"></param>
        /// <returns></returns>
        public CommandStatus ModeSelect(bool save, ModeTable table)
        {
            if (m_logger != null)
            {
                string t = "";
                for (int i = 0; i < table.Pages.Count; i++)
                {
                    if (t.Length > 0)
                        t += ", ";
                    t = t + table.Pages[i].PageCode;
                }
                string args = save.ToString() + ", ModeTable(" + t + ")";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ModeSelect(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.ModeSelect, 10, table.Size, Command.CmdDirection.Out, 60 * 5))
            {
                byte b = 0x10;
                if (save)
                    b |= 0x01;

                cmd.SetCDB8(1, b);
                cmd.SetCDB16(7, table.Size);
                table.Format(cmd.GetBuffer());

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

            return CommandStatus.Success;
        }
Exemple #11
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pc"></param>
        /// <param name="page"></param>
        /// <param name="table"></param>
        /// <returns></returns>
        public CommandStatus ModeSense(PageControl pc, byte page, out ModeTable table)
        {
            if (m_logger != null)
            {
                string args = pc.ToString() + ", " + page.ToString() + ", out result";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ModeSense(" + args + ")"));
            }

            ushort len = 0;

            table = null;

            byte b = 0;
            b |= (byte)((byte)(pc) << 7);
            b |= (byte)(page & 0x3f);

            using (Command cmd = new Command(ScsiCommandCode.ModeSense, 10, 8, Command.CmdDirection.In, 60 * 5))
            {
                cmd.SetCDB8(1, 8);              // Disable block descriptors
                cmd.SetCDB8(2, b);
                cmd.SetCDB16(7, 8);

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

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

            using (Command cmd = new Command(ScsiCommandCode.ModeSense, 10, len, Command.CmdDirection.In, 60 * 5))
            {
                cmd.SetCDB8(1, 8);              // Disable block descriptors
                cmd.SetCDB8(2, b);
                cmd.SetCDB16(7, len);

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

                table = new ModeTable(cmd.GetBuffer(), cmd.BufferSize);
            }

            return CommandStatus.Success;
        }
Exemple #12
0
        /// <summary>
        /// Perform a SCSI inquiry on the device to get information about the device
        /// </summary>
        /// <param name="result">The return value describing the inquiry results</param>
        /// <returns></returns>
        public CommandStatus Inquiry(out InquiryResult result)
        {
            if (m_logger != null)
            {
                string args = "out result";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Inquiry(" + args + ")"));
            }

            result = null;

            byte len = 0;
            using (Command cmd = new Command(ScsiCommandCode.Inquiry, 6, 36, Command.CmdDirection.In, 10))
            {
                cmd.SetCDB16(3, 36);
                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                len = cmd.GetBuffer8(4);
                len += 5;

                if (len <= cmd.BufferSize)
                {
                    result = new InquiryResult(cmd.GetBuffer(), len);

                    if (m_logger != null)
                        m_logger.DumpBuffer(9, "Raw Inquiry Result", cmd.GetBuffer(), len);
                    return CommandStatus.Success;
                }

                //
                // As an oddity, the Sony DW-G120A only supports requests that are an even number
                // of bytes.
                //
                if ((len % 2) == 1)
                    len = (byte)((len / 2 * 2) + (((len % 2) == 1) ? 2 : 0));
            }

            using (Command cmd = new Command(ScsiCommandCode.Inquiry, 6, len, Command.CmdDirection.In, 100))
            {
                cmd.SetCDB8(4, len);
                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                result = new InquiryResult(cmd.GetBuffer(), cmd.BufferSize);

                if (m_logger != null)
                    m_logger.DumpBuffer(9, "Raw Inquiry Result", cmd.GetBuffer(), cmd.BufferSize);
            }

            return CommandStatus.Success;
        }
Exemple #13
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus GetPerformance(uint lba, PerformanceList.DataType rwtype, PerformanceList.ExceptType extype, out PerformanceList list)
        {
            list = null;

            if (m_logger != null)
            {
                string args = rwtype.ToString() + ", " + extype.ToString() + ", list";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.GetPerformance(" + args + ")"));
            }

            uint len = 0;
            using (Command cmd = new Command(ScsiCommandCode.GetPerformance, 12, 24, Command.CmdDirection.In, 10))
            {
                byte b = 0x10;
                if (rwtype == PerformanceList.DataType.WriteData)
                    b |= 0x04 ;

                b |= (byte)extype;

                cmd.SetCDB8(1, b);
                cmd.SetCDB16(8, 1);

                if (extype == PerformanceList.ExceptType.Entire)
                    cmd.SetCDB32(2, lba);

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

                len = cmd.GetBuffer32(0);
                len += 4;       // For the length field
            }

            using (Command cmd = new Command(ScsiCommandCode.GetPerformance, 12, (ushort)len, Command.CmdDirection.In, 10))
            {
                byte b = 0x10;
                if (rwtype == PerformanceList.DataType.WriteData)
                    b |= 0x04;

                b |= (byte)extype;

                cmd.SetCDB8(1, b);

                if (extype == PerformanceList.ExceptType.Entire)
                    cmd.SetCDB32(2, lba);

                cmd.SetCDB16(8, (ushort)((len - 8) / 16));

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

                list = new PerformanceList(cmd.GetBuffer(), cmd.BufferSize);
            }

            return CommandStatus.Success;
        }
Exemple #14
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus GetSpeed(out SpeedDescriptorList list)
        {
            ushort initial_size = 8 + 4 * 16;
            list = null;

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

            uint len = 0;
            using (Command cmd = new Command(ScsiCommandCode.GetPerformance, 12, initial_size, Command.CmdDirection.In, 10 * 60))
            {
                cmd.SetCDB16(8, (ushort)((initial_size - 8) / 16));
                cmd.SetCDB8(10, 3);

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

                len = cmd.GetBuffer32(0);
                len += 4;                       // For the length field
            }

            using (Command cmd = new Command(ScsiCommandCode.GetPerformance, 12, (ushort)len, Command.CmdDirection.In, 10 * 60))
            {
                cmd.SetCDB16(8, (ushort)((len - 8) / 16));
                cmd.SetCDB8(10, 3);

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


                list = new SpeedDescriptorList(cmd.GetBuffer(), cmd.BufferSize);
            }

            return CommandStatus.Success;
        }
Exemple #15
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 #16
0
        /// <summary>
        /// This method returns the buffer capacity for the pass through SCSI device. 
        /// </summary>
        /// <param name="blocks">if true, the length and available is given in blocks, otherwise bytes</param>
        /// <param name="length">return vaue, the length of the buffer</param>
        /// <param name="avail">return value, the available space in the buffer</param>
        /// <returns>status of the command</returns>
        public CommandStatus ReadBufferCapacity(bool blocks, out int length, out int avail)
        {
            if (m_logger != null)
            {
                string args = blocks.ToString() + ", out length, out available";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 9, "Bwg.Scsi.Device.ReadBufferCapacity(" + args + ")"));
            }
            length = 0;
            avail = 0;

            using (Command cmd = new Command(ScsiCommandCode.ReadBufferCapacity, 10, 12, Command.CmdDirection.In, 60 * 5))
            {
                cmd.SetCDB16(7, 12);
                if (blocks)
                    cmd.SetCDB8(1, 1);
                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;

                length = (int)cmd.GetBuffer32(4);
                avail = (int)cmd.GetBuffer32(8);
            }

            return CommandStatus.Success;
        }
Exemple #17
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 #18
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 #19
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 #20
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 #21
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 #22
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus ReadDiskInformation(out DiskInformation result)
        {
            if (m_logger != null)
            {
                string args = "out result";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReadDiskInformation(" + args + ")"));
            }

            ushort len = 0;
            result = null;

            using (Command cmd = new Command(ScsiCommandCode.ReadDiskInformation, 10, 34, Command.CmdDirection.In, 60))
            {
                cmd.SetCDB16(7, 34);

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


                len = cmd.GetBuffer16(0);
                if (len <= 34)
                {
                    result = new DiskInformation(cmd.GetBuffer(), cmd.BufferSize);
                    return CommandStatus.Success;
                }
                len += 2;
            }

            using (Command cmd = new Command(ScsiCommandCode.ReadDiskInformation, 10, len, Command.CmdDirection.In, 60))
            {
                cmd.SetCDB16(7, len);

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

                result = new DiskInformation(cmd.GetBuffer(), cmd.BufferSize);
            }

            return CommandStatus.Success;
        }
Exemple #23
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus RepairTrack(ushort track)
        {
            if (m_logger != null)
            {
                string args = track.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.RepairTrack(" + args + ")"));
            }
            using (Command cmd = new Command(ScsiCommandCode.RepairTrack, 10, 0, Command.CmdDirection.None, 5 * 60))
            {
                cmd.SetCDB16(4, track);
                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }

            return CommandStatus.Success;
        }
Exemple #24
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 #25
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 #26
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 #27
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus Verify(int start, int size)
        {
            if (m_logger != null)
            {
                string args = start.ToString() + ", " + size.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Verify(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.Verify, 10, 2048, Command.CmdDirection.None, 60 * 60))
            {
                cmd.SetCDB32(2, (uint)start);
                cmd.SetCDB16(7, (ushort)size);

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

            return CommandStatus.Success;
        }
Exemple #28
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 #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="type"></param>
        /// <param name="start"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public CommandStatus GetConfiguration(GetConfigType type, ushort start, out FeatureList result)
        {
            if (m_logger != null)
            {
                string args = type.ToString() + ", " + start.ToString() + ", out result";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.GetConfiguration(" + args + ")"));
            }

            uint len = 0;
            result = null;

            if (type == GetConfigType.Reserved)
                throw new Exception("cannot use reserved value") ;

            using (Command cmd = new Command(ScsiCommandCode.GetConfiguration, 10, 8, Command.CmdDirection.In, 10))
            {
                cmd.SetCDB8(1, (byte)type);
                cmd.SetCDB16(2, start);
                cmd.SetCDB16(7, 8);

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

                len = cmd.GetBuffer32(0);
                len += 4;       // Add four for the length field
            }

            using (Command cmd = new Command(ScsiCommandCode.GetConfiguration, 10, (ushort)len, Command.CmdDirection.In, 10))
            {
                cmd.SetCDB8(1, (byte)type);
                cmd.SetCDB16(2, start);
                cmd.SetCDB16(7, (ushort)len);

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

                result = new FeatureList(cmd.GetBuffer(), cmd.BufferSize);
            }

            return CommandStatus.Success;
        }