//
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for DotNet
//
// Copyright (C) 2006 by Jack W. Griffin (butchg@comcast.net)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330,
// Boston, MA 02111-1307 USA
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace Bwg.Scsi
{
///
/// This class contains the results of the ReadDiskInformation SCSI command
///
public class DiskInformation : Result
{
#region Public types
///
/// Type defining the state of the last session on the disk
///
public enum SessionStateType
{
///
/// The session is empty
///
EmptySession = 0,
///
/// The session is incomplete
///
IncompleteSession = 1,
///
/// The session is damaged
///
DamagedSession = 2,
///
/// The session is complete
///
CompleteSession = 3
} ;
///
/// Type defining the status of the disk
///
public enum DiskStatusType
{
///
/// The disk is empty
///
EmptyDisk = 0,
///
/// The disk is incomplete
///
IncompleteDisk = 1,
///
/// The disk is finalized
///
FinalizedDisk = 2,
///
/// The disk is in an other state which is dependent on the media type
///
RandomlyRecordable = 3
} ;
///
/// The state of a background format
///
public enum BackgroundFormatStatusType
{
///
/// No background format was started, or it does not apply
///
NotStartedOrDoesNotApply = 0,
///
/// A background format was started, did not complete, and is not running
///
StartedButNotRunning = 1,
///
/// A background format is in progress and is not complete
///
InProgress = 2,
///
/// A background format was started and is complete
///
Complete = 3
} ;
#endregion
#region Public Data Members
private readonly bool m_erasable;
///
/// If true, the disk is erasable. If false the disk cannot be erased
///
public bool Erasable
{
get { return m_erasable; }
}
private readonly SessionStateType m_session_state;
///
/// The state of the last session on the disk
///
public SessionStateType SessionState
{
get { return m_session_state; }
}
private readonly DiskStatusType m_disk_status;
///
/// The status of the disk
///
public DiskStatusType DiskStatus
{
get { return m_disk_status; }
}
private readonly byte m_first_track;
///
/// Number of the first track on the disk
///
public byte FirstTrack
{
get { return m_first_track; }
}
private readonly ushort m_session_count;
///
/// Number of sessions on the disk
///
public ushort SessionCount
{
get { return m_session_count; }
}
private readonly ushort m_first_track_in_last_session;
///
/// The first track number in the last session
///
public ushort FirstTrackInLastSession
{
get { return m_first_track_in_last_session; }
}
private readonly ushort m_last_track_in_last_session;
///
/// The last track number in the last session
///
public ushort LastTrackInLastSession
{
get { return m_last_track_in_last_session; }
}
private readonly bool m_disk_id_valid;
///
/// If true, the disk ID was valid
///
public bool DiskIdValid
{
get { return m_disk_id_valid; }
}
private readonly uint m_disk_identification;
///
/// The four byte disk id
///
public uint DiskIdentification
{
get { return m_disk_identification; }
}
private readonly bool m_disk_bar_code_valid;
///
/// If true, the disk bar code was valid
///
public bool DiskBarCodeValid
{
get { return m_disk_bar_code_valid; }
}
private readonly byte[] m_disk_bar_code;
///
/// The eight byte disk bar code
///
public byte[] DiskBarCode
{
get { return m_disk_bar_code; }
}
private readonly bool m_unrestricted_disk_use;
///
/// If true, this disk is unrestriced it its use
///
public bool UnrestrictedDiskUse
{
get { return m_unrestricted_disk_use; }
}
private readonly bool m_disk_application_code_valid;
///
/// If true, the disk application code is valid
///
public bool DiskApplicationCodeValid
{
get { return m_disk_application_code_valid; }
}
private readonly byte m_disk_application_code;
///
/// The disk application code
///
public byte DiskApplicationCode
{
get { return m_disk_application_code; }
}
private readonly bool m_dirty_bit;
///
/// The Dbit (dirty bit) for MRW media
///
public bool DirtyBit
{
get { return m_dirty_bit; }
}
private readonly BackgroundFormatStatusType m_background_format_status;
///
/// The status of a background format
///
public BackgroundFormatStatusType BackgroundFormatStatus
{
get { return m_background_format_status; }
}
private readonly MinuteSecondFrame m_last_session_lead_in_start_address;
///
/// The last session leadin start address, media dependent, see SCSI-3 MMC spec
///
public MinuteSecondFrame LastSessionLeadInStartAddress
{
get { return m_last_session_lead_in_start_address; }
}
private readonly MinuteSecondFrame m_last_possible_leadout_start_address;
///
/// The last possible leadout start address, media dependent, see SCSI-3 MMC spec
///
public MinuteSecondFrame LastPossibleLeadoutStartAddress
{
get { return m_last_possible_leadout_start_address; }
}
///
/// The OPC table
///
public IList OpcTable;
#endregion
#region constructor
///
/// The constructor for the DiskInformation class. It parses the information from the
/// memory buffer that contains the raw SCSI result.
///
/// The buffer containing the raw SCSI result
/// The size of the raw SCSI result buffer
public DiskInformation(IntPtr buffer, int size) : base(buffer, size)
{
ushort len = Get16(0);
byte b = Get8(2);
if ((b & 0x10) != 0)
m_erasable = true;
else
m_erasable = false;
m_session_state = (SessionStateType)((b >> 2) & 0x03);
m_disk_status = (DiskStatusType)(b & 0x03);
m_first_track = Get8(3);
m_session_count = (ushort)(Get8(4) | (Get8(9) << 8));
m_first_track_in_last_session = (ushort)(Get8(5) | (Get8(10) << 8));
m_last_track_in_last_session = (ushort)(Get8(6) | (Get8(11) << 8));
b = Get8(7);
if ((b & 0x80) != 0)
{
m_disk_id_valid = true;
m_disk_identification = Get32(12);
}
else
m_disk_id_valid = false;
if ((b & 0x40) != 0)
{
m_disk_bar_code_valid = true;
m_disk_bar_code = new byte[8];
for (int i = 24; i <= 31; i++)
m_disk_bar_code[i - 24] = Get8(i);
}
else
{
m_disk_bar_code_valid = false;
m_disk_bar_code = null;
}
if ((b & 0x20) != 0)
m_unrestricted_disk_use = true;
else
m_unrestricted_disk_use = false;
if ((b & 0x10) != 0)
{
m_disk_application_code_valid = true;
m_disk_application_code = Get8(32);
}
else
m_disk_application_code_valid = false;
if ((b & 0x04) != 0)
m_dirty_bit = true;
else
m_dirty_bit = false;
m_background_format_status = (BackgroundFormatStatusType)(b & 0x03);
m_last_session_lead_in_start_address = new MinuteSecondFrame(Get8(16) * 60 + Get8(17), Get8(18), Get8(19));
m_last_possible_leadout_start_address = new MinuteSecondFrame(Get8(20) * 60 + Get8(21), Get8(22), Get8(23));
OpcTable = new List();
if (BufferSize > 33)
{
byte cnt = Get8(33);
int offset = 34;
for(byte i = 0 ; i < cnt && offset < BufferSize ; i++)
{
OpcTableEntry entry = new OpcTableEntry(Buffer, BufferSize, offset);
OpcTable.Add(entry);
offset += 8;
}
}
}
#endregion
}
}