Exemple #1
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 #2
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 #3
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 #4
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;
        }
Exemple #5
0
        /// <summary>
        /// This function instructs the device to erase blocks on the disk.
        /// </summary>
        /// <param name="immd">If true, return immediately and perform the function in the background</param>
        /// <param name="lba">The starting block address for the erase operation</param>
        /// <param name="count">The number of blocks to erase.  If this count is zero, the ERA bit is set in the SCSI erase request</param>
        /// <returns></returns>
        public CommandStatus Erase(bool immd, uint lba, ushort count)
        {
            if (m_logger != null)
            {
                string args = immd.ToString() + ", " + lba.ToString() + ", " + count.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Erase(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.Erase, 10, 0, Command.CmdDirection.None, 60 * 30))
            {
                byte b = 0;

                if (immd)
                    b |= 0x02;
                if (count == 0)
                    b |= 0x04;
                cmd.SetCDB8(1, b);
                cmd.SetCDB32(2, lba);
                cmd.SetCDB16(7, count);

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

            return CommandStatus.Success;
        }
Exemple #6
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 #7
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 #8
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 #9
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;
        }
Exemple #10
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 #11
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 #12
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 #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 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; 
        }
Exemple #15
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 #16
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 #17
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 #18
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 #19
0
        /// <summary>
        /// This function blanks a portion of the CD or DVD that is in the drive.
        /// </summary>
        /// <param name="immd"></param>If true, this function returns immediately and the blanking
        /// happens in the backgroun.  If false, this funtion does not return until the blanking operation
        /// is complete
        /// <param name="t"></param>The type of blanking operation
        /// <param name="addr"></param>The address for the blanking operation if an address is required
        /// <returns>
        /// Success - the command complete sucessfully
        /// IoctlFailed - the windows DeviceIoControl failed, LastError give the Win32 error code
        /// DeviceFailed - the device failed the command, the sense information has more data
        /// </returns>
        public CommandStatus Blank(bool immd, BlankType t, int addr)
        {
            if (m_logger != null)
            {
                string args = immd.ToString() + ", " + t.ToString() + ", " + addr.ToString();
                m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 8, "Bwg.Scsi.Device.Blank(" + args + ")"));
            }

            using (Command cmd = new Command(ScsiCommandCode.Blank, 12, 0, Command.CmdDirection.None, 60*30))
            {
                byte b = (byte)t;
                if (immd)
                    b |= (1 << 4);
                cmd.SetCDB8(1, b);

                cmd.SetCDB32(2, addr);
                CommandStatus st = SendCommand(cmd);
                if (st != CommandStatus.Success)
                    return st;
            }

            return CommandStatus.Success;
        }