Esempio n. 1
0
		public unsafe bool TestReadCommand()
		{
			if (readCommandFound)
				return true;

			//ReadCDCommand[] readmode = { ReadCDCommand.ReadCdBEh, ReadCDCommand.ReadCdD8h };
            ReadCDCommand[] readmode = { ReadCDCommand.ReadCdBEh, ReadCDCommand.ReadCdD8h };
			Device.C2ErrorMode[] c2mode = { Device.C2ErrorMode.Mode294, Device.C2ErrorMode.Mode296, Device.C2ErrorMode.None };
			Device.MainChannelSelection[] mainmode = { Device.MainChannelSelection.UserData, Device.MainChannelSelection.F8h };
			bool found = false;
			_autodetectResult = "";
			_currentStart = 0;
			m_max_sectors = Math.Min(NSECTORS, m_device.MaximumTransferLength / CB_AUDIO - 1);
			int sector = 3;
			int pass = 0;

			for (int c = 0; c <= 2 && !found; c++)
				for (int r = 0; r <= 1 && !found; r++)
					for (int m = 0; m <= 1 && !found; m++)
					{
						_readCDCommand = readmode[r];
						_c2ErrorMode = c2mode[c];
						_mainChannelMode = mainmode[m];
						if (_forceReadCommand != ReadCDCommand.Unknown && _readCDCommand != _forceReadCommand)
							continue;
                        if (_readCDCommand == ReadCDCommand.ReadCdD8h && (_c2ErrorMode != Device.C2ErrorMode.None || _mainChannelMode != Device.MainChannelSelection.UserData))
							continue;
						Array.Clear(_readBuffer, 0, _readBuffer.Length); // fill with something nasty instead?
						DateTime tm = DateTime.Now;
						if (ReadProgress != null)
						{
							progressArgs.Action = Resource1.StatusDetectingDriveFeatures;
							progressArgs.Pass = -1;
							progressArgs.Position = pass++;
							progressArgs.PassStart = 0;
							progressArgs.PassEnd = 2 * 3 * 2 - 1;
							progressArgs.ErrorsCount = 0;
							progressArgs.PassTime = tm;
							ReadProgress(this, progressArgs);
						}
						System.Diagnostics.Trace.WriteLine("Trying " + CurrentReadCommand);
						Device.CommandStatus st = FetchSectors(sector, m_max_sectors, false);
						TimeSpan delay = DateTime.Now - tm;
						_autodetectResult += string.Format("{0}: {1} ({2}ms)\n", CurrentReadCommand, (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString()), delay.TotalMilliseconds);
						found = st == Device.CommandStatus.Success;
						
						//sector += m_max_sectors;
					}
			//if (found)
			//    for (int n = 1; n <= m_max_sectors; n++)
			//    {
			//        Device.CommandStatus st = FetchSectors(0, n, false, false);
			//        if (st != Device.CommandStatus.Success)
			//        {
			//            _autodetectResult += string.Format("Maximum sectors: {0}, else {1}; max length {2}\n", n - 1, (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString()), m_device.MaximumTransferLength);
			//            m_max_sectors = n - 1;
			//            break;
			//        }
			//    }
            if (found)
            {
                TestGaps();
                _autodetectResult += "Chosen " + CurrentReadCommand + "\n";
            }
            else
            {
                _gapDetection = GapDetectionMethod.None;
                _readCDCommand = ReadCDCommand.Unknown;
            }

			_currentStart = -1;
			_currentEnd = -1;
			readCommandFound = found;
			return found;
		}
Esempio n. 2
0
		private unsafe void TestGaps()
		{
			_gapDetection = GapDetectionMethod.None;

			//st = m_device.Seek((uint)(sector + i * 33) + _toc[_toc.FirstAudio][0].Start);
			//if (st != Device.CommandStatus.Success)
			//    break;
			//bool ready;
			//st = m_device.TestUnitReady(out ready);
			//if (st != Device.CommandStatus.Success)
			//    break;
			//if (!ready)
			//{
			//    st = Device.CommandStatus.NotSupported;
			//    break;
			//}

			// try ReadCD:
			Device.CommandStatus st;
			int sector = 3;

			if (_readCDCommand == ReadCDCommand.ReadCdBEh)
			{
                // PLEXTOR PX-W1210A always returns data, even if asked only for subchannel.
                // So we fill the buffer with magic data, give extra space for command so it won't hang the drive,
                // request subchannel data and check if magic data was overwritten.
                bool overwritten = false;
                for (int i = 0; i < 16; i++)
                {
                    _subchannelBuffer[m_max_sectors * (588 * 4 + 16) - 16 + i] = (byte)(13 + i);
                }
                fixed (byte* data = _subchannelBuffer)
                {
                    st = m_device.ReadCDAndSubChannel(Device.MainChannelSelection.None, Device.SubChannelMode.QOnly, Device.C2ErrorMode.None, 1, false, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)m_max_sectors, (IntPtr)((void*)data), _timeout);
                }
                for (int i = 0; i < 16; i++)
                {
                    if (_subchannelBuffer[m_max_sectors * (588 * 4 + 16) - 16 + i] != (byte)(13 + i))
                        overwritten = true;
                }
                if (overwritten)
                    st = Device.CommandStatus.NotSupported;
                //else
                //    st = m_device.ReadSubChannel(2, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)m_max_sectors, ref _subchannelBuffer, _timeout);
				if (st == Device.CommandStatus.Success)
				{
					int[] goodsecs = new int[2];
					for (int bcd = 1; bcd >= 0; bcd--)
					{
						for (int i = 0; i < m_max_sectors; i++)
						{
							int adr = _subchannelBuffer[i * 16 + 0] & 7;
							if (bcd == 0 && adr == 1)
							{
								_subchannelBuffer[i * 16 + 3] = toBCD(_subchannelBuffer[i * 16 + 3]);
								_subchannelBuffer[i * 16 + 4] = toBCD(_subchannelBuffer[i * 16 + 4]);
								_subchannelBuffer[i * 16 + 5] = toBCD(_subchannelBuffer[i * 16 + 5]);
								_subchannelBuffer[i * 16 + 7] = toBCD(_subchannelBuffer[i * 16 + 7]);
								_subchannelBuffer[i * 16 + 8] = toBCD(_subchannelBuffer[i * 16 + 8]);
								_subchannelBuffer[i * 16 + 9] = toBCD(_subchannelBuffer[i * 16 + 9]);
							}

							ushort crc = _crc.ComputeChecksum(_subchannelBuffer, i * 16, 10);
							crc ^= 0xffff;
							ushort scrc = (ushort)((_subchannelBuffer[i * 16 + 10] << 8) | _subchannelBuffer[i * 16 + 11]);
							if (scrc != 0 && scrc != crc)
								continue;
							if (adr != 1)
								continue;

							int sTrack = fromBCD(_subchannelBuffer[i * 16 + 1]);
							int sIndex = fromBCD(_subchannelBuffer[i * 16 + 2]);

							if (sTrack == 0 || sTrack == 110)
								continue;

							int mm = fromBCD(_subchannelBuffer[i * 16 + 7]);
							int ss = fromBCD(_subchannelBuffer[i * 16 + 8]);
							int ff = fromBCD(_subchannelBuffer[i * 16 + 9]);
							int sPos = ff + 75 * (ss + 60 * mm) - 150;

							if (sPos < sector + i - 8 || sPos > sector + i + 8)
								continue;

							goodsecs[bcd]++;
						}
					}

					if (goodsecs[0] > 0 || goodsecs[1] > 0)
					{
						_qChannelInBCD = goodsecs[1] >= goodsecs[0];
						_gapDetection = GapDetectionMethod.ReadCD;
					}
				}
			}

			if (_gapDetection == GapDetectionMethod.None)
			{
				fixed (byte* data = _subchannelBuffer)
				{
					// seek to given sector
					if (_readCDCommand == ReadCDCommand.ReadCdBEh)
						st = m_device.ReadCDAndSubChannel(_mainChannelMode, Device.SubChannelMode.None, _c2ErrorMode, 1, false, (uint)sector + _toc[_toc.FirstAudio][0].Start, 1, (IntPtr)((void*)data), _timeout);
					else
						st = m_device.ReadCDDA(Device.SubChannelMode.None, (uint)sector + _toc[_toc.FirstAudio][0].Start, 1, (IntPtr)((void*)data), _timeout);
				}
				if (st == Device.CommandStatus.Success)
				{
					st = m_device.ReadSubChannel42(1, 0, ref _subchannelBuffer, 0, _timeout);
					if (st == Device.CommandStatus.Success)
					{
						if (_subchannelBuffer[0] == 0 && _subchannelBuffer[2] == 0 && _subchannelBuffer[3] == 12 && _subchannelBuffer[4] == 1)
						{
							int ctl = _subchannelBuffer[5] & 0xf;
							int adr = (_subchannelBuffer[5] >> 4) & 0xf;
							if (adr == 1)
							{
								_gapDetection = GapDetectionMethod.ReadSubchannel;
							}
						}
					}
				}
			}
		}