Esempio n. 1
0
        /// <summary>Sends the MMC READ CD command</summary>
        /// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
        /// <param name="buffer">Buffer where the MMC READ CD response will be stored</param>
        /// <param name="senseBuffer">Sense buffer.</param>
        /// <param name="timeout">Timeout in seconds.</param>
        /// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
        /// <param name="lba">Start block address.</param>
        /// <param name="transferLength">How many blocks to read.</param>
        /// <param name="blockSize">Block size.</param>
        /// <param name="expectedSectorType">Expected sector type.</param>
        /// <param name="dap">If set to <c>true</c> CD-DA should be modified by mute and interpolation</param>
        /// <param name="relAddr">If set to <c>true</c> address is relative to current position.</param>
        /// <param name="sync">If set to <c>true</c> we request the sync bytes for data sectors.</param>
        /// <param name="headerCodes">Header codes.</param>
        /// <param name="userData">If set to <c>true</c> we request the user data.</param>
        /// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
        /// <param name="c2Error">C2 error options.</param>
        /// <param name="subchannel">Subchannel selection.</param>
        public bool ReadCd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint transferLength,
                           MmcSectorTypes expectedSectorType, bool dap, bool relAddr, bool sync,
                           MmcHeaderCodes headerCodes, bool userData, bool edcEcc, MmcErrorField c2Error,
                           MmcSubchannel subchannel, uint timeout, out double duration)
        {
            senseBuffer = new byte[32];
            byte[] cdb = new byte[12];

            cdb[0] = (byte)ScsiCommands.ReadCd;
            cdb[1] = (byte)((byte)expectedSectorType << 2);

            if (dap)
            {
                cdb[1] += 0x02;
            }

            if (relAddr)
            {
                cdb[1] += 0x01;
            }

            cdb[2]  = (byte)((lba & 0xFF000000) >> 24);
            cdb[3]  = (byte)((lba & 0xFF0000) >> 16);
            cdb[4]  = (byte)((lba & 0xFF00) >> 8);
            cdb[5]  = (byte)(lba & 0xFF);
            cdb[6]  = (byte)((transferLength & 0xFF0000) >> 16);
            cdb[7]  = (byte)((transferLength & 0xFF00) >> 8);
            cdb[8]  = (byte)(transferLength & 0xFF);
            cdb[9]  = (byte)((byte)c2Error << 1);
            cdb[9] += (byte)((byte)headerCodes << 5);

            if (sync)
            {
                cdb[9] += 0x80;
            }

            if (userData)
            {
                cdb[9] += 0x10;
            }

            if (edcEcc)
            {
                cdb[9] += 0x08;
            }

            cdb[10] = (byte)subchannel;

            buffer = new byte[blockSize * transferLength];

            LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
                                        out bool sense);

            Error = LastError != 0;

            DicConsole.DebugWriteLine("SCSI Device", "READ CD took {0} ms.", duration);

            return(sense);
        }
Esempio n. 2
0
        /// <summary>Sends the MMC READ CD MSF command</summary>
        /// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
        /// <param name="buffer">Buffer where the MMC READ CD MSF response will be stored</param>
        /// <param name="senseBuffer">Sense buffer.</param>
        /// <param name="timeout">Timeout in seconds.</param>
        /// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
        /// <param name="startMsf">Start MM:SS:FF of read encoded as 0x00MMSSFF.</param>
        /// <param name="endMsf">End MM:SS:FF of read encoded as 0x00MMSSFF.</param>
        /// <param name="blockSize">Block size.</param>
        /// <param name="expectedSectorType">Expected sector type.</param>
        /// <param name="dap">If set to <c>true</c> CD-DA should be modified by mute and interpolation</param>
        /// <param name="sync">If set to <c>true</c> we request the sync bytes for data sectors.</param>
        /// <param name="headerCodes">Header codes.</param>
        /// <param name="userData">If set to <c>true</c> we request the user data.</param>
        /// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
        /// <param name="c2Error">C2 error options.</param>
        /// <param name="subchannel">Subchannel selection.</param>
        public bool ReadCdMsf(out byte[] buffer, out byte[] senseBuffer, uint startMsf, uint endMsf, uint blockSize,
                              MmcSectorTypes expectedSectorType, bool dap, bool sync, MmcHeaderCodes headerCodes,
                              bool userData, bool edcEcc, MmcErrorField c2Error, MmcSubchannel subchannel, uint timeout,
                              out double duration)
        {
            senseBuffer = new byte[32];
            byte[] cdb = new byte[12];

            cdb[0] = (byte)ScsiCommands.ReadCdMsf;
            cdb[1] = (byte)((byte)expectedSectorType << 2);

            if (dap)
            {
                cdb[1] += 0x02;
            }

            cdb[3]  = (byte)((startMsf & 0xFF0000) >> 16);
            cdb[4]  = (byte)((startMsf & 0xFF00) >> 8);
            cdb[5]  = (byte)(startMsf & 0xFF);
            cdb[6]  = (byte)((endMsf & 0xFF0000) >> 16);
            cdb[7]  = (byte)((endMsf & 0xFF00) >> 8);
            cdb[8]  = (byte)(endMsf & 0xFF);
            cdb[9]  = (byte)((byte)c2Error << 1);
            cdb[9] += (byte)((byte)headerCodes << 5);

            if (sync)
            {
                cdb[9] += 0x80;
            }

            if (userData)
            {
                cdb[9] += 0x10;
            }

            if (edcEcc)
            {
                cdb[9] += 0x08;
            }

            cdb[10] = (byte)subchannel;

            uint transferLength = (uint)(((cdb[6] - cdb[3]) * 60 * 75) + ((cdb[7] - cdb[4]) * 75) + (cdb[8] - cdb[5]));

            buffer = new byte[blockSize * transferLength];

            LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
                                        out bool sense);

            Error = LastError != 0;

            AaruConsole.DebugWriteLine("SCSI Device",
                                       "READ CD MSF (Start MSF: {1}, End MSF: {2}, Block Size: {3}, Expected Sector Type: {4}, DAP: {5}, Sync: {6}, Headers: {7}, User Data: {8}, ECC/EDC: {9}, C2: {10}, Subchannel: {11}, Sense: {12}, LastError: {13}) took {0} ms.",
                                       duration, startMsf, endMsf, blockSize, expectedSectorType, dap, sync,
                                       headerCodes, userData, edcEcc, c2Error, subchannel, sense, LastError);

            return(sense);
        }
Esempio n. 3
0
        /// <summary>Sends the MMC READ CD command</summary>
        /// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
        /// <param name="buffer">Buffer where the MMC READ CD response will be stored</param>
        /// <param name="senseBuffer">Sense buffer.</param>
        /// <param name="timeout">Timeout in seconds.</param>
        /// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
        /// <param name="lba">Start block address.</param>
        /// <param name="transferLength">How many blocks to read.</param>
        /// <param name="blockSize">Block size.</param>
        /// <param name="expectedSectorType">Expected sector type.</param>
        /// <param name="dap">If set to <c>true</c> CD-DA should be modified by mute and interpolation</param>
        /// <param name="relAddr">If set to <c>true</c> address is relative to current position.</param>
        /// <param name="sync">If set to <c>true</c> we request the sync bytes for data sectors.</param>
        /// <param name="headerCodes">Header codes.</param>
        /// <param name="userData">If set to <c>true</c> we request the user data.</param>
        /// <param name="edcEcc">If set to <c>true</c> we request the EDC/ECC fields for data sectors.</param>
        /// <param name="c2Error">C2 error options.</param>
        /// <param name="subchannel">Subchannel selection.</param>
        public bool ReadCd(out byte[] buffer, out byte[] senseBuffer, uint lba, uint blockSize, uint transferLength,
                           MmcSectorTypes expectedSectorType, bool dap, bool relAddr, bool sync,
                           MmcHeaderCodes headerCodes, bool userData, bool edcEcc, MmcErrorField c2Error,
                           MmcSubchannel subchannel, uint timeout, out double duration)
        {
            senseBuffer = new byte[32];
            byte[] cdb = new byte[12];

            cdb[0] = (byte)ScsiCommands.ReadCd;
            cdb[1] = (byte)((byte)expectedSectorType << 2);

            if (dap)
            {
                cdb[1] += 0x02;
            }

            if (relAddr)
            {
                cdb[1] += 0x01;
            }

            cdb[2]  = (byte)((lba & 0xFF000000) >> 24);
            cdb[3]  = (byte)((lba & 0xFF0000) >> 16);
            cdb[4]  = (byte)((lba & 0xFF00) >> 8);
            cdb[5]  = (byte)(lba & 0xFF);
            cdb[6]  = (byte)((transferLength & 0xFF0000) >> 16);
            cdb[7]  = (byte)((transferLength & 0xFF00) >> 8);
            cdb[8]  = (byte)(transferLength & 0xFF);
            cdb[9]  = (byte)((byte)c2Error << 1);
            cdb[9] += (byte)((byte)headerCodes << 5);

            if (sync)
            {
                cdb[9] += 0x80;
            }

            if (userData)
            {
                cdb[9] += 0x10;
            }

            if (edcEcc)
            {
                cdb[9] += 0x08;
            }

            cdb[10] = (byte)subchannel;

            buffer = new byte[blockSize * transferLength];

            LastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration,
                                        out bool sense);

            Error = LastError != 0;

            AaruConsole.DebugWriteLine("SCSI Device",
                                       "READ CD (LBA: {1}, Block Size: {2}, Transfer Length: {3}, Expected Sector Type: {4}, DAP: {5}, Relative Address: {6}, Sync: {7}, Headers: {8}, User Data: {9}, ECC/EDC: {10}, C2: {11}, Subchannel: {12}, Sense: {13}, Last Error: {14}) took {0} ms.",
                                       duration, lba, blockSize, transferLength, expectedSectorType, dap, relAddr, sync,
                                       headerCodes, userData, edcEcc, c2Error, subchannel, sense, LastError);

            return(sense);
        }