예제 #1
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;
        }
예제 #2
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;
        }
예제 #3
0
 private CommandStatus SendCommand(Command cmd)
 {
     return (m_ossize == 32) ? SendCommand32(cmd) : SendCommand64(cmd);
 }
예제 #4
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;
        }
예제 #5
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;
        }
예제 #6
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;
        }
예제 #7
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; 
        }
예제 #8
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;
        }
예제 #9
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;
		}
예제 #10
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;
        }
예제 #11
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;
        }
예제 #12
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;
        }
예제 #13
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;
        }
예제 #14
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;
        }
예제 #15
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;
		}
예제 #16
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;
        }
예제 #17
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public CommandStatus SetReadAhead(uint trigger, uint lba)
        {
            if (m_logger != null)
            {
                string args = trigger.ToString() + ", " + lba.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.SetReadAhead(" + args + ")"));
            }
            using (Command cmd = new Command(ScsiCommandCode.SetReadAhead, 12, 0, Command.CmdDirection.None, 2))
            {
                cmd.SetCDB32(2, trigger);
                cmd.SetCDB32(6, lba);

                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }
            return CommandStatus.Success; 
        }
예제 #18
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;
        }
예제 #19
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;
        }
예제 #20
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus ReserveTrack(uint size)
        {
            if (m_logger != null)
            {
                string args = size.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.ReserveTrack(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.ReserveTrack, 10, 0, Command.CmdDirection.None, 5 * 60))
            {
                cmd.SetCDB32(5, size);
                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }

            return CommandStatus.Success;
        }
예제 #21
0
 /// <summary>
 /// 
 /// </summary>
 /// <returns></returns>
 public CommandStatus StopPlayScan()
 {
     using (Command cmd = new Command(ScsiCommandCode.StopPlayScan, 10, 0, Command.CmdDirection.None, 30))
     {
         if (m_logger != null)
         {
             string args = "";
             m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.StopPlayScan(" + args + ")"));
         }
         CommandStatus st = SendCommand(cmd);
         if (st != CommandStatus.Success)
             return st;
     }
     return CommandStatus.Success; 
 }
예제 #22
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;
        }
예제 #23
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus TestUnitReady(out bool ready)
        {
            if (m_logger != null)
            {
                string args = "out ready";
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 9, "Bwg.Scsi.Device.TestUnitReady(" + args + ")"));
            }

            ready = true;
            using (Command cmd = new Command(ScsiCommandCode.TestUnitReady, 6, 0, Command.CmdDirection.None, 60))
            {
                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                {
                    ready = false ;

                    if (st == CommandStatus.DeviceFailed && GetSenseKey() == SenseKeyType.NotReady)
                        st = CommandStatus.Success;

                    return st;
                }
            }
                
            return CommandStatus.Success;
        }
예제 #24
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public CommandStatus Seek(uint lba)
        {
            if (m_logger != null)
            {
                string args = lba.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Seek(" + args + ")"));
            }
            using (Command cmd = new Command(ScsiCommandCode.Seek, 10, 0, Command.CmdDirection.None, 10))
            {
                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }

            return CommandStatus.Success;
        }
예제 #25
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;
        }
예제 #26
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;
        }
예제 #27
0
        /// <summary>
        /// Send the sense information to the logger
        /// </summary>
        private void LogSenseInformation(Command cmd)
        {
            if (m_ignore_long_write_error && IsLongWriteInProgress(GetSenseAsc(), GetSenseAscq()))
                return;

            if (m_logger != null && LogSenseState)
            {
                int len = GetSenseLength();
                int offset = 0;
                int line = 0;
                UserMessage m;
                string str;
                Logger logger = GetLogger();

                str = "SCSI Operation Failed: " ;
                str += LookupSenseError(GetSenseAsc(), GetSenseAscq()) ;
                m = new UserMessage(UserMessage.Category.Error, 0, str);
                m_logger.LogMessage(m);

                str = "    SenseKey = " + GetSenseKey().ToString("X");
                m = new UserMessage(UserMessage.Category.Error, 0, str);
                m_logger.LogMessage(m);

                str = "    SenseAsc = " + GetSenseAsc().ToString("X");
                m = new UserMessage(UserMessage.Category.Error, 0, str);
                m_logger.LogMessage(m);

                str = "    SenseAscq = " + GetSenseAscq().ToString("X");
                m = new UserMessage(UserMessage.Category.Error, 0, str);
                m_logger.LogMessage(m);

                while (offset < len)
                {
                    line = 0;
                    str = "    SenseData:";
                    while (offset < len && line < 8)
                    {
                        str += " " + GetSenseByte(offset++).ToString("X2");
                        line++;
                    }

                    m = new UserMessage(UserMessage.Category.Error, 0, str);
                    logger.LogMessage(m);
                }

                if (GetSenseAsc() == 0x24 && GetSenseAscq() == 0x00)
                {
                    // This is invalid field in CDB, so dump the CDB to the log
                    str = "INVALID CDB:";
                    for (byte i = 0; i < cmd.GetCDBLength(); i++)
                    {
                        byte b = cmd.GetCDB(i);
                        str += " " + b.ToString("X");
                    }
                    m = new UserMessage(UserMessage.Category.Error, 0, str);
                    m_logger.LogMessage(m);
                }
            }
        }
예제 #28
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;
        }
예제 #29
0
        private CommandStatus SendCommand32(Command cmd)
        {
            SCSI_PASS_THROUGH_DIRECT32 f = new SCSI_PASS_THROUGH_DIRECT32();
            f.Length = m_scsi_request_size_32;
            f.CdbLength = (byte)cmd.GetCDBLength();
            f.DataIn = 0;
            if (cmd.Direction == Command.CmdDirection.In)
                f.DataIn = 1;
            f.DataTransferLength = (uint)cmd.BufferSize;
            f.TimeOutValue = (uint)cmd.TimeOut;
            for (byte i = 0; i < f.CdbLength; i++)
                f.CdbData[i] = cmd.GetCDB(i);
            f.SenseInfoOffset = 48;
            f.SenseInfoLength = 24;

            uint total = (uint)Marshal.SizeOf(f);

            uint ret = 0;

            // Set the buffer field
            f.DataBuffer = cmd.GetBuffer();

            // Send through ioctl field
            IntPtr pt = new IntPtr(&f);
            if (!Control(IOCTL_SCSI_PASS_THROUGH_DIRECT, pt, total, pt, total, ref ret, IntPtr.Zero))
            {
                string str ;
                str = "IOCTL_SCSI_PASS_THROUGH_DIRECT failed - " + Win32ErrorToString(LastError);
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Error, 0, str));
                return CommandStatus.IoctlFailed;
            }

            m_scsi_status = f.ScsiStatus;
            if (f.SenseInfoLength != 0)
            {
                m_sense_info = new byte[f.SenseInfoLength];
                for (int i = 0; i < f.SenseInfoLength; i++)
                    m_sense_info[i] = f.SenseInfo[i];
            }
            else
                m_sense_info = null;

            if (m_scsi_status != 0)
            {
                LogSenseInformation(cmd);
                return CommandStatus.DeviceFailed;
            }

            return CommandStatus.Success;
        }
예제 #30
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;
        }