mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 10:04:24 +00:00
Initial checkin
This commit is contained in:
112
Bwg.Hardware/Bwg.Hardware.csproj
Normal file
112
Bwg.Hardware/Bwg.Hardware.csproj
Normal file
@@ -0,0 +1,112 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{B75FA7AD-968E-4990-B342-1B4B17C850DF}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Bwg.Hardware</RootNamespace>
|
||||
<AssemblyName>Bwg.Hardware</AssemblyName>
|
||||
<SccProjectName>
|
||||
</SccProjectName>
|
||||
<SccLocalPath>
|
||||
</SccLocalPath>
|
||||
<SccAuxPath>
|
||||
</SccAuxPath>
|
||||
<SccProvider>
|
||||
</SccProvider>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>2.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>bin\Debug\Bwg.Hardware.XML</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>bin\Debug\Bwg.Hardware.XML</DocumentationFile>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>bin\Debug\Bwg.Hardware.XML</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="HardwareDevice.cs" />
|
||||
<Compile Include="HardwareManager.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
209
Bwg.Hardware/HardwareDevice.cs
Normal file
209
Bwg.Hardware/HardwareDevice.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Bwg.Hardware
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a hardware device as extracted from the registry.
|
||||
/// </summary>
|
||||
public class HardwareDevice
|
||||
{
|
||||
#region private member variables
|
||||
private string m_name;
|
||||
private string m_desc;
|
||||
private string m_class;
|
||||
private Guid m_class_guid;
|
||||
private string m_key_name ;
|
||||
private string m_location;
|
||||
private string[] m_hardware;
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// The constructor for a device.
|
||||
/// </summary>
|
||||
/// <param name="key">the name of the registry key that contains info about this device</param>
|
||||
public HardwareDevice(string key)
|
||||
{
|
||||
m_key_name = key;
|
||||
m_name = string.Empty ;
|
||||
m_desc = string.Empty ;
|
||||
m_location = string.Empty;
|
||||
|
||||
m_hardware = new string[0];
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
/// <summary>
|
||||
/// Add a new hardware address to the device
|
||||
/// </summary>
|
||||
/// <param name="addr">the new address to add to the device</param>
|
||||
public void AddHardware(string addr)
|
||||
{
|
||||
int count = m_hardware.GetLength(0);
|
||||
Array.Resize(ref m_hardware, count + 1);
|
||||
m_hardware[count] = addr;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
|
||||
/// <summary>
|
||||
/// The name of the key where this information was extracted
|
||||
/// </summary>
|
||||
public string KeyName
|
||||
{
|
||||
get { return m_key_name; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property is the (friendly) name of the device
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_name != string.Empty)
|
||||
return m_name;
|
||||
|
||||
if (m_desc != string.Empty)
|
||||
return m_desc;
|
||||
|
||||
return m_key_name;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property is the description of the device
|
||||
/// </summary>
|
||||
public string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_desc;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_desc = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property is the class that the device belong to
|
||||
/// </summary>
|
||||
public string Class
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_class;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_class = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property is the GUID for the class that the device belongs to
|
||||
/// </summary>
|
||||
public Guid ClassGUID
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_class_guid;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_class_guid = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property is the location of the device
|
||||
/// </summary>
|
||||
public string Location
|
||||
{
|
||||
get { return m_location; }
|
||||
set { m_location = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class is the hardware addresses assocaited with the device
|
||||
/// </summary>
|
||||
public string[] Hardware
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_hardware;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if the device is an IDE device
|
||||
/// </summary>
|
||||
public bool IsIde
|
||||
{
|
||||
get
|
||||
{
|
||||
return HardwareStartsWith("IDE");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if this is a USB device
|
||||
/// </summary>
|
||||
public bool IsUsb
|
||||
{
|
||||
get
|
||||
{
|
||||
return HardwareStartsWith("USB") ;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if this is a Firewire device
|
||||
/// </summary>
|
||||
public bool IsFirewire
|
||||
{
|
||||
get
|
||||
{
|
||||
return HardwareStartsWith("SBP2");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if this is a SCSI device
|
||||
/// </summary>
|
||||
public bool IsScsi
|
||||
{
|
||||
get
|
||||
{
|
||||
return HardwareStartsWith("SCSI");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private methods
|
||||
/// <summary>
|
||||
/// This method returns true if the hardware address start with the string given
|
||||
/// </summary>
|
||||
/// <param name="begin">the string to start with</param>
|
||||
/// <returns>true if the string begins with the right value, otherwise false</returns>
|
||||
public bool HardwareStartsWith(string begin)
|
||||
{
|
||||
foreach (string str in m_hardware)
|
||||
{
|
||||
if (str.StartsWith(begin))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
209
Bwg.Hardware/HardwareManager.cs
Normal file
209
Bwg.Hardware/HardwareManager.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Bwg.Hardware
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is the manager that reads the registry and determines which devices exist
|
||||
/// </summary>
|
||||
public class HardwareManager : IEnumerable<HardwareDevice>, IEnumerable
|
||||
{
|
||||
#region private member variables
|
||||
private IList<HardwareDevice> m_devices;
|
||||
#endregion
|
||||
|
||||
#region constructors
|
||||
/// <summary>
|
||||
/// The constructor for the device manager, creates a list for devices to be added.
|
||||
/// </summary>
|
||||
public HardwareManager()
|
||||
{
|
||||
m_devices = new List<HardwareDevice>();
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Return an enumerator for iterating over all of the tracks on the
|
||||
/// disk.
|
||||
/// </summary>
|
||||
/// <returns>iterator</returns>
|
||||
public IEnumerator<HardwareDevice> GetEnumerator()
|
||||
{
|
||||
return m_devices.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return m_devices.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open a given machine, or the default machine if no machine is given
|
||||
/// </summary>
|
||||
/// <param name="keyname"></param>
|
||||
/// <returns></returns>
|
||||
public bool OpenMachine(string keyname)
|
||||
{
|
||||
if (keyname == string.Empty)
|
||||
keyname = "System\\CurrentControlSet\\Enum";
|
||||
|
||||
RegistryKey key = Registry.LocalMachine.OpenSubKey(keyname);
|
||||
if (key == null)
|
||||
return false;
|
||||
|
||||
CheckForHardware(key);
|
||||
key.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a specific device given its class, vendor, and product
|
||||
/// </summary>
|
||||
/// <param name="classname">the class of the device</param>
|
||||
/// <param name="vendor">the vendor id of the device</param>
|
||||
/// <param name="product">the product id of the device</param>
|
||||
/// <returns></returns>
|
||||
public HardwareDevice FindDevice(string classname, string vendor, string product)
|
||||
{
|
||||
foreach (HardwareDevice dev in m_devices)
|
||||
{
|
||||
if (dev.Class != classname)
|
||||
continue;
|
||||
|
||||
if (dev.Name.Contains(vendor) && dev.Name.Contains(product))
|
||||
{
|
||||
if (dev.IsUsb && dev.Location.Length == 0)
|
||||
dev.Location = FindUsbLocation(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#region private methods
|
||||
|
||||
private string FindUsbLocation(HardwareDevice cddev)
|
||||
{
|
||||
string result = string.Empty;
|
||||
int index = cddev.KeyName.LastIndexOf('&');
|
||||
if (index == -1)
|
||||
return result;
|
||||
|
||||
string devname = cddev.KeyName.Substring(0, index);
|
||||
foreach (HardwareDevice dev in m_devices)
|
||||
{
|
||||
if (dev.Class == "USB" && dev.KeyName == devname)
|
||||
return dev.Location;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool FindClassString(string s1)
|
||||
{
|
||||
return s1 == "Class";
|
||||
}
|
||||
|
||||
private static bool FindClassGUIDString(string s1)
|
||||
{
|
||||
return s1 == "ClassGUID";
|
||||
}
|
||||
|
||||
private void CreateDevice(RegistryKey key)
|
||||
{
|
||||
string keyname = key.ToString();
|
||||
string onekey ;
|
||||
HardwareDevice dev;
|
||||
|
||||
try
|
||||
{
|
||||
onekey = Path.GetFileName(keyname);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dev = new HardwareDevice(onekey);
|
||||
object value;
|
||||
|
||||
value = key.GetValue("Class");
|
||||
if (value != null)
|
||||
{
|
||||
if (value is string)
|
||||
dev.Class = (string)value;
|
||||
else if (value is string[])
|
||||
{
|
||||
dev.Class = ((string[])value)[0];
|
||||
}
|
||||
}
|
||||
|
||||
value = key.GetValue("ClassGUID");
|
||||
if (value != null && value is string)
|
||||
dev.ClassGUID = new Guid((string)value);
|
||||
|
||||
value = key.GetValue("DeviceDesc");
|
||||
if (value != null && value is string)
|
||||
dev.Description = (string)value;
|
||||
|
||||
value = key.GetValue("FriendlyName");
|
||||
if (value != null && value is string)
|
||||
dev.Name = (string)value;
|
||||
|
||||
value = key.GetValue("LocationInformation");
|
||||
if (value != null && value is string)
|
||||
dev.Location = (string)value;
|
||||
|
||||
value = key.GetValue("HardwareID");
|
||||
if (value != null)
|
||||
{
|
||||
if (value is string)
|
||||
dev.AddHardware((string)value);
|
||||
else if (value is string[])
|
||||
{
|
||||
foreach (string str in (string[])value)
|
||||
dev.AddHardware(str);
|
||||
}
|
||||
}
|
||||
|
||||
m_devices.Add(dev);
|
||||
}
|
||||
|
||||
private void CheckForHardware(RegistryKey key)
|
||||
{
|
||||
string[] values = key.GetValueNames();
|
||||
if (Array.Find(values, FindClassString) != null && Array.Find(values, FindClassGUIDString) != null)
|
||||
{
|
||||
// This is a device
|
||||
CreateDevice(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
values = key.GetSubKeyNames();
|
||||
foreach (string str in values)
|
||||
{
|
||||
try
|
||||
{
|
||||
RegistryKey subkey = key.OpenSubKey(str);
|
||||
if (subkey != null)
|
||||
{
|
||||
CheckForHardware(subkey);
|
||||
subkey.Close();
|
||||
}
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
35
Bwg.Hardware/Properties/AssemblyInfo.cs
Normal file
35
Bwg.Hardware/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Bwg.Hardware")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("BwgSoftware")]
|
||||
[assembly: AssemblyProduct("BwgBurn")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2006 by Jack W. Griffin, Jr.")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("de5dc145-3520-47ee-8988-205a142c6177")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("0.0.7.1")]
|
||||
[assembly: AssemblyFileVersion("0.0.7.1")]
|
||||
121
Bwg.Logging/Bwg.Logging.csproj
Normal file
121
Bwg.Logging/Bwg.Logging.csproj
Normal file
@@ -0,0 +1,121 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{F2DFEB00-BB35-4665-85EA-CB8C7729A6B7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Bwg.Logging</RootNamespace>
|
||||
<AssemblyName>Bwg.Logging</AssemblyName>
|
||||
<SccProjectName>
|
||||
</SccProjectName>
|
||||
<SccLocalPath>
|
||||
</SccLocalPath>
|
||||
<SccAuxPath>
|
||||
</SccAuxPath>
|
||||
<SccProvider>
|
||||
</SccProvider>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>2.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>bin\Debug\Bwg.Logging.XML</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>bin\Release\Bwg.Logging.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>bin\Debug\Bwg.Logging.XML</DocumentationFile>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>bin\Release\Bwg.Logging.XML</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>bin\Debug\Bwg.Logging.XML</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>bin\Release\Bwg.Logging.XML</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ConsoleSink.cs" />
|
||||
<Compile Include="FileSink.cs" />
|
||||
<Compile Include="Logger.cs" />
|
||||
<Compile Include="MemorySink.cs" />
|
||||
<Compile Include="MessageAddedArgs.cs" />
|
||||
<Compile Include="TeeSink.cs" />
|
||||
<Compile Include="UserMessage.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Sink.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
47
Bwg.Logging/ConsoleSink.cs
Normal file
47
Bwg.Logging/ConsoleSink.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// A message sink class that writes messages to the console
|
||||
/// </summary>
|
||||
public class ConsoleSink : Sink
|
||||
{
|
||||
/// <summary>
|
||||
/// Log the message to the console
|
||||
/// </summary>
|
||||
/// <param name="m">the message</param>
|
||||
public override void LogMessage(UserMessage m)
|
||||
{
|
||||
if (m.Code == 0)
|
||||
System.Console.WriteLine(m.MType.ToString() + ": " + m.Text);
|
||||
else
|
||||
System.Console.WriteLine(m.MType.ToString() + " " + m.Code.ToString() + ": " + m.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
Bwg.Logging/FileSink.cs
Normal file
67
Bwg.Logging/FileSink.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO ;
|
||||
|
||||
namespace Bwg.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is a message sink that writes the message to a file
|
||||
/// </summary>
|
||||
public class FileSink : Sink, IDisposable
|
||||
{
|
||||
#region private member variables
|
||||
private TextWriter m_writer;
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// Create a new file sink given the name of the output file
|
||||
/// </summary>
|
||||
/// <param name="filename">the output file</param>
|
||||
public FileSink(string filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_writer = new StreamWriter(filename);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_writer = null;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
/// <summary>
|
||||
/// Dispose of the class, close the file
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close the file
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
if (m_writer != null)
|
||||
{
|
||||
m_writer.Flush();
|
||||
m_writer.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log the message
|
||||
/// </summary>
|
||||
/// <param name="m">the message to log</param>
|
||||
public override void LogMessage(UserMessage m)
|
||||
{
|
||||
if (m_writer != null)
|
||||
m_writer.WriteLine(m.ToString());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
213
Bwg.Logging/Logger.cs
Normal file
213
Bwg.Logging/Logger.cs
Normal file
@@ -0,0 +1,213 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// This class allows for the logging of messages
|
||||
/// </summary>
|
||||
public class Logger
|
||||
{
|
||||
/// <summary>
|
||||
/// This is used to lock the logger when multiple threads are
|
||||
/// trying to log messages concurrently
|
||||
/// </summary>
|
||||
private Object m_lock_object;
|
||||
|
||||
/// <summary>
|
||||
/// This is a map from message type to sinks
|
||||
/// </summary>
|
||||
private IDictionary<UserMessage.Category, Sink> m_sinks;
|
||||
|
||||
/// <summary>
|
||||
/// This is a map from the message type to the level that is being filtered. Anything
|
||||
/// below the value found here is not displayed
|
||||
/// </summary>
|
||||
private IDictionary<UserMessage.Category, int> m_level;
|
||||
|
||||
/// <summary>
|
||||
/// Create the logging object
|
||||
/// </summary>
|
||||
public Logger()
|
||||
{
|
||||
m_lock_object = new Object();
|
||||
m_sinks = new Dictionary<UserMessage.Category, Sink>();
|
||||
m_level = new Dictionary<UserMessage.Category, int>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assocated a sink with a given type of message
|
||||
/// </summary>
|
||||
/// <param name="c">the category of message</param>
|
||||
/// <param name="s">the sink for this category of message</param>
|
||||
public void SetSink(UserMessage.Category c, Sink s)
|
||||
{
|
||||
lock (m_lock_object)
|
||||
{
|
||||
m_sinks[c] = s;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the sink given the type of message
|
||||
/// </summary>
|
||||
/// <param name="c">the type of sink</param>
|
||||
/// <returns>the sink associated with the message type</returns>
|
||||
public Sink GetSink(UserMessage.Category c)
|
||||
{
|
||||
Sink s = null;
|
||||
|
||||
lock (m_lock_object)
|
||||
{
|
||||
m_sinks.TryGetValue(c, out s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets a level, below which messages are filtered
|
||||
/// </summary>
|
||||
/// <param name="c">the category to filter</param>
|
||||
/// <param name="level">the level to display</param>
|
||||
public void SetLevel(UserMessage.Category c, int level)
|
||||
{
|
||||
lock (m_lock_object)
|
||||
{
|
||||
m_level[c] = level;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given the category, this method returns the current
|
||||
/// level for this type of message
|
||||
/// </summary>
|
||||
/// <param name="c">the type of message</param>
|
||||
/// <returns>the current level</returns>
|
||||
public int GetLevel(UserMessage.Category c)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
lock (m_lock_object)
|
||||
{
|
||||
if (m_level.ContainsKey(c))
|
||||
ret = m_level[c];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Remove the sink associated with a specific category of message.
|
||||
/// </summary>
|
||||
/// <param name="c">the category of message</param>
|
||||
public void RemoveSink(UserMessage.Category c)
|
||||
{
|
||||
lock (m_lock_object)
|
||||
{
|
||||
m_sinks.Remove(c);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function returns TRUE if the logger has a message sink for the given
|
||||
/// category of message. Otherwise it returns FALSE.
|
||||
/// </summary>
|
||||
/// <param name="c">the category of interest</param>
|
||||
/// <returns>true if a sink is present, false otherwise</returns>
|
||||
public bool HasSink(UserMessage.Category c)
|
||||
{
|
||||
return m_sinks.Keys.Contains(c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message
|
||||
/// </summary>
|
||||
/// <param name="m">the message to log</param>
|
||||
public void LogMessage(UserMessage m)
|
||||
{
|
||||
lock (m_lock_object)
|
||||
{
|
||||
if (m_sinks.ContainsKey(m.MType))
|
||||
{
|
||||
int level = 0;
|
||||
|
||||
if (m_level.ContainsKey(m.MType))
|
||||
level = m_level[m.MType];
|
||||
|
||||
if (m.Level <= level)
|
||||
{
|
||||
Sink s = m_sinks[m.MType];
|
||||
s.LogMessage(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dump a data buffer to the log file, used for debugging
|
||||
/// </summary>
|
||||
/// <param name="loglevel">the log level</param>
|
||||
/// <param name="title">the title</param>
|
||||
/// <param name="buffer">the buffer</param>
|
||||
/// <param name="size">the buffer size</param>
|
||||
public void DumpBuffer(uint loglevel, string title, IntPtr buffer, int size)
|
||||
{
|
||||
UserMessage m;
|
||||
|
||||
m = new UserMessage(UserMessage.Category.Debug, loglevel, "Dumping data for structure '" + title + "'");
|
||||
LogMessage(m);
|
||||
|
||||
int index = 0;
|
||||
int linebytes = 0;
|
||||
string str = string.Empty;
|
||||
while (index < size)
|
||||
{
|
||||
if (linebytes == 16)
|
||||
{
|
||||
m = new UserMessage(UserMessage.Category.Debug, loglevel, str);
|
||||
LogMessage(m);
|
||||
linebytes = 0;
|
||||
str = string.Empty;
|
||||
}
|
||||
|
||||
byte b = Marshal.ReadByte(buffer, index++);
|
||||
str += b.ToString("X2") + " ";
|
||||
linebytes++;
|
||||
}
|
||||
|
||||
if (linebytes != 0)
|
||||
{
|
||||
m = new UserMessage(UserMessage.Category.Debug, loglevel, str);
|
||||
LogMessage(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
114
Bwg.Logging/MemorySink.cs
Normal file
114
Bwg.Logging/MemorySink.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is a message sink that stores all of the messages
|
||||
/// in a list.
|
||||
/// </summary>
|
||||
public class MemorySink : Sink
|
||||
{
|
||||
private Object m_lock;
|
||||
private IList<UserMessage> m_list ;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public EventHandler<MessageAddedArgs> MessageAdded;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public MemorySink()
|
||||
{
|
||||
m_lock = new Object();
|
||||
m_list = new List<UserMessage>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int GetMessageCount()
|
||||
{
|
||||
int cnt;
|
||||
|
||||
lock (m_lock)
|
||||
{
|
||||
cnt = m_list.Count;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public UserMessage GetMessage(int n)
|
||||
{
|
||||
UserMessage m;
|
||||
|
||||
lock (m_lock)
|
||||
{
|
||||
m = m_list[n];
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
public override void LogMessage(UserMessage m)
|
||||
{
|
||||
lock (m_lock)
|
||||
{
|
||||
m_list.Add(m);
|
||||
}
|
||||
|
||||
if (MessageAdded != null)
|
||||
{
|
||||
MessageAddedArgs args = new MessageAddedArgs(m);
|
||||
MessageAdded(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
lock (m_lock)
|
||||
{
|
||||
m_list.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
49
Bwg.Logging/MessageAddedArgs.cs
Normal file
49
Bwg.Logging/MessageAddedArgs.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Logging
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MessageAddedArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public UserMessage AddedMessage;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
public MessageAddedArgs(UserMessage m)
|
||||
{
|
||||
AddedMessage = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Bwg.Logging/Properties/AssemblyInfo.cs
Normal file
35
Bwg.Logging/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Bwg.Logging")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("BwgSoftware")]
|
||||
[assembly: AssemblyProduct("BwgBurn")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2006 by Jack W. Griffin, Jr.")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("216f12e9-2978-457c-95d6-32b4b87a361d")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("0.0.7.1")]
|
||||
[assembly: AssemblyFileVersion("0.0.7.1")]
|
||||
43
Bwg.Logging/Sink.cs
Normal file
43
Bwg.Logging/Sink.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract class that provides a place to send messages meant for the
|
||||
/// user. A class derived from this class is used to allow for GUI versus
|
||||
/// console applications
|
||||
/// </summary>
|
||||
abstract public class Sink
|
||||
{
|
||||
/// <summary>
|
||||
/// This method sends a message to a sink.
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
abstract public void LogMessage(UserMessage m);
|
||||
}
|
||||
}
|
||||
59
Bwg.Logging/TeeSink.cs
Normal file
59
Bwg.Logging/TeeSink.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Bwg.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is a message sink that forwards a message to a set of receiving sinks
|
||||
/// </summary>
|
||||
public class TeeSink : Sink
|
||||
{
|
||||
#region private member variables
|
||||
/// <summary>
|
||||
/// The list of sinks to send the message to
|
||||
/// </summary>
|
||||
IList<Sink> m_sinks;
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// The constructor to creat the object
|
||||
/// </summary>
|
||||
public TeeSink()
|
||||
{
|
||||
m_sinks = new List<Sink>();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
/// <summary>
|
||||
/// Add the sink to the list of receiving sinks
|
||||
/// </summary>
|
||||
/// <param name="s">the sink to add</param>
|
||||
public void AddSink(Sink s)
|
||||
{
|
||||
m_sinks.Add(s);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the sink to the list of receiving sinks
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public void RemoveSink(Sink s)
|
||||
{
|
||||
m_sinks.Remove(s);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message to the receiving sinks
|
||||
/// </summary>
|
||||
/// <param name="m">the message</param>
|
||||
public override void LogMessage(UserMessage m)
|
||||
{
|
||||
foreach (Sink s in m_sinks)
|
||||
s.LogMessage(m);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
117
Bwg.Logging/UserMessage.cs
Normal file
117
Bwg.Logging/UserMessage.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// A message to be logged to the u
|
||||
/// </summary>
|
||||
public class UserMessage
|
||||
{
|
||||
#region Public Types
|
||||
/// <summary>
|
||||
/// Message types
|
||||
/// </summary>
|
||||
public enum Category
|
||||
{
|
||||
/// <summary>
|
||||
/// An error occurred
|
||||
/// </summary>
|
||||
Error,
|
||||
|
||||
/// <summary>
|
||||
/// A warning occurred
|
||||
/// </summary>
|
||||
Warning,
|
||||
|
||||
/// <summary>
|
||||
/// Information about the process
|
||||
/// </summary>
|
||||
Info,
|
||||
|
||||
/// <summary>
|
||||
/// Debugging information
|
||||
/// </summary>
|
||||
Debug
|
||||
} ;
|
||||
#endregion
|
||||
|
||||
#region Public Data Members
|
||||
/// <summary>
|
||||
/// The category for the message (error, warning, info, debug)
|
||||
/// </summary>
|
||||
public readonly Category MType ;
|
||||
|
||||
/// <summary>
|
||||
/// The numeric error code
|
||||
/// </summary>
|
||||
public readonly uint Code ;
|
||||
|
||||
/// <summary>
|
||||
/// The text for the error message
|
||||
/// </summary>
|
||||
public readonly string Text;
|
||||
|
||||
/// <summary>
|
||||
/// The level for the message, used to filter out messages
|
||||
/// </summary>
|
||||
public readonly uint Level;
|
||||
|
||||
/// <summary>
|
||||
/// This member contains a time stamp for the message
|
||||
/// </summary>
|
||||
public readonly DateTime When;
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// Constructor for a message
|
||||
/// </summary>
|
||||
/// <param name="t">Category of the message</param>
|
||||
/// <param name="level">Level of the message</param>
|
||||
/// <param name="s">Text of the message</param>
|
||||
public UserMessage(Category t, uint level, string s)
|
||||
{
|
||||
MType = t;
|
||||
Text = s;
|
||||
Level = level;
|
||||
When = DateTime.Now;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public member functions
|
||||
/// <summary>
|
||||
/// This method converts a user message to a single string
|
||||
/// </summary>
|
||||
/// <returns>the string that represnts the message</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return When.ToLongDateString() + " " + When.ToLongTimeString() + " : " + MType.ToString() + " : Level " + Level.ToString() + " : " + Text;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
150
Bwg.Scsi/AtipInfo.cs
Normal file
150
Bwg.Scsi/AtipInfo.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
//
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents the ATIP information read from the disk
|
||||
/// </summary>
|
||||
public class AtipInfo : Result
|
||||
{
|
||||
/// <summary>
|
||||
/// The target write power for the disk
|
||||
/// </summary>
|
||||
public readonly byte IndicativeTargetWritingPower;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly byte ReferenceSpeed;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this is a double density CD
|
||||
/// </summary>
|
||||
public readonly bool IsDDCD;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this disk is for unrestricted use
|
||||
/// </summary>
|
||||
public readonly bool UnrestrictedUse;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the media is CDRW, otherwise it is CDR
|
||||
/// </summary>
|
||||
public readonly bool MediaCDRW;
|
||||
|
||||
/// <summary>
|
||||
/// The CD/RW media subtype
|
||||
/// </summary>
|
||||
public readonly byte MediaSubtype;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool A1Valid;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool A2Valid;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool A3Valid;
|
||||
|
||||
/// <summary>
|
||||
/// The ATIP value for the starting leadin time
|
||||
/// </summary>
|
||||
public readonly MinuteSecondFrame StartTimeOfLeadin;
|
||||
|
||||
/// <summary>
|
||||
/// This is the address for the last possible leadout
|
||||
/// </summary>
|
||||
public readonly MinuteSecondFrame LastPossibleStartOfLeadout;
|
||||
|
||||
/// <summary>
|
||||
/// The data from the A1 field
|
||||
/// </summary>
|
||||
public readonly byte[] A1Values;
|
||||
|
||||
/// <summary>
|
||||
/// The data from the A1 field
|
||||
/// </summary>
|
||||
public readonly byte[] A2Values;
|
||||
|
||||
/// <summary>
|
||||
/// The data from the A3 field
|
||||
/// </summary>
|
||||
public readonly byte[] A3Values;
|
||||
|
||||
/// <summary>
|
||||
/// This constructs the ATIP infomation
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="size"></param>
|
||||
public AtipInfo(IntPtr buffer, int size) : base(buffer, size)
|
||||
{
|
||||
byte b;
|
||||
|
||||
if (size < 4)
|
||||
return;
|
||||
|
||||
b = Get8(4);
|
||||
IndicativeTargetWritingPower = (byte)((b >> 4) & 0x0f);
|
||||
IsDDCD = GetBit(4, 3);
|
||||
ReferenceSpeed = (byte)(b & 0x07);
|
||||
|
||||
b = Get8(5);
|
||||
UnrestrictedUse = GetBit(5, 6);
|
||||
|
||||
b = Get8(6);
|
||||
MediaCDRW = GetBit(6, 6);
|
||||
MediaSubtype = (byte)((b >> 3) & 0x07);
|
||||
|
||||
A1Valid = GetBit(6, 2);
|
||||
A2Valid = GetBit(6, 1);
|
||||
A3Valid = GetBit(6, 0);
|
||||
|
||||
StartTimeOfLeadin = new MinuteSecondFrame(Get8(8), Get8(9), Get8(10));
|
||||
LastPossibleStartOfLeadout = new MinuteSecondFrame(Get8(12), Get8(13), Get8(14));
|
||||
|
||||
A1Values = new byte[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
A1Values[i] = Get8(i + 16);
|
||||
|
||||
A2Values = new byte[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
A2Values[i] = Get8(i + 20);
|
||||
|
||||
A3Values = new byte[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
A3Values[i] = Get8(i + 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
159
Bwg.Scsi/Bwg.Scsi.csproj
Normal file
159
Bwg.Scsi/Bwg.Scsi.csproj
Normal file
@@ -0,0 +1,159 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{A05B6AA6-0EC3-495D-BCC4-ECE1210071A8}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Bwg.Scsi</RootNamespace>
|
||||
<AssemblyName>Bwg.Scsi</AssemblyName>
|
||||
<SccProjectName>
|
||||
</SccProjectName>
|
||||
<SccLocalPath>
|
||||
</SccLocalPath>
|
||||
<SccAuxPath>
|
||||
</SccAuxPath>
|
||||
<SccProvider>
|
||||
</SccProvider>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>2.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Debug\Bwg.Scsi.XML</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Release\Bwg.Scsi.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Debug\Bwg.Scsi.XML</DocumentationFile>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Release\Bwg.Scsi.XML</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Debug\Bwg.Scsi.XML</DocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Release\Bwg.Scsi.XML</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AtipInfo.cs" />
|
||||
<Compile Include="CapacityDescriptor.cs" />
|
||||
<Compile Include="Command.cs" />
|
||||
<Compile Include="Defs.cs" />
|
||||
<Compile Include="Device.cs" />
|
||||
<Compile Include="DeviceInfo.cs" />
|
||||
<Compile Include="DeviceManager.cs" />
|
||||
<Compile Include="DeviceManagerRescanArgs.cs" />
|
||||
<Compile Include="DiskInformation.cs" />
|
||||
<Compile Include="EventStatusNotification.cs" />
|
||||
<Compile Include="Feature.cs" />
|
||||
<Compile Include="FeatureList.cs" />
|
||||
<None Include="FileReader.cs" />
|
||||
<Compile Include="FormatParameterList.cs" />
|
||||
<Compile Include="HeaderData.cs" />
|
||||
<Compile Include="InitializationPattern.cs" />
|
||||
<Compile Include="InquiryResult.cs" />
|
||||
<Compile Include="MinuteSecondFrame.cs" />
|
||||
<Compile Include="ModePage.cs" />
|
||||
<Compile Include="ModeTable.cs" />
|
||||
<Compile Include="OpcTableEntry.cs" />
|
||||
<Compile Include="Performance.cs" />
|
||||
<Compile Include="PerformanceList.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Result.cs" />
|
||||
<Compile Include="SpeedDescriptor.cs" />
|
||||
<Compile Include="SpeedDescriptorList.cs" />
|
||||
<Compile Include="SubheaderData.cs" />
|
||||
<Compile Include="TocEntry.cs" />
|
||||
<Compile Include="TrackInformation.cs" />
|
||||
<Compile Include="WinDev.cs" />
|
||||
<Compile Include="WriteBuffer.cs" />
|
||||
<Compile Include="WriteBufferPool.cs" />
|
||||
<Compile Include="WriteBufferStream.cs" />
|
||||
<Compile Include="WriteParameterModePage.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Bwg.Logging\Bwg.Logging.csproj">
|
||||
<Project>{F2DFEB00-BB35-4665-85EA-CB8C7729A6B7}</Project>
|
||||
<Name>Bwg.Logging</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
109
Bwg.Scsi/CapacityDescriptor.cs
Normal file
109
Bwg.Scsi/CapacityDescriptor.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CapacityDescriptor : Result
|
||||
{
|
||||
#region public types
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum DescriptorType : byte
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
Reserved = 0,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
Unformatted = 1,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
Formatted = 2,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
NoMedia = 3
|
||||
} ;
|
||||
#endregion
|
||||
|
||||
#region public variables
|
||||
|
||||
/// <summary>
|
||||
/// The number of blocks on this media.
|
||||
/// </summary>
|
||||
public readonly uint NumberOfBlocks;
|
||||
|
||||
/// <summary>
|
||||
/// This length of a single block for this capacity
|
||||
/// </summary>
|
||||
public readonly uint BlockLength;
|
||||
|
||||
/// <summary>
|
||||
/// This is the descriptor type, see the SCSI-3 MMC specification
|
||||
/// </summary>
|
||||
public readonly DescriptorType DescType;
|
||||
|
||||
/// <summary>
|
||||
/// This is the type of format for the capacity descriptor, see the SCSI-3 MMC spec
|
||||
/// </summary>
|
||||
public readonly byte FormatType;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="size"></param>
|
||||
public CapacityDescriptor(IntPtr buffer, int offset, int size)
|
||||
: base(buffer, size)
|
||||
{
|
||||
byte b;
|
||||
|
||||
NumberOfBlocks = Get32(offset);
|
||||
|
||||
b = Get8(offset + 4);
|
||||
DescType = (DescriptorType)(b & 0x03);
|
||||
FormatType = (byte)(b >> 2);
|
||||
|
||||
BlockLength = Get24(offset + 5);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
236
Bwg.Scsi/Command.cs
Normal file
236
Bwg.Scsi/Command.cs
Normal file
@@ -0,0 +1,236 @@
|
||||
//
|
||||
// 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;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
class Command : IDisposable
|
||||
{
|
||||
[DllImport("ntdll.dll")]
|
||||
internal static extern void RtlZeroMemory(IntPtr dest, int size);
|
||||
|
||||
public enum CmdDirection
|
||||
{
|
||||
In,
|
||||
Out,
|
||||
None
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
/// The data buffer for the SCSI command
|
||||
/// </summary>
|
||||
private int m_buffer_size;
|
||||
private IntPtr m_buffer;
|
||||
private bool m_delete_buffer;
|
||||
|
||||
/// <summary>
|
||||
/// The CDB buffer for the command. This gets copied into the SCSI_PASS_THROUGH_DIRECT
|
||||
/// structure when this command is sent to the SCSI target.
|
||||
/// </summary>
|
||||
private byte[] m_cdb;
|
||||
|
||||
/// <summary>
|
||||
/// The direction of data transfer via the m_buffer field above
|
||||
/// </summary>
|
||||
private CmdDirection m_dir;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of time to pass in seconds before a timeout
|
||||
/// </summary>
|
||||
private int m_timeout;
|
||||
|
||||
public Command(ScsiCommandCode code, byte cdbsize, int bufsize, CmdDirection dir, int timeout)
|
||||
{
|
||||
Debug.Assert(bufsize < UInt16.MaxValue);
|
||||
|
||||
m_cdb = new byte[cdbsize];
|
||||
m_cdb[0] = (byte)code;
|
||||
|
||||
m_buffer_size = bufsize;
|
||||
if (bufsize == 0)
|
||||
m_buffer = IntPtr.Zero;
|
||||
else
|
||||
{
|
||||
m_delete_buffer = true;
|
||||
m_buffer = Marshal.AllocHGlobal(bufsize);
|
||||
RtlZeroMemory(m_buffer, bufsize);
|
||||
}
|
||||
|
||||
m_dir = dir;
|
||||
m_timeout = timeout;
|
||||
}
|
||||
|
||||
public Command(ScsiCommandCode code, byte cdbsize, IntPtr buffer, int bufsize, CmdDirection dir, int timeout)
|
||||
{
|
||||
m_cdb = new byte[cdbsize];
|
||||
m_cdb[0] = (byte)code;
|
||||
|
||||
m_buffer_size = bufsize;
|
||||
if (bufsize == 0)
|
||||
m_buffer = IntPtr.Zero;
|
||||
else
|
||||
{
|
||||
m_delete_buffer = false;
|
||||
m_buffer = buffer;
|
||||
}
|
||||
|
||||
m_dir = dir;
|
||||
m_timeout = timeout;
|
||||
}
|
||||
|
||||
public int TimeOut
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
public ushort GetCDBLength()
|
||||
{
|
||||
return (ushort)m_cdb.GetLength(0);
|
||||
}
|
||||
|
||||
public CmdDirection Direction { get { return m_dir; } }
|
||||
public int BufferSize { get { return m_buffer_size; } }
|
||||
public IntPtr GetBuffer() { return m_buffer ; }
|
||||
public byte GetCDB(byte addr) { return m_cdb[addr] ; }
|
||||
|
||||
public void SetCDB8(byte addr, byte value)
|
||||
{
|
||||
m_cdb[addr] = value;
|
||||
}
|
||||
|
||||
public void SetCDB16(byte addr, ushort value)
|
||||
{
|
||||
m_cdb[addr] = (byte)((value >> 8) & 0xff);
|
||||
m_cdb[addr + 1] = (byte)(value & 0xff);
|
||||
}
|
||||
|
||||
public void SetCDB24(byte addr, uint value)
|
||||
{
|
||||
m_cdb[addr] = (byte)((value >> 16) & 0xff);
|
||||
m_cdb[addr + 1] = (byte)((value >> 8) & 0xff);
|
||||
m_cdb[addr + 2] = (byte)(value & 0xff);
|
||||
}
|
||||
|
||||
public void SetCDB24(byte addr, int value)
|
||||
{
|
||||
m_cdb[addr] = (byte)((value >> 16) & 0xff);
|
||||
m_cdb[addr + 1] = (byte)((value >> 8) & 0xff);
|
||||
m_cdb[addr + 2] = (byte)(value & 0xff);
|
||||
}
|
||||
|
||||
public void SetCDB32(byte addr, uint value)
|
||||
{
|
||||
m_cdb[addr] = (byte)((value >> 24) & 0xff);
|
||||
m_cdb[addr + 1] = (byte)((value >> 16) & 0xff);
|
||||
m_cdb[addr + 2] = (byte)((value >> 8) & 0xff);
|
||||
m_cdb[addr + 3] = (byte)(value & 0xff);
|
||||
}
|
||||
|
||||
public void SetCDB32(byte addr, int value)
|
||||
{
|
||||
m_cdb[addr] = (byte)((value >> 24) & 0xff);
|
||||
m_cdb[addr + 1] = (byte)((value >> 16) & 0xff);
|
||||
m_cdb[addr + 2] = (byte)((value >> 8) & 0xff);
|
||||
m_cdb[addr + 3] = (byte)(value & 0xff);
|
||||
}
|
||||
|
||||
public void SetBuffer8(ushort addr, byte value)
|
||||
{
|
||||
Marshal.WriteByte(m_buffer, addr, value);
|
||||
}
|
||||
|
||||
public void SetBuffer16(ushort addr, ushort value)
|
||||
{
|
||||
Marshal.WriteByte(m_buffer, addr + 0, (byte)((value >> 8) & 0xff));
|
||||
Marshal.WriteByte(m_buffer, addr + 1, (byte)((value >> 0) & 0xff));
|
||||
}
|
||||
|
||||
public void SetBuffer24(ushort addr, uint value)
|
||||
{
|
||||
Marshal.WriteByte(m_buffer, addr + 0, (byte)((value >> 16) & 0xff));
|
||||
Marshal.WriteByte(m_buffer, addr + 1, (byte)((value >> 8) & 0xff));
|
||||
Marshal.WriteByte(m_buffer, addr + 2, (byte)((value >> 0) & 0xff));
|
||||
}
|
||||
|
||||
public void SetBuffer32(ushort addr, uint value)
|
||||
{
|
||||
Marshal.WriteByte(m_buffer, addr + 0, (byte)((value >> 24) & 0xff));
|
||||
Marshal.WriteByte(m_buffer, addr + 1, (byte)((value >> 16) & 0xff));
|
||||
Marshal.WriteByte(m_buffer, addr + 2, (byte)((value >> 8) & 0xff));
|
||||
Marshal.WriteByte(m_buffer, addr + 3, (byte)((value >> 0) & 0xff));
|
||||
}
|
||||
|
||||
public byte GetBuffer8(ushort addr)
|
||||
{
|
||||
return Marshal.ReadByte(m_buffer, addr);
|
||||
}
|
||||
|
||||
public ushort GetBuffer16(ushort addr)
|
||||
{
|
||||
ushort v = 0;
|
||||
|
||||
v |= (ushort)(Marshal.ReadByte(m_buffer, addr) << 8);
|
||||
v |= (ushort)(Marshal.ReadByte(m_buffer, addr + 1) << 0);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public uint GetBuffer24(ushort addr)
|
||||
{
|
||||
uint v = 0;
|
||||
|
||||
v |= (uint)(Marshal.ReadByte(m_buffer, addr) << 16);
|
||||
v |= (uint)(Marshal.ReadByte(m_buffer, addr + 1) << 8);
|
||||
v |= (uint)(Marshal.ReadByte(m_buffer, addr + 2) << 0);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public uint GetBuffer32(ushort addr)
|
||||
{
|
||||
uint v = 0;
|
||||
|
||||
v |= (uint)(Marshal.ReadByte(m_buffer, addr + 0) << 24);
|
||||
v |= (uint)(Marshal.ReadByte(m_buffer, addr + 1) << 16);
|
||||
v |= (uint)(Marshal.ReadByte(m_buffer, addr + 2) << 8);
|
||||
v |= (uint)(Marshal.ReadByte(m_buffer, addr + 3) << 0);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (m_buffer_size > 0 && m_delete_buffer)
|
||||
Marshal.FreeHGlobal(m_buffer);
|
||||
m_cdb = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
81
Bwg.Scsi/Defs.cs
Normal file
81
Bwg.Scsi/Defs.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
enum ScsiCommandCode
|
||||
{
|
||||
TestUnitReady = 0x00,
|
||||
RequestSense = 0x03,
|
||||
FormatUnit = 0x04,
|
||||
Inquiry = 0x12,
|
||||
StartStopUnit = 0x1B,
|
||||
PreventAllowMediumRemoval = 0x1E,
|
||||
ReadFormatCapacities = 0x23,
|
||||
ReadCapacity = 0x25,
|
||||
Read = 0x28,
|
||||
Seek = 0x2B,
|
||||
Write = 0x2A,
|
||||
Erase = 0x2C,
|
||||
WriteAndVerify = 0x2E,
|
||||
Verify = 0x2F,
|
||||
SyncronizeCache = 0x35,
|
||||
WriteBuffer = 0x3B,
|
||||
ReadBuffer = 0x3C,
|
||||
ReadSubChannel = 0x42,
|
||||
ReadTocPmaAtip = 0x43,
|
||||
PlayAudio10 = 0x45,
|
||||
GetConfiguration = 0x46,
|
||||
PlayAudioMSF = 0x47,
|
||||
GetEventStatusNotification = 0x4A,
|
||||
PauseResume = 0x4B,
|
||||
StopPlayScan = 0x4E,
|
||||
ReadDiskInformation = 0x51,
|
||||
ReadTrackInformation = 0x52,
|
||||
ReserveTrack = 0x53,
|
||||
SendOpcInformation = 0x54,
|
||||
ModeSelect = 0x55,
|
||||
RepairTrack = 0x58,
|
||||
ModeSense = 0x5A,
|
||||
CloseTrackSession = 0x5B,
|
||||
ReadBufferCapacity = 0x5C,
|
||||
SendCueSheet = 0x5D,
|
||||
Blank = 0xA1,
|
||||
SendKey = 0xA3,
|
||||
ReportKey = 0xA4,
|
||||
PlayAudio12 = 0xA5,
|
||||
LoadUnloadMedium = 0xA6,
|
||||
SetReadAhead = 0xA7,
|
||||
Read12 = 0xA8,
|
||||
Write12 = 0xAA,
|
||||
GetPerformance = 0xAC,
|
||||
ReadDvdStructure = 0xAD,
|
||||
SetStreaming = 0xB6,
|
||||
ReadCdMSF = 0xB9,
|
||||
Scan = 0xBA,
|
||||
SetCdSpeed = 0xBB,
|
||||
MechanismStatus = 0xBD,
|
||||
ReadCd = 0xBE,
|
||||
SendDvdStructure = 0xBF
|
||||
} ;
|
||||
}
|
||||
3686
Bwg.Scsi/Device.cs
Normal file
3686
Bwg.Scsi/Device.cs
Normal file
File diff suppressed because it is too large
Load Diff
160
Bwg.Scsi/DeviceInfo.cs
Normal file
160
Bwg.Scsi/DeviceInfo.cs
Normal file
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains information about a burner device that is useful to have
|
||||
/// even when the device it not open
|
||||
/// </summary>
|
||||
public class DeviceInfo
|
||||
{
|
||||
#region private member variables
|
||||
/// <summary>
|
||||
/// The device name for the device
|
||||
/// </summary>
|
||||
private string m_device_name;
|
||||
|
||||
/// <summary>
|
||||
/// The device latter for the device
|
||||
/// </summary>
|
||||
private string m_device_letter;
|
||||
|
||||
/// <summary>
|
||||
/// The result of an inquiry
|
||||
/// </summary>
|
||||
private InquiryResult m_inqury_result;
|
||||
|
||||
#endregion
|
||||
|
||||
#region static private member variables
|
||||
/// <summary>
|
||||
/// The list of devices found and created. For each device only a single DeviceInfo object
|
||||
/// will ever be created and this list holds the objects created to date
|
||||
/// </summary>
|
||||
private static IList<DeviceInfo> m_devices = new List<DeviceInfo>();
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// Create a new device info object given the device name and drive letter for the device
|
||||
/// </summary>
|
||||
/// <param name="name">the device name</param>
|
||||
/// <param name="letter">the drive letter</param>
|
||||
private DeviceInfo(string name, string letter)
|
||||
{
|
||||
m_device_name = name;
|
||||
m_device_letter = letter;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
/// <summary>
|
||||
/// This property returns the drive letter associated with the device
|
||||
/// </summary>
|
||||
public string DeviceLetter
|
||||
{
|
||||
get { return m_device_letter; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns the NT device name associated with the device
|
||||
/// </summary>
|
||||
public string DeviceName
|
||||
{
|
||||
get { return m_device_name; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns a short description of the drive including drive letter
|
||||
/// and NT device name.
|
||||
/// </summary>
|
||||
public string ShortDesc
|
||||
{
|
||||
get { return m_device_letter + " ( " + m_device_name + " )"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property return a long description of the drive including the drive letter,
|
||||
/// NT device name, vendor ID and product ID.
|
||||
/// </summary>
|
||||
public string LongDesc
|
||||
{
|
||||
get
|
||||
{
|
||||
string result = m_device_letter + " ";
|
||||
// result += " ( " + m_device_name + " ) ";
|
||||
result += "[" + m_inqury_result.VendorIdentification + " " +
|
||||
m_inqury_result.ProductIdentification + " " +
|
||||
m_inqury_result.FirmwareVersion + "]";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns the inquiry data from the inquiry request
|
||||
/// </summary>
|
||||
public InquiryResult InquiryData
|
||||
{
|
||||
get { return m_inqury_result; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
|
||||
/// <summary>
|
||||
/// This method returns a string representation of this object
|
||||
/// </summary>
|
||||
/// <returns>string representatation of the object</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return m_device_letter + " (" + m_inqury_result.VendorIdentification.Trim() + " " + m_inqury_result.ProductIdentification.Trim() + ")";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract the information we want to keep around after we close the device.
|
||||
/// </summary>
|
||||
/// <param name="dev">the open device we are going to query</param>
|
||||
/// <returns>true if we got the info, false otherwise</returns>
|
||||
public bool ExtractInfo(Device dev)
|
||||
{
|
||||
if (dev.Inquiry(out m_inqury_result) != Device.CommandStatus.Success)
|
||||
return false;
|
||||
|
||||
if (!m_inqury_result.Valid)
|
||||
return false;
|
||||
|
||||
if (m_inqury_result.PeripheralQualifier != 0)
|
||||
return false;
|
||||
|
||||
if (m_inqury_result.PeripheralDeviceType != Device.MMCDeviceType)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public static methods
|
||||
/// <summary>
|
||||
/// This method returns or creates a unique device info structure based on the name and the
|
||||
/// drive letter for a given drive.
|
||||
/// </summary>
|
||||
/// <param name="name">the NT name of the drive</param>
|
||||
/// <param name="letter">the drive letter for the drive</param>
|
||||
/// <returns>the single DeviceInfo object that represents this drive</returns>
|
||||
public static DeviceInfo CreateDevice(string name, string letter)
|
||||
{
|
||||
foreach (DeviceInfo info in m_devices)
|
||||
{
|
||||
if (info.DeviceName == name && info.DeviceLetter == letter)
|
||||
return info;
|
||||
}
|
||||
|
||||
DeviceInfo newdev = new DeviceInfo(name, letter);
|
||||
m_devices.Add(newdev);
|
||||
return newdev;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
228
Bwg.Scsi/DeviceManager.cs
Normal file
228
Bwg.Scsi/DeviceManager.cs
Normal file
@@ -0,0 +1,228 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices ;
|
||||
using System.IO;
|
||||
using Bwg.Logging;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class manages the burner devices that are in the system.
|
||||
/// </summary>
|
||||
public unsafe class DeviceManager
|
||||
{
|
||||
#region external functions
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
private static extern uint QueryDosDevice(string name, IntPtr buffer, uint size);
|
||||
#endregion
|
||||
|
||||
#region private member variables
|
||||
|
||||
/// <summary>
|
||||
/// The logger for logging messages
|
||||
/// </summary>
|
||||
private Logger m_logger;
|
||||
|
||||
/// <summary>
|
||||
/// This list contains the device names found in the system
|
||||
/// </summary>
|
||||
private IList<DeviceInfo> m_devices_found;
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// This constructor creates a new device manager object.
|
||||
/// </summary>
|
||||
/// <param name="l">the logger to use for logging messages</param>
|
||||
public DeviceManager(Logger l)
|
||||
{
|
||||
m_logger = l;
|
||||
m_devices_found = new List<DeviceInfo>();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public variables
|
||||
/// <summary>
|
||||
/// This event is fired just before a rescan of the devices in the system.
|
||||
/// </summary>
|
||||
public EventHandler<DeviceManagerRescanArgs> BeforeScan;
|
||||
|
||||
/// <summary>
|
||||
/// This event is triggered just after a rescan of devices in the system.
|
||||
/// </summary>
|
||||
public EventHandler<DeviceManagerRescanArgs> AfterScan;
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
/// <summary>
|
||||
/// This property returns the list of devices found as a result of the most recent
|
||||
/// scan.
|
||||
/// </summary>
|
||||
public IList<DeviceInfo> DevicesFound
|
||||
{
|
||||
get { return m_devices_found; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns the logger assocaited with the device manager
|
||||
/// </summary>
|
||||
public Logger MyLogger
|
||||
{
|
||||
get { return m_logger; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
/// <summary>
|
||||
/// This method scans the current machine for all CDROM devices found in the system.
|
||||
/// </summary>
|
||||
public void ScanForDevices()
|
||||
{
|
||||
if (BeforeScan != null)
|
||||
{
|
||||
DeviceManagerRescanArgs args = new DeviceManagerRescanArgs();
|
||||
BeforeScan(this, args);
|
||||
}
|
||||
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 0, "Scanning for devices ... ")) ;
|
||||
|
||||
OperatingSystem os = Environment.OSVersion;
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Info, 0, "Operating System: " + os.ToString()));
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Info, 0, "Platform: " + os.Platform.ToString()));
|
||||
|
||||
int ossize = 32 ;
|
||||
if (IntPtr.Size == 8)
|
||||
ossize = 64 ;
|
||||
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 0, "OS Word Size: " + ossize.ToString())) ;
|
||||
|
||||
m_devices_found.Clear();
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
uint dlev = (uint)((i > 5) ? 9 : 8);
|
||||
string name = "\\\\.\\CDROM" + i.ToString();
|
||||
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, dlev, "Checking device " + name + " ... "));
|
||||
|
||||
Device dev = new Device(m_logger) ;
|
||||
if (!dev.Open(name))
|
||||
{
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, dlev, " ... device open failed"));
|
||||
continue ;
|
||||
}
|
||||
|
||||
string letter = GetLetterFromDeviceName(name);
|
||||
|
||||
DeviceInfo info = DeviceInfo.CreateDevice(name, letter);
|
||||
if (!info.ExtractInfo(dev))
|
||||
{
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, dlev, " ... cannot extract inquiry information from the drive"));
|
||||
|
||||
string str = "The drive '" + letter + "' (" + name + ") is a CD/DVD driver, but is not a valid MMC device.";
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Error, 0, str));
|
||||
str = "This drive is not supported by BwgBurn and is probably an older device.";
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Error, 0, str));
|
||||
continue;
|
||||
}
|
||||
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, dlev, " ... device added to device list"));
|
||||
m_devices_found.Add(info) ;
|
||||
dev.Close() ;
|
||||
}
|
||||
|
||||
if (AfterScan != null)
|
||||
{
|
||||
DeviceManagerRescanArgs args = new DeviceManagerRescanArgs();
|
||||
AfterScan(this, args);
|
||||
}
|
||||
|
||||
string devlist = string.Empty;
|
||||
foreach (DeviceInfo info in m_devices_found)
|
||||
{
|
||||
if (devlist.Length > 0)
|
||||
devlist += ", ";
|
||||
devlist += info.ShortDesc;
|
||||
}
|
||||
m_logger.LogMessage(new UserMessage(UserMessage.Category.Debug, 0, "Found devices ... " + devlist));
|
||||
|
||||
foreach (DeviceInfo info in m_devices_found)
|
||||
{
|
||||
UserMessage m = new UserMessage(UserMessage.Category.Debug, 6, "Found Device: " + info.DeviceLetter) ;
|
||||
m_logger.LogMessage(m);
|
||||
|
||||
m = new UserMessage(UserMessage.Category.Debug, 6, " NT Name = " + info.DeviceName);
|
||||
m_logger.LogMessage(m);
|
||||
|
||||
m = new UserMessage(UserMessage.Category.Debug, 6, " Vendor = " + info.InquiryData.VendorIdentification.Trim());
|
||||
m_logger.LogMessage(m);
|
||||
|
||||
m = new UserMessage(UserMessage.Category.Debug, 6, " Product = " + info.InquiryData.ProductIdentification.Trim());
|
||||
m_logger.LogMessage(m);
|
||||
|
||||
m = new UserMessage(UserMessage.Category.Debug, 6, " Revision = " + info.InquiryData.ProductRevision.Trim());
|
||||
m_logger.LogMessage(m);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private methods
|
||||
|
||||
private static string GetNtDeviceNameForDrive(string name)
|
||||
{
|
||||
string result;
|
||||
const int buflen = 512;
|
||||
uint ret;
|
||||
byte[] buffer = new byte[buflen];
|
||||
|
||||
if (name.EndsWith("\\"))
|
||||
name = name.Substring(0, name.Length - 1);
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(buflen);
|
||||
{
|
||||
ret = QueryDosDevice(name, ptr, buflen / 2);
|
||||
Marshal.Copy(ptr, buffer, 0, buflen);
|
||||
|
||||
int totallen = buflen;
|
||||
for (int i = 0; i < buflen - 2; i++)
|
||||
{
|
||||
if (buffer[i] == 0 && buffer[i + 1] == 0)
|
||||
{
|
||||
totallen = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = Encoding.Unicode.GetString(buffer, 0, totallen);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the drive letter for a drive given its NT name
|
||||
/// </summary>
|
||||
/// <param name="devname">the NT name</param>
|
||||
/// <returns>the drive letter</returns>
|
||||
public static string GetLetterFromDeviceName(string devname)
|
||||
{
|
||||
if (devname.StartsWith("\\\\.\\"))
|
||||
devname = devname.Substring(4);
|
||||
|
||||
foreach (DriveInfo info in DriveInfo.GetDrives())
|
||||
{
|
||||
if (info.DriveType == DriveType.CDRom)
|
||||
{
|
||||
string ntname = GetNtDeviceNameForDrive(info.Name);
|
||||
if (ntname.StartsWith("\\Device\\"))
|
||||
ntname = ntname.Substring(8);
|
||||
|
||||
if (ntname.ToLower() == devname.ToLower())
|
||||
return info.Name;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
14
Bwg.Scsi/DeviceManagerRescanArgs.cs
Normal file
14
Bwg.Scsi/DeviceManagerRescanArgs.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents the arguments to the scan event in the
|
||||
/// device manager.
|
||||
/// </summary>
|
||||
public class DeviceManagerRescanArgs : EventArgs
|
||||
{
|
||||
}
|
||||
}
|
||||
409
Bwg.Scsi/DiskInformation.cs
Normal file
409
Bwg.Scsi/DiskInformation.cs
Normal file
@@ -0,0 +1,409 @@
|
||||
//
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains the results of the ReadDiskInformation SCSI command
|
||||
/// </summary>
|
||||
public class DiskInformation : Result
|
||||
{
|
||||
#region Public types
|
||||
/// <summary>
|
||||
/// Type defining the state of the last session on the disk
|
||||
/// </summary>
|
||||
public enum SessionStateType
|
||||
{
|
||||
/// <summary>
|
||||
/// The session is empty
|
||||
/// </summary>
|
||||
EmptySession = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The session is incomplete
|
||||
/// </summary>
|
||||
IncompleteSession = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The session is damaged
|
||||
/// </summary>
|
||||
DamagedSession = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The session is complete
|
||||
/// </summary>
|
||||
CompleteSession = 3
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
/// Type defining the status of the disk
|
||||
/// </summary>
|
||||
public enum DiskStatusType
|
||||
{
|
||||
/// <summary>
|
||||
/// The disk is empty
|
||||
/// </summary>
|
||||
EmptyDisk = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The disk is incomplete
|
||||
/// </summary>
|
||||
IncompleteDisk = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The disk is finalized
|
||||
/// </summary>
|
||||
FinalizedDisk = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The disk is in an other state which is dependent on the media type
|
||||
/// </summary>
|
||||
RandomlyRecordable = 3
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
/// The state of a background format
|
||||
/// </summary>
|
||||
public enum BackgroundFormatStatusType
|
||||
{
|
||||
/// <summary>
|
||||
/// No background format was started, or it does not apply
|
||||
/// </summary>
|
||||
NotStartedOrDoesNotApply = 0,
|
||||
|
||||
/// <summary>
|
||||
/// A background format was started, did not complete, and is not running
|
||||
/// </summary>
|
||||
StartedButNotRunning = 1,
|
||||
|
||||
/// <summary>
|
||||
/// A background format is in progress and is not complete
|
||||
/// </summary>
|
||||
InProgress = 2,
|
||||
|
||||
/// <summary>
|
||||
/// A background format was started and is complete
|
||||
/// </summary>
|
||||
Complete = 3
|
||||
} ;
|
||||
#endregion
|
||||
|
||||
#region Public Data Members
|
||||
|
||||
private readonly bool m_erasable;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the disk is erasable. If false the disk cannot be erased
|
||||
/// </summary>
|
||||
public bool Erasable
|
||||
{
|
||||
get { return m_erasable; }
|
||||
}
|
||||
|
||||
private readonly SessionStateType m_session_state;
|
||||
|
||||
/// <summary>
|
||||
/// The state of the last session on the disk
|
||||
/// </summary>
|
||||
public SessionStateType SessionState
|
||||
{
|
||||
get { return m_session_state; }
|
||||
}
|
||||
|
||||
private readonly DiskStatusType m_disk_status;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The status of the disk
|
||||
/// </summary>
|
||||
public DiskStatusType DiskStatus
|
||||
{
|
||||
get { return m_disk_status; }
|
||||
}
|
||||
|
||||
|
||||
private readonly byte m_first_track;
|
||||
|
||||
/// <summary>
|
||||
/// Number of the first track on the disk
|
||||
/// </summary>
|
||||
public byte FirstTrack
|
||||
{
|
||||
get { return m_first_track; }
|
||||
}
|
||||
|
||||
|
||||
private readonly ushort m_session_count;
|
||||
|
||||
/// <summary>
|
||||
/// Number of sessions on the disk
|
||||
/// </summary>
|
||||
public ushort SessionCount
|
||||
{
|
||||
get { return m_session_count; }
|
||||
}
|
||||
|
||||
|
||||
private readonly ushort m_first_track_in_last_session;
|
||||
|
||||
/// <summary>
|
||||
/// The first track number in the last session
|
||||
/// </summary>
|
||||
public ushort FirstTrackInLastSession
|
||||
{
|
||||
get { return m_first_track_in_last_session; }
|
||||
}
|
||||
|
||||
|
||||
private readonly ushort m_last_track_in_last_session;
|
||||
|
||||
/// <summary>
|
||||
/// The last track number in the last session
|
||||
/// </summary>
|
||||
public ushort LastTrackInLastSession
|
||||
{
|
||||
get { return m_last_track_in_last_session; }
|
||||
}
|
||||
|
||||
|
||||
private readonly bool m_disk_id_valid;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the disk ID was valid
|
||||
/// </summary>
|
||||
public bool DiskIdValid
|
||||
{
|
||||
get { return m_disk_id_valid; }
|
||||
}
|
||||
|
||||
|
||||
private readonly uint m_disk_identification;
|
||||
|
||||
/// <summary>
|
||||
/// The four byte disk id
|
||||
/// </summary>
|
||||
public uint DiskIdentification
|
||||
{
|
||||
get { return m_disk_identification; }
|
||||
}
|
||||
|
||||
|
||||
private readonly bool m_disk_bar_code_valid;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the disk bar code was valid
|
||||
/// </summary>
|
||||
public bool DiskBarCodeValid
|
||||
{
|
||||
get { return m_disk_bar_code_valid; }
|
||||
}
|
||||
|
||||
|
||||
private readonly byte[] m_disk_bar_code;
|
||||
|
||||
/// <summary>
|
||||
/// The eight byte disk bar code
|
||||
/// </summary>
|
||||
public byte[] DiskBarCode
|
||||
{
|
||||
get { return m_disk_bar_code; }
|
||||
}
|
||||
|
||||
|
||||
private readonly bool m_unrestricted_disk_use;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this disk is unrestriced it its use
|
||||
/// </summary>
|
||||
public bool UnrestrictedDiskUse
|
||||
{
|
||||
get { return m_unrestricted_disk_use; }
|
||||
}
|
||||
|
||||
|
||||
private readonly bool m_disk_application_code_valid;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the disk application code is valid
|
||||
/// </summary>
|
||||
public bool DiskApplicationCodeValid
|
||||
{
|
||||
get { return m_disk_application_code_valid; }
|
||||
}
|
||||
|
||||
|
||||
private readonly byte m_disk_application_code;
|
||||
|
||||
/// <summary>
|
||||
/// The disk application code
|
||||
/// </summary>
|
||||
public byte DiskApplicationCode
|
||||
{
|
||||
get { return m_disk_application_code; }
|
||||
}
|
||||
|
||||
|
||||
private readonly bool m_dirty_bit;
|
||||
|
||||
/// <summary>
|
||||
/// The Dbit (dirty bit) for MRW media
|
||||
/// </summary>
|
||||
public bool DirtyBit
|
||||
{
|
||||
get { return m_dirty_bit; }
|
||||
}
|
||||
|
||||
|
||||
private readonly BackgroundFormatStatusType m_background_format_status;
|
||||
|
||||
/// <summary>
|
||||
/// The status of a background format
|
||||
/// </summary>
|
||||
public BackgroundFormatStatusType BackgroundFormatStatus
|
||||
{
|
||||
get { return m_background_format_status; }
|
||||
}
|
||||
|
||||
|
||||
private readonly MinuteSecondFrame m_last_session_lead_in_start_address;
|
||||
|
||||
/// <summary>
|
||||
/// The last session leadin start address, media dependent, see SCSI-3 MMC spec
|
||||
/// </summary>
|
||||
public MinuteSecondFrame LastSessionLeadInStartAddress
|
||||
{
|
||||
get { return m_last_session_lead_in_start_address; }
|
||||
}
|
||||
|
||||
|
||||
private readonly MinuteSecondFrame m_last_possible_leadout_start_address;
|
||||
|
||||
/// <summary>
|
||||
/// The last possible leadout start address, media dependent, see SCSI-3 MMC spec
|
||||
/// </summary>
|
||||
public MinuteSecondFrame LastPossibleLeadoutStartAddress
|
||||
{
|
||||
get { return m_last_possible_leadout_start_address; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The OPC table
|
||||
/// </summary>
|
||||
public IList<OpcTableEntry> OpcTable;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// The constructor for the DiskInformation class. It parses the information from the
|
||||
/// memory buffer that contains the raw SCSI result.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The buffer containing the raw SCSI result</param>
|
||||
/// <param name="size">The size of the raw SCSI result buffer</param>
|
||||
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<OpcTableEntry>();
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
171
Bwg.Scsi/EventStatusNotification.cs
Normal file
171
Bwg.Scsi/EventStatusNotification.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
//
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains information about event status communicated from the device
|
||||
/// via the GetEventStatusNotification SCSI command.
|
||||
/// </summary>
|
||||
public class EventStatusNotification : Result
|
||||
{
|
||||
#region public types
|
||||
|
||||
/// <summary>
|
||||
/// This field indicates the type of event
|
||||
/// </summary>
|
||||
public enum EventType
|
||||
{
|
||||
/// <summary>
|
||||
/// No event was returned
|
||||
/// </summary>
|
||||
NoEvent = 0x00,
|
||||
|
||||
/// <summary>
|
||||
/// There was an operation change
|
||||
/// </summary>
|
||||
OperationalChange = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// There was a change in power management status
|
||||
/// </summary>
|
||||
PowerManagement = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// There was an external request to the device
|
||||
/// </summary>
|
||||
ExternalRequest = 0x03,
|
||||
|
||||
/// <summary>
|
||||
/// The status of the media has changed
|
||||
/// </summary>
|
||||
Media = 0x04,
|
||||
|
||||
/// <summary>
|
||||
/// There was a change in the multiple initiator device
|
||||
/// </summary>
|
||||
MultipleInitiator = 0x05,
|
||||
|
||||
/// <summary>
|
||||
/// There was a change in the busy state of the device
|
||||
/// </summary>
|
||||
DeviceBusy = 0x06,
|
||||
|
||||
/// <summary>
|
||||
/// This value is reserved and should not be returned
|
||||
/// </summary>
|
||||
Reserved = 0x07,
|
||||
} ;
|
||||
#endregion
|
||||
|
||||
#region public member variables
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if an event is available
|
||||
/// </summary>
|
||||
public readonly bool EventAvailable;
|
||||
|
||||
/// <summary>
|
||||
/// This property is a byte that contains a mask of the supported event classes
|
||||
/// </summary>
|
||||
public readonly byte SupportedEventClasses;
|
||||
|
||||
/// <summary>
|
||||
/// This property contains the notification class of the specific event that has
|
||||
/// occurred.
|
||||
/// </summary>
|
||||
public readonly EventType NotificationClass;
|
||||
|
||||
/// <summary>
|
||||
/// This array contains the specific data returned describing the event. The format of this
|
||||
/// data is described in the SCSI-3 MMC specification.
|
||||
/// </summary>
|
||||
public readonly byte [] EventData;
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// This is the contructor for this class which contains information about any events that
|
||||
/// have occurred in the SCSI device.
|
||||
/// </summary>
|
||||
/// <param name="buffer">Pointer to a memory area containing the reply from the SCSI device</param>
|
||||
/// <param name="size">The size of the memory area containing the reply from the SCSI device</param>
|
||||
public EventStatusNotification(IntPtr buffer, int size) : base(buffer, size)
|
||||
{
|
||||
SupportedEventClasses = Marshal.ReadByte(buffer, 3);
|
||||
|
||||
byte b = Marshal.ReadByte(buffer, 2);
|
||||
if ((b & 0x80) != 0)
|
||||
{
|
||||
EventAvailable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ushort len = Get16(0);
|
||||
EventAvailable = true;
|
||||
NotificationClass = (EventType)(b & 0x03);
|
||||
EventData = new byte[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
EventData[i] = Marshal.ReadByte(buffer, 4 + i);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
/// <summary>
|
||||
/// This property returns true if Operational Events are supported on this device
|
||||
/// </summary>
|
||||
public bool OperationalChangeEventsSupported { get { return (SupportedEventClasses & 0x02) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if Power Management Events are supported on this device
|
||||
/// </summary>
|
||||
public bool PowerManagementEventsSupported { get { return (SupportedEventClasses & 0x04) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if External Request Events are supported on this device
|
||||
/// </summary>
|
||||
public bool ExternalRequestEventsSupported { get { return (SupportedEventClasses & 0x08) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if Media Events are supported on this device
|
||||
/// </summary>
|
||||
public bool MediaEventsSupported { get { return (SupportedEventClasses & 0x10) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if Multiple Initiator Events are supported on this device
|
||||
/// </summary>
|
||||
public bool MultiInitiatorEventsSupported { get { return (SupportedEventClasses & 0x20) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if Device Busy Events are supported on this device
|
||||
/// </summary>
|
||||
public bool DeviceBusyEventsSupported { get { return (SupportedEventClasses & 0x40) != 0; } }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
438
Bwg.Scsi/Feature.cs
Normal file
438
Bwg.Scsi/Feature.cs
Normal file
@@ -0,0 +1,438 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class describes a single SCSI feature. The data associated with the feature is
|
||||
/// stored as a series of bytes that must be interpreted by the calling code.
|
||||
/// </summary>
|
||||
public class Feature : Result
|
||||
{
|
||||
#region Feature Numbers
|
||||
/// <summary>
|
||||
/// This enumerated type indicates the type of the feature.
|
||||
/// </summary>
|
||||
public enum FeatureType : ushort
|
||||
{
|
||||
/// <summary>
|
||||
/// The ProfileList feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
ProfileList = 0x0000,
|
||||
|
||||
/// <summary>
|
||||
/// The Core feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
Core = 0x0001,
|
||||
|
||||
/// <summary>
|
||||
/// The Morphing feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
Morphing = 0x0002,
|
||||
|
||||
/// <summary>
|
||||
/// The RemovableMedia feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
RemovableMedia = 0x0003,
|
||||
|
||||
/// <summary>
|
||||
/// The WriteProtect feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
WriteProtect = 0x0004,
|
||||
|
||||
/// <summary>
|
||||
/// The RandomReadable feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
RandomReadable = 0x0010,
|
||||
|
||||
/// <summary>
|
||||
/// The MultiRead feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
MultiRead = 0x001d,
|
||||
|
||||
/// <summary>
|
||||
/// The CDRead feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
CDRead = 0x001e,
|
||||
|
||||
/// <summary>
|
||||
/// The DVDRead feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
DVDRead = 0x001f,
|
||||
|
||||
/// <summary>
|
||||
/// The RandomWritable feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
RandomWritable = 0x0020,
|
||||
|
||||
/// <summary>
|
||||
/// The IncrementalStreamWritable feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
IncrementalStreamWritable = 0x0021,
|
||||
|
||||
/// <summary>
|
||||
/// The SectorErasable feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
SectorErasable = 0x0022,
|
||||
|
||||
/// <summary>
|
||||
/// The Formattable feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
Formattable = 0x0023,
|
||||
|
||||
/// <summary>
|
||||
/// The HardwareDefectManagement feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
HardwareDefectManagement = 0x0024,
|
||||
|
||||
/// <summary>
|
||||
/// The WriteOnce feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
WriteOnce = 0x0025,
|
||||
|
||||
/// <summary>
|
||||
/// The RestrictedOverwrite feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
RestrictedOverwrite = 0x0026,
|
||||
|
||||
/// <summary>
|
||||
/// The CDRWCavWrite feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
CDRWCavWrite = 0x0027,
|
||||
|
||||
/// <summary>
|
||||
/// The MRW feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
MRW = 0x0028,
|
||||
|
||||
/// <summary>
|
||||
/// The EnhancedDefectReporting feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
EnhancedDefectReporting = 0x0029,
|
||||
|
||||
/// <summary>
|
||||
/// The DVDPlusRW feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
DVDPlusRW = 0x002a,
|
||||
|
||||
/// <summary>
|
||||
/// The DVDPlusR feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
DVDPlusR = 0x002b,
|
||||
|
||||
/// <summary>
|
||||
/// The RigidRestrictedOverwrite feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
RigidRestrictedOverwrite = 0x002c,
|
||||
|
||||
/// <summary>
|
||||
/// The CDTrackAtOnce feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
CDTrackAtOnce = 0x002d,
|
||||
|
||||
/// <summary>
|
||||
/// The CDSessionAtOnce feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
CDSessionAtOnce = 0x002e,
|
||||
|
||||
/// <summary>
|
||||
/// The DVDMinusR_DVDMinusRW feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
DVDMinusR_DVDMinusRW = 0x002f,
|
||||
|
||||
/// <summary>
|
||||
/// The DDCDRead feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
DDCDRead = 0x0030,
|
||||
|
||||
/// <summary>
|
||||
/// The DDCDMinusR feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
DDCDMinusR = 0x0031,
|
||||
|
||||
/// <summary>
|
||||
/// The DDCDMinusRW feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
DDCDMinusRW = 0x0032,
|
||||
|
||||
/// <summary>
|
||||
/// The layer jump recording feature (see the SCSI MMC-5 specification)
|
||||
/// </summary>
|
||||
LayerJumpRecording = 0x0033,
|
||||
|
||||
/// <summary>
|
||||
/// The CDRWMediaWriteSupport feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
CDRWMediaWriteSupport = 0x0037,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
BD_RPseudoOverWrite = 0x0038,
|
||||
|
||||
/// <summary>
|
||||
/// The dual layer feature for DVD+RW
|
||||
/// </summary>
|
||||
DvdPlusRWDualLayer = 0x003a,
|
||||
|
||||
/// <summary>
|
||||
/// The dual layer featuer for DVD+R
|
||||
/// </summary>
|
||||
DvdPlusRDualLayer = 0x003b,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
BDRead = 0x0040,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
BDWrite = 0x0041,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
TSR = 0x0042,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
HdDvdRead = 0x0050,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
HdDvdWrite = 0x0051,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
OldHybridDisk = 0x0052,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
HybridDisk = 0x0080,
|
||||
|
||||
/// <summary>
|
||||
/// The PowerMangaementFeature feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
PowerMangaementFeature = 0x0100,
|
||||
|
||||
/// <summary>
|
||||
/// The S_M_A_R_T feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
S_M_A_R_T = 0x0101,
|
||||
|
||||
/// <summary>
|
||||
/// The EmbeddedChanger feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
EmbeddedChanger = 0x0102,
|
||||
|
||||
/// <summary>
|
||||
/// The CDAudioExternalPlay feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
CDAudioExternalPlay = 0x0103,
|
||||
|
||||
/// <summary>
|
||||
/// The MicrocodeUpgrade feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
MicrocodeUpgrade = 0x0104,
|
||||
|
||||
/// <summary>
|
||||
/// The Timeout feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
Timeout = 0x0105,
|
||||
|
||||
/// <summary>
|
||||
/// The DVDCSS feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
DVDCSS = 0x0106,
|
||||
|
||||
/// <summary>
|
||||
/// The RealTimeStreaming feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
RealTimeStreaming = 0x0107,
|
||||
|
||||
/// <summary>
|
||||
/// The LogicalUnitSerialNumber feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
LogicalUnitSerialNumber = 0x0108,
|
||||
|
||||
/// <summary>
|
||||
/// The MediaSerialNumber feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
MediaSerialNumber = 0x0109,
|
||||
|
||||
/// <summary>
|
||||
/// The DiskControlBlock feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
DiskControlBlock = 0x010A,
|
||||
|
||||
/// <summary>
|
||||
/// The DVD_CPRM feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
DVD_CPRM = 0x010B,
|
||||
|
||||
/// <summary>
|
||||
/// The FirmwareInformation feature (see the SCSI-3 MMC specification)
|
||||
/// </summary>
|
||||
FirmwareInformation = 0x010C,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
AACS = 0x010d,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
VCPS = 0x0110
|
||||
} ;
|
||||
#endregion
|
||||
|
||||
#region private variables
|
||||
|
||||
/// <summary>
|
||||
/// The feature code for this feature
|
||||
/// </summary>
|
||||
private FeatureType m_code;
|
||||
|
||||
/// <summary>
|
||||
/// The verion for this feature
|
||||
/// </summary>
|
||||
private byte m_version;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this feature is persistent (see SCSI MMC spec for more details)
|
||||
/// </summary>
|
||||
private bool m_persistent;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this feature is current (see SCSI MMC spec for more details)
|
||||
/// </summary>
|
||||
private bool m_current;
|
||||
|
||||
/// <summary>
|
||||
/// The raw data assocaited with the feature. This data may be invalid if the
|
||||
/// feature is invalid.
|
||||
/// </summary>
|
||||
private byte[] m_data;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// This is a constructor for the SCSI feature. It takes data from a raw buffer and
|
||||
/// creates the SCSI featuer object
|
||||
/// </summary>
|
||||
/// <param name="buffer">Pointer to the start of the raw reply buffer</param>
|
||||
/// <param name="size">Size of the raw reply buffer</param>
|
||||
/// <param name="offset">The offset to start parsing a SCSI feature from the reply buffer</param>
|
||||
public Feature(IntPtr buffer, int size, ref int offset) : base(buffer, size)
|
||||
{
|
||||
m_code = (FeatureType)Get16(offset);
|
||||
offset += 2;
|
||||
|
||||
byte b = Get8(offset);
|
||||
offset++;
|
||||
|
||||
if ((b & 0x01) != 0)
|
||||
m_current = true;
|
||||
else
|
||||
m_current = false;
|
||||
|
||||
if ((b & 0x02) != 0)
|
||||
m_persistent = true;
|
||||
else
|
||||
m_persistent = false;
|
||||
|
||||
m_version = (byte)((b >> 2) & 0x0f);
|
||||
|
||||
byte len = Get8(offset);
|
||||
offset++;
|
||||
|
||||
m_data = new byte[len];
|
||||
for(int i = 0 ; i < len && offset < BufferSize ; i++)
|
||||
{
|
||||
m_data[i] = Get8(offset);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
/// <summary>
|
||||
/// Return a string representing a human readable form of this object.
|
||||
/// </summary>
|
||||
/// <returns>string representing this object</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "Feature(type=" + m_code.ToString() + ")";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public propreties
|
||||
/// <summary>
|
||||
/// Return the code associated with this feature
|
||||
/// </summary>
|
||||
public FeatureType Code { get { return m_code; } }
|
||||
|
||||
/// <summary>
|
||||
/// Return the version of the current feature
|
||||
/// </summary>
|
||||
public byte Version { get { return m_version; } }
|
||||
|
||||
/// <summary>
|
||||
/// Return the presistence state of the feature. If true, this feature is persistant
|
||||
/// </summary>
|
||||
public bool Persistent { get { return m_persistent; } }
|
||||
|
||||
/// <summary>
|
||||
/// Return the current flag associated with the feature. If true, this feature is currently active.
|
||||
/// </summary>
|
||||
public bool Current { get { return m_current; } }
|
||||
|
||||
/// <summary>
|
||||
/// This item contains the data from the feature
|
||||
/// </summary>
|
||||
public byte[] Data { get { return m_data; } }
|
||||
|
||||
/// <summary>
|
||||
/// This property returns the name of the feature.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_code.ToString();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
64
Bwg.Scsi/FeatureList.cs
Normal file
64
Bwg.Scsi/FeatureList.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a list of features returned from the SCSI device.
|
||||
/// </summary>
|
||||
public class FeatureList : Result
|
||||
{
|
||||
/// <summary>
|
||||
/// The profile associated with this feature list.
|
||||
/// </summary>
|
||||
public readonly ushort Profile;
|
||||
|
||||
/// <summary>
|
||||
/// The list of features returned from the device
|
||||
/// </summary>
|
||||
public readonly IList<Feature> Features;
|
||||
|
||||
/// <summary>
|
||||
/// The constructure for the ScsiFeatureList object
|
||||
/// </summary>
|
||||
/// <param name="buffer">The pointer to the memory area containing the SCSI reply</param>
|
||||
/// <param name="size">The size of the SCSI reply</param>
|
||||
public FeatureList(IntPtr buffer, int size) : base(buffer, size)
|
||||
{
|
||||
Profile = Get16(6);
|
||||
Features = new List<Feature>() ;
|
||||
|
||||
uint len = Get32(0);
|
||||
int offset = 8;
|
||||
while (offset < len + 8 && offset < size)
|
||||
{
|
||||
Feature f = new Feature(buffer, size, ref offset);
|
||||
Features.Add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
142
Bwg.Scsi/FileReader.cs
Normal file
142
Bwg.Scsi/FileReader.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
//using Bwg.Utils;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class reads data from a file and sends this data to the buffered
|
||||
/// write stream.
|
||||
/// </summary>
|
||||
public unsafe class FileReader
|
||||
{
|
||||
#region private member variables
|
||||
/// <summary>
|
||||
/// The OS file for reading data from a file into a memory buffer (IntPtr)
|
||||
/// </summary>
|
||||
private OsFileReader m_reader;
|
||||
|
||||
/// <summary>
|
||||
/// The buffer pool to receive the data
|
||||
/// </summary>
|
||||
private WriteBufferPool m_buffer_stream;
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a new file reader that sends the data read to a buffer stream
|
||||
/// object
|
||||
/// </summary>
|
||||
/// <param name="buffer">the buffer to receive the data</param>
|
||||
public FileReader(WriteBufferPool buffer)
|
||||
{
|
||||
m_buffer_stream = buffer;
|
||||
m_reader = new OsFileReader();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open a file to read data from
|
||||
/// </summary>
|
||||
/// <param name="filename">the name of the file</param>
|
||||
/// <returns>true if the file is opened, false otherwise</returns>
|
||||
public bool Open(string filename)
|
||||
{
|
||||
return m_reader.Open(filename);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method closes an open file.
|
||||
/// </summary>
|
||||
/// <returns>true if the file is closed sucessfully, false otherwise</returns>
|
||||
public bool Close()
|
||||
{
|
||||
return m_reader.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function reads data from the file and sends it to the
|
||||
/// buffer stream to be sent to the burner. This function does not
|
||||
/// return until all of the data from the file is read.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ReadData(int sector_size, long lba)
|
||||
{
|
||||
bool shortbuf = false;
|
||||
int NumberRead ;
|
||||
int num_sectors ;
|
||||
bool first = true;
|
||||
|
||||
// This is the number of whole sectors that will fit into the buffer.
|
||||
num_sectors = m_buffer_stream.PageSize / sector_size;
|
||||
|
||||
while (true)
|
||||
{
|
||||
WriteBuffer buf ;
|
||||
|
||||
buf = m_buffer_stream.GetFreeBuffer();
|
||||
if (!m_reader.ReadData(buf.BufferPtr, num_sectors * sector_size, out NumberRead))
|
||||
return false ;
|
||||
|
||||
// If the read succeeded, but read zero bytes, we have reached the
|
||||
// end of the file.
|
||||
if (NumberRead == 0)
|
||||
return true;
|
||||
|
||||
if (shortbuf)
|
||||
throw new Exception("read two short packets");
|
||||
|
||||
// Mark the buffer with the amount of data that has
|
||||
// been read from the file
|
||||
int sectors = NumberRead / sector_size ;
|
||||
if ((NumberRead % sector_size) != 0)
|
||||
{
|
||||
shortbuf = true;
|
||||
sectors++;
|
||||
}
|
||||
|
||||
if (first)
|
||||
{
|
||||
buf.SourceString = "First block from FileReader";
|
||||
buf.LogicalBlockAddress = lba;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.SourceString = "Not first block from FileReader";
|
||||
buf.LogicalBlockAddress = long.MaxValue;
|
||||
}
|
||||
|
||||
buf.SectorSize = sector_size;
|
||||
buf.DataSize = sectors;
|
||||
|
||||
// Send the buffer to the device
|
||||
m_buffer_stream.SendBufferToDevice(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
343
Bwg.Scsi/FormatParameterList.cs
Normal file
343
Bwg.Scsi/FormatParameterList.cs
Normal file
@@ -0,0 +1,343 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents the list of format parameters that are presented to
|
||||
/// the device when performing a FormatUnit() operation.
|
||||
/// </summary>
|
||||
public class FormatParameterList
|
||||
{
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
public enum UnitFormatType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
FullFormat = 0,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
SpareAreaExpansion = 1,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
ZoneReformat = 4,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
ZoneFormat = 5,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
CD_DVD_RW_FullFormat = 0x10,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
CD_DVD_RW_GrowSession = 0x11,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
CD_DVD_RW_AddSession = 0x12,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
DVD_RW_QuickGrowLastSession = 0x13,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
DVD_RW_QuickAddSession = 0x14,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
DVD_RW_QuickFormat = 0x15,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
MRW_FullFormat = 0x24, // CD-RW NumberOfBlocks = 0xffffffff
|
||||
// DVD+RW NumberOfBlocks = 0xffffffff
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
DVD_Plus_RW_BasicFormat = 0x25, // NumberOfBlock = 0xffffffff
|
||||
|
||||
/// <summary>
|
||||
/// Basic format for DVD+RW (either SL or DL), see SCSI MMC-6
|
||||
/// </summary>
|
||||
DVD_Plus_RW_BasicFormat_DL_SL = 0x26,
|
||||
|
||||
/// <summary>
|
||||
/// Format with spare areas for BluRay-RE
|
||||
/// </summary>
|
||||
BDRE_Format_With_Spare_Areas = 0x30,
|
||||
|
||||
/// <summary>
|
||||
/// Format without spare areas for BlueRay-RE
|
||||
/// </summary>
|
||||
BDRE_Format_Without_Spare_Areas = 0x31,
|
||||
|
||||
/// <summary>
|
||||
/// Format a BD-R disk with spare area
|
||||
/// </summary>
|
||||
BDR_Format_With_Spare_Areas = 0x32
|
||||
|
||||
} ;
|
||||
|
||||
private byte m_flags;
|
||||
|
||||
/// <summary>
|
||||
/// The initializaion pattern for this format operation (not yet supported)
|
||||
/// </summary>
|
||||
public InitializationPattern IP;
|
||||
|
||||
/// <summary>
|
||||
/// The format type for this format operation
|
||||
/// </summary>
|
||||
public UnitFormatType FormatType;
|
||||
|
||||
/// <summary>
|
||||
/// The subtype for the format
|
||||
/// </summary>
|
||||
public byte FormatSubType;
|
||||
|
||||
/// <summary>
|
||||
/// The number of blocks for the format operation
|
||||
/// </summary>
|
||||
public uint NumberOfBlocks;
|
||||
|
||||
/// <summary>
|
||||
/// The format type dependent parameter
|
||||
/// </summary>
|
||||
public uint Parameter;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for the parameter list object
|
||||
/// </summary>
|
||||
public FormatParameterList()
|
||||
{
|
||||
m_flags = 0;
|
||||
IP = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The size of the format parameters list in bytes, as it will exist in
|
||||
/// the command to the SCSI unit.
|
||||
/// </summary>
|
||||
public uint Size
|
||||
{
|
||||
get
|
||||
{
|
||||
return 4 + 8;
|
||||
}
|
||||
}
|
||||
|
||||
#region public flags
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
public byte FOV
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)((m_flags >> 7) & 0x01);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != 0)
|
||||
m_flags |= 0x80;
|
||||
else
|
||||
m_flags &= 0x7f;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
public byte DPRY
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)((m_flags >> 6) & 0x01);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != 0)
|
||||
m_flags |= 0x40;
|
||||
else
|
||||
m_flags &= 0xbf;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
public byte DCRT
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)((m_flags >> 5) & 0x01);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != 0)
|
||||
m_flags |= 0x20;
|
||||
else
|
||||
m_flags &= 0xdf;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
public byte STPF
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)((m_flags >> 4) & 0x01);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != 0)
|
||||
m_flags |= 0x10;
|
||||
else
|
||||
m_flags &= 0xEF;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
public byte TRYOUT
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)((m_flags >> 2) & 0x01);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != 0)
|
||||
m_flags |= 0x04;
|
||||
else
|
||||
m_flags &= 0xFB;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
public byte IMMED
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)((m_flags >> 1) & 0x01);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != 0)
|
||||
m_flags |= 0x02;
|
||||
else
|
||||
m_flags &= 0xFD;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC-4 specification
|
||||
/// </summary>
|
||||
public byte VS
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)((m_flags >> 0) & 0x01);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != 0)
|
||||
m_flags |= 0x01;
|
||||
else
|
||||
m_flags &= 0xFE;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Format the parameter list to the memory block to be sent down to the device.
|
||||
/// The result should be a format parameter block as seen in the SCSI MMC specs.
|
||||
/// </summary>
|
||||
/// <param name="dest"></param>
|
||||
public void FormatToMemory(IntPtr dest)
|
||||
{
|
||||
byte v;
|
||||
int offset;
|
||||
|
||||
Marshal.WriteByte(dest, 0, 0); // Byte 0 - reserved
|
||||
|
||||
v = m_flags;
|
||||
if (IP != null)
|
||||
v |= 0x08;
|
||||
Marshal.WriteByte(dest, 1, v); // Byte 1 - flags
|
||||
|
||||
Marshal.WriteByte(dest, 2, 0);
|
||||
Marshal.WriteByte(dest, 3, 8); // Format descriptor length = 8
|
||||
|
||||
offset = 4 ;
|
||||
if (IP != null)
|
||||
{
|
||||
// If the initialization pattern exists, it goes here
|
||||
throw new Exception("Not supported yet");
|
||||
}
|
||||
|
||||
// Write the # of blocks
|
||||
Marshal.WriteByte(dest, offset++, (byte)((NumberOfBlocks >> 24) & 0xff));
|
||||
Marshal.WriteByte(dest, offset++, (byte)((NumberOfBlocks >> 16) & 0xff));
|
||||
Marshal.WriteByte(dest, offset++, (byte)((NumberOfBlocks >> 8) & 0xff));
|
||||
Marshal.WriteByte(dest, offset++, (byte)((NumberOfBlocks >> 0) & 0xff));
|
||||
|
||||
byte b = (byte)(((byte)FormatType << 2) | FormatSubType) ;
|
||||
Marshal.WriteByte(dest, offset++, b) ;
|
||||
|
||||
Marshal.WriteByte(dest, offset++, (byte)((Parameter >> 16) & 0xff));
|
||||
Marshal.WriteByte(dest, offset++, (byte)((Parameter >> 8) & 0xff));
|
||||
Marshal.WriteByte(dest, offset++, (byte)((Parameter >> 0) & 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
142
Bwg.Scsi/HeaderData.cs
Normal file
142
Bwg.Scsi/HeaderData.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains the header data read from a sector
|
||||
/// </summary>
|
||||
public class HeaderData : Result
|
||||
{
|
||||
#region public types
|
||||
/// <summary>
|
||||
/// The block type, see SCSI MMC spec
|
||||
/// </summary>
|
||||
public enum BlockTypeType : byte
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
UserDataBlock = 0x00,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
FourthRunInBlock = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
ThirdRunInBlock = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
SecondRunInBlock = 0x03,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
FirstRunInBlock = 0x04,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
LinkBlock = 0x05,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
SecondRunOutBlock = 0x06,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
FirstRunOutBlock = 0x07
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
/// The data mode for the sector (only applies if track mode is 0x04)
|
||||
/// </summary>
|
||||
public enum DataTypeType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Mode 0 data, 2336 bytes of zero
|
||||
/// </summary>
|
||||
Mode0Data = 0x00,
|
||||
|
||||
/// <summary>
|
||||
/// Mode 1 data, 2048 bytes of user data
|
||||
/// </summary>
|
||||
Mode1Data = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Mode 2 data, multiple forms of data
|
||||
/// </summary>
|
||||
Mode2Data = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved, should not be returned by a drive
|
||||
/// </summary>
|
||||
Reserved = 0x03
|
||||
} ;
|
||||
#endregion
|
||||
|
||||
#region public data members
|
||||
/// <summary>
|
||||
/// The time data read from the sector
|
||||
/// </summary>
|
||||
public readonly MinuteSecondFrame MSF;
|
||||
|
||||
/// <summary>
|
||||
/// The block type, see SCSI MMC spec
|
||||
/// </summary>
|
||||
public readonly BlockTypeType BlockType;
|
||||
|
||||
/// <summary>
|
||||
/// The data type, see SCSI MMC spec
|
||||
/// </summary>
|
||||
public readonly DataTypeType DataType;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Create the header data object from a buffer containing the header data
|
||||
/// </summary>
|
||||
/// <param name="buf">buffer containing the data</param>
|
||||
/// <param name="size">size of the data</param>
|
||||
public HeaderData(IntPtr buf, int size)
|
||||
: base(buf, size)
|
||||
{
|
||||
byte b ;
|
||||
|
||||
MSF = new MinuteSecondFrame(Get8(0), Get8(1), Get8(2));
|
||||
b = Get8(3);
|
||||
BlockType = (BlockTypeType)((b >> 5) & 0x07);
|
||||
DataType = (DataTypeType)(b & 0x03);
|
||||
}
|
||||
}
|
||||
}
|
||||
77
Bwg.Scsi/InitializationPattern.cs
Normal file
77
Bwg.Scsi/InitializationPattern.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// The class representing a pattern to use in initialization the surface of a
|
||||
/// DVD.
|
||||
/// </summary>
|
||||
public class InitializationPattern
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of modifier for the IP pattern
|
||||
/// </summary>
|
||||
public enum IPModifierType : byte
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
NoHeader = 0,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
WriteLBA = 1,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
WriteLBAPhysical = 2,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
Reserved = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The modifier
|
||||
/// </summary>
|
||||
public IPModifierType IPModifier;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte PatternType;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte[] Pattern;
|
||||
}
|
||||
}
|
||||
128
Bwg.Scsi/InquiryResult.cs
Normal file
128
Bwg.Scsi/InquiryResult.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains the information returned from a SCSI Inquiry request
|
||||
/// </summary>
|
||||
public sealed class InquiryResult : Result
|
||||
{
|
||||
/// <summary>
|
||||
/// The peripheral qualifier field from the SCSI inquiry reply, should be zero for MMC devices.
|
||||
/// </summary>
|
||||
public readonly byte PeripheralQualifier ;
|
||||
|
||||
/// <summary>
|
||||
/// The peripheral device type field from the SCSI inquiry reply, should be five for MMC devices.
|
||||
/// </summary>
|
||||
public readonly byte PeripheralDeviceType;
|
||||
|
||||
/// <summary>
|
||||
/// This gives the version number of the Inquiry data returned
|
||||
/// </summary>
|
||||
public readonly byte ResponseDataFormat;
|
||||
|
||||
/// <summary>
|
||||
/// The RMB field from the SCSI inquiry reply, should be true for MMC devices.
|
||||
/// </summary>
|
||||
public readonly bool RMB;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly byte Version;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly string VendorIdentification;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly string ProductIdentification;
|
||||
|
||||
/// <summary>
|
||||
/// The version of the firmware
|
||||
/// </summary>
|
||||
public readonly string FirmwareVersion;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly string ProductRevision;
|
||||
|
||||
/// <summary>
|
||||
/// This property returns true if the device supports removable medium.
|
||||
/// </summary>
|
||||
public bool RemovableMediumBit { get { return RMB; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="size"></param>
|
||||
public InquiryResult(IntPtr buffer, int size) : base(buffer, size)
|
||||
{
|
||||
ResponseDataFormat = (byte)(Get8(3) & 0x0f);
|
||||
|
||||
//
|
||||
// Make sure the inquiry data is in the right format
|
||||
// A data format of 2 is good up through MMC-3. A data format of 3
|
||||
// is used for MMC-4 and MMC-5. Some drives (especially from LiteOn)
|
||||
// use a value of 1, but still behave as expected.
|
||||
//
|
||||
if (ResponseDataFormat != 2 && ResponseDataFormat != 3 && ResponseDataFormat != 1)
|
||||
{
|
||||
m_valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
PeripheralQualifier = (byte)((Get8(0) >> 5) & 0x07);
|
||||
PeripheralDeviceType = (byte)(Get8(0) & 0x1f);
|
||||
RMB = false;
|
||||
if ((Get8(1) & 0x80) != 0)
|
||||
RMB = true;
|
||||
|
||||
Version = Get8(0x02);
|
||||
|
||||
VendorIdentification = GetString(8, 15);
|
||||
ProductIdentification = GetString(16, 31);
|
||||
|
||||
int len = 35;
|
||||
if (len >= size)
|
||||
len = size - 1;
|
||||
FirmwareVersion = GetString(32, len);
|
||||
|
||||
if (size >= 56)
|
||||
ProductRevision = GetString(36, 55);
|
||||
else
|
||||
ProductRevision = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
309
Bwg.Scsi/MinuteSecondFrame.cs
Normal file
309
Bwg.Scsi/MinuteSecondFrame.cs
Normal file
@@ -0,0 +1,309 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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.Diagnostics;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This type represents a location on a disk in minute, seconds, frame format
|
||||
/// </summary>
|
||||
[Serializable()]
|
||||
public class MinuteSecondFrame
|
||||
{
|
||||
/// <summary>
|
||||
/// The number of 44100 Hz samples in a single frame
|
||||
/// </summary>
|
||||
public const long SamplesPerFrame = 588;
|
||||
|
||||
/// <summary>
|
||||
/// The number of frames in a second
|
||||
/// </summary>
|
||||
public const long FramesPerSecond = 75;
|
||||
|
||||
/// <summary>
|
||||
/// The number of seconds in a minute.
|
||||
/// </summary>
|
||||
public const long SecondsPerMinute = 60;
|
||||
|
||||
/// <summary>
|
||||
/// The minutes of this time frame
|
||||
/// </summary>
|
||||
public int Minutes;
|
||||
|
||||
/// <summary>
|
||||
/// The seconds of this time frame
|
||||
/// </summary>
|
||||
public byte Seconds;
|
||||
|
||||
/// <summary>
|
||||
/// The frames (at FramesPerSecond per second) of this time frame
|
||||
/// </summary>
|
||||
public byte Frames;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for the type
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
/// <param name="s"></param>
|
||||
/// <param name="f"></param>
|
||||
public MinuteSecondFrame(int m, int s, int f)
|
||||
{
|
||||
Minutes = m;
|
||||
Seconds = (byte)s;
|
||||
Frames = (byte)f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a MinuteSecondFrame value from a sector count
|
||||
/// </summary>
|
||||
/// <param name="sectors"></param>
|
||||
public MinuteSecondFrame(long sectors)
|
||||
{
|
||||
long m = sectors / (FramesPerSecond * SecondsPerMinute);
|
||||
sectors -= m * FramesPerSecond * SecondsPerMinute;
|
||||
|
||||
long s = sectors / FramesPerSecond;
|
||||
sectors -= s * FramesPerSecond;
|
||||
|
||||
Debug.Assert(s < SecondsPerMinute);
|
||||
Debug.Assert(sectors < FramesPerSecond);
|
||||
|
||||
Minutes = (int)m;
|
||||
Seconds = (byte)s;
|
||||
Frames = (byte)sectors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the sector count for this time span
|
||||
/// </summary>
|
||||
public long SectorCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return Minutes * SecondsPerMinute * FramesPerSecond + Seconds * FramesPerSecond + Frames;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns the logical block address associated with the time given.
|
||||
/// </summary>
|
||||
public long LogicalBlockAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
long result = Minutes * FramesPerSecond * SecondsPerMinute + Seconds * FramesPerSecond + Frames;
|
||||
|
||||
if (Minutes < 90)
|
||||
result -= 150;
|
||||
else
|
||||
result -= 450150;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Return a hash code for this object
|
||||
/// </summary>
|
||||
/// <returns>hash value</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the two objects are equal
|
||||
/// </summary>
|
||||
/// <param name="o">the object to compare to</param>
|
||||
/// <returns>true if the objects are equal, false otherwise</returns>
|
||||
public override bool Equals(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
if (!(o is MinuteSecondFrame))
|
||||
return false;
|
||||
|
||||
|
||||
MinuteSecondFrame other = (MinuteSecondFrame)o;
|
||||
return other.Minutes == Minutes && other.Seconds == Seconds && other.Frames == Frames;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert to a string
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return Minutes.ToString("") + ":" + Seconds.ToString("") + "." + Frames.ToString("") + ", " + SectorCount + " sectors";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// convert to a string with format options
|
||||
/// </summary>
|
||||
/// <param name="fmt">the format to use for the output</param>
|
||||
/// <returns>a string representing the object</returns>
|
||||
public string ToString(string fmt)
|
||||
{
|
||||
string result = "";
|
||||
|
||||
if (fmt == "M:S")
|
||||
{
|
||||
result = Minutes.ToString("d2") + ":" + Seconds.ToString("d2");
|
||||
}
|
||||
else if (fmt == "M:S.F")
|
||||
{
|
||||
result = Minutes.ToString("d2") + ":" + Seconds.ToString("d2") + "." + Frames.ToString("d2");
|
||||
}
|
||||
else if (fmt == "M:S:F")
|
||||
{
|
||||
result = Minutes.ToString("d2") + ":" + Seconds.ToString("d2") + ":" + Frames.ToString("d2");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FormatException("the format '" + fmt + "' is not valid for the class Bwg.Scsi.MinuteSecondFrame");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a number of samples into an MSF object
|
||||
/// </summary>
|
||||
/// <param name="samples">the number of samples</param>
|
||||
/// <returns></returns>
|
||||
static public MinuteSecondFrame FromSampleCount(long samples)
|
||||
{
|
||||
long frames = samples / SamplesPerFrame;
|
||||
uint m = (uint)(frames / (FramesPerSecond * SecondsPerMinute));
|
||||
frames -= m * FramesPerSecond * SecondsPerMinute;
|
||||
|
||||
uint s = (uint)(frames / FramesPerSecond);
|
||||
frames -= s * FramesPerSecond;
|
||||
|
||||
Debug.Assert(s < SecondsPerMinute);
|
||||
Debug.Assert(m < FramesPerSecond);
|
||||
return new MinuteSecondFrame((byte)m, (byte)s, (byte)frames);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operator for adding two MinuteSecondFrame times together
|
||||
/// </summary>
|
||||
/// <param name="t1">the first operand</param>
|
||||
/// <param name="t2">the second operand</param>
|
||||
/// <returns>the sum of t1 and t2</returns>
|
||||
static public MinuteSecondFrame operator +(MinuteSecondFrame t1, MinuteSecondFrame t2)
|
||||
{
|
||||
return new MinuteSecondFrame(t1.SectorCount + t2.SectorCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operator for adding a time value with a frame count (or sector count)
|
||||
/// </summary>
|
||||
/// <param name="t1">the time value</param>
|
||||
/// <param name="t2">the count in sectors (or frames)</param>
|
||||
/// <returns>the addition time</returns>
|
||||
static public MinuteSecondFrame operator +(MinuteSecondFrame t1, long t2)
|
||||
{
|
||||
return new MinuteSecondFrame(t1.SectorCount + t2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the first object is less than the second object
|
||||
/// </summary>
|
||||
/// <param name="t1">the first object</param>
|
||||
/// <param name="t2">the second object</param>
|
||||
/// <returns>true if t1 is less than t2 </returns>
|
||||
static public bool operator <(MinuteSecondFrame t1, MinuteSecondFrame t2)
|
||||
{
|
||||
if (t1.Minutes < t2.Minutes)
|
||||
return true;
|
||||
|
||||
if (t1.Minutes > t2.Minutes)
|
||||
return false;
|
||||
|
||||
if (t1.Seconds < t2.Seconds)
|
||||
return true;
|
||||
|
||||
if (t1.Seconds > t2.Seconds)
|
||||
return false;
|
||||
|
||||
if (t1.Frames < t2.Frames)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the first object is greater than the second object
|
||||
/// </summary>
|
||||
/// <param name="t1">the first object</param>
|
||||
/// <param name="t2">the second object</param>
|
||||
/// <returns>true, if t1 is greater than t2</returns>
|
||||
static public bool operator >(MinuteSecondFrame t1, MinuteSecondFrame t2)
|
||||
{
|
||||
if (t1.Minutes > t2.Minutes)
|
||||
return true;
|
||||
|
||||
if (t1.Minutes < t2.Minutes)
|
||||
return false;
|
||||
|
||||
if (t1.Seconds > t2.Seconds)
|
||||
return true;
|
||||
|
||||
if (t1.Seconds < t2.Seconds)
|
||||
return false;
|
||||
|
||||
if (t1.Frames > t2.Frames)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns true if t1 is less than or equal to t2
|
||||
/// </summary>
|
||||
/// <param name="t1"></param>
|
||||
/// <param name="t2"></param>
|
||||
/// <returns></returns>
|
||||
static public bool operator <=(MinuteSecondFrame t1, MinuteSecondFrame t2)
|
||||
{
|
||||
return (t1 < t2) || (t1 == t2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="t1"></param>
|
||||
/// <param name="t2"></param>
|
||||
/// <returns></returns>
|
||||
static public bool operator >=(MinuteSecondFrame t1, MinuteSecondFrame t2)
|
||||
{
|
||||
return (t1 > t2) || (t1 == t2);
|
||||
}
|
||||
}
|
||||
}
|
||||
174
Bwg.Scsi/ModePage.cs
Normal file
174
Bwg.Scsi/ModePage.cs
Normal file
@@ -0,0 +1,174 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// This object represents a single mode page in a mode table.
|
||||
/// </summary>
|
||||
public class ModePage : Result
|
||||
{
|
||||
#region private member variables
|
||||
/// <summary>
|
||||
/// The data associated with the page table. This data also includes the page code and length
|
||||
/// data elements from the mode page data.
|
||||
/// </summary>
|
||||
protected byte[] m_page_data;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// This is the constructor for the mode page object. It builds a mode page object from
|
||||
/// the raw reply area from the SCSI device.
|
||||
/// </summary>
|
||||
/// <param name="buffer">A pointer to the raw reply area</param>
|
||||
/// <param name="size">The size of the raw reply area in bytes</param>
|
||||
/// <param name="offset">The offset to the mode page data</param>
|
||||
public ModePage(IntPtr buffer, int size, ref ushort offset) : base(buffer, size)
|
||||
{
|
||||
byte b = Get8(offset);
|
||||
offset++;
|
||||
byte len = Get8(offset);
|
||||
offset++;
|
||||
|
||||
m_page_data = new byte[len + 2];
|
||||
m_page_data[0] = b;
|
||||
m_page_data[1] = len;
|
||||
for(int i = 0 ; i < len ; i++)
|
||||
m_page_data[i + 2] = Get8(offset++);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
|
||||
/// <summary>
|
||||
/// This is the data that makes up this mode page
|
||||
/// </summary>
|
||||
public byte[] PageData
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_page_data;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The length of this mode page in bytes
|
||||
/// </summary>
|
||||
public ushort Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ushort)m_page_data.GetLength(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The page code for this page
|
||||
/// </summary>
|
||||
public byte PageCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)(m_page_data[0] & 0x3f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, these parameters are saved permanently
|
||||
/// </summary>
|
||||
public bool ParametersSavable
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((m_page_data[0] & 0x80) != 0) ? true : false;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
m_page_data[0] |= 0x80;
|
||||
else
|
||||
m_page_data[0] &= 0x7f;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
/// <summary>
|
||||
/// Retreive a 32 bit value from a mode page
|
||||
/// </summary>
|
||||
/// <param name="offset">offset in the page to the value</param>
|
||||
/// <returns>a 32 bit value retreived from the mode page data</returns>
|
||||
public int ModeGet32(int offset)
|
||||
{
|
||||
return m_page_data[offset + 0] << 24 |
|
||||
m_page_data[offset + 1] << 16 |
|
||||
m_page_data[offset + 2] << 8 |
|
||||
m_page_data[offset + 3] << 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a 32 bit value in a mode page
|
||||
/// </summary>
|
||||
/// <param name="offset">offset in the page to where the value will be placed</param>
|
||||
/// <param name="value">the value to write</param>
|
||||
public void ModeSet32(int offset, int value)
|
||||
{
|
||||
m_page_data[offset + 0] = (byte)((value >> 24) & 0xff);
|
||||
m_page_data[offset + 1] = (byte)((value >> 16) & 0xff);
|
||||
m_page_data[offset + 2] = (byte)((value >> 8) & 0xff);
|
||||
m_page_data[offset + 3] = (byte)((value >> 0) & 0xff);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public ushort ModeGet16(int offset)
|
||||
{
|
||||
return (ushort)(m_page_data[offset + 0] << 8 |
|
||||
m_page_data[offset + 1] << 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="value"></param>
|
||||
public void ModeSet16(int offset, ushort value)
|
||||
{
|
||||
m_page_data[offset + 0] = (byte)((value >> 8) & 0xff);
|
||||
m_page_data[offset + 1] = (byte)((value >> 0) & 0xff);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
108
Bwg.Scsi/ModeTable.cs
Normal file
108
Bwg.Scsi/ModeTable.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a mode table from the scsi device.
|
||||
/// </summary>
|
||||
public class ModeTable : Result
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the size of the header associated with a mode table.
|
||||
/// </summary>
|
||||
public const int ModeTableHeaderSize = 8;
|
||||
|
||||
/// <summary>
|
||||
/// The set of mode pages in this mode table.
|
||||
/// </summary>
|
||||
public IList<ModePage> Pages;
|
||||
|
||||
/// <summary>
|
||||
/// The constructor for the mode table object. It builds the mode table from
|
||||
/// the raw reply buffer from the SCSI device.
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="size"></param>
|
||||
public ModeTable(IntPtr buffer, int size): base(buffer, size)
|
||||
{
|
||||
ushort len = Get16(0);
|
||||
ushort index = ModeTableHeaderSize;
|
||||
|
||||
Pages = new List<ModePage>();
|
||||
|
||||
while (index < len && index < size)
|
||||
{
|
||||
int b0 = Get8(index) & 0x3f;
|
||||
|
||||
ModePage page ;
|
||||
if (b0 == 0x05)
|
||||
page = new WriteParameterModePage(buffer, size, ref index) ;
|
||||
else
|
||||
page = new ModePage(buffer, size, ref index);
|
||||
|
||||
Pages.Add(page);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns the total size of the raw mode table in bytes
|
||||
/// </summary>
|
||||
public ushort Size
|
||||
{
|
||||
get
|
||||
{
|
||||
ushort len = ModeTableHeaderSize;
|
||||
|
||||
foreach (ModePage p in Pages)
|
||||
len += p.Length;
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format a mode table back into raw buffer for shipment down to a SCSI device.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The buffer to receive the mode table</param>
|
||||
public void Format(IntPtr buffer)
|
||||
{
|
||||
ushort s = (ushort)(Size - ModeTableHeaderSize);
|
||||
Marshal.WriteByte(buffer, 0, (byte)((s >> 8) & 0xff));
|
||||
Marshal.WriteByte(buffer, 1, (byte)(s & 0xff));
|
||||
|
||||
int offset = ModeTableHeaderSize;
|
||||
foreach (ModePage p in Pages)
|
||||
{
|
||||
IntPtr dest = new IntPtr(buffer.ToInt32() + offset);
|
||||
Marshal.Copy(p.PageData, 0, dest, p.Length);
|
||||
offset += p.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Bwg.Scsi/OpcTableEntry.cs
Normal file
60
Bwg.Scsi/OpcTableEntry.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a single entry in the OPC table
|
||||
/// </summary>
|
||||
public class OpcTableEntry : Result
|
||||
{
|
||||
/// <summary>
|
||||
/// The speed to which this entry applies
|
||||
/// </summary>
|
||||
public readonly ushort Speed;
|
||||
|
||||
/// <summary>
|
||||
/// The OPC table entries
|
||||
/// </summary>
|
||||
public readonly byte[] Table;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for an OPC table entry
|
||||
/// </summary>
|
||||
/// <param name="buffer">The raw buffer being processed</param>
|
||||
/// <param name="size">The size of the buffer</param>
|
||||
/// <param name="offset">The offset into the buffer that contains the OPC entry</param>
|
||||
public OpcTableEntry(IntPtr buffer, int size, int offset) : base(buffer, size)
|
||||
{
|
||||
Speed = Get16(offset);
|
||||
|
||||
Table = new byte [6] ;
|
||||
for (int i = 0; i < 6; i++)
|
||||
Table[i] = Get8(offset + i + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
84
Bwg.Scsi/Performance.cs
Normal file
84
Bwg.Scsi/Performance.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a performance entry from the device's performance list
|
||||
/// </summary>
|
||||
public class Performance : Result
|
||||
{
|
||||
/// <summary>
|
||||
/// The start LBA for this entry
|
||||
/// </summary>
|
||||
public readonly uint StartLBA;
|
||||
|
||||
/// <summary>
|
||||
/// The starting performance for this entry
|
||||
/// </summary>
|
||||
public readonly uint StartPerformance;
|
||||
|
||||
/// <summary>
|
||||
/// The end LBA for this entry
|
||||
/// </summary>
|
||||
public readonly uint EndLBA;
|
||||
|
||||
/// <summary>
|
||||
/// The end performance for this entry
|
||||
/// </summary>
|
||||
public readonly uint EndPerformance;
|
||||
|
||||
/// <summary>
|
||||
/// The constructor to create a performance entry
|
||||
/// </summary>
|
||||
/// <param name="buffer">the buffer</param>
|
||||
/// <param name="offset">the offset into the buffer</param>
|
||||
/// <param name="size">the size of the buffer</param>
|
||||
public Performance(IntPtr buffer, int offset, int size)
|
||||
: base(buffer, size)
|
||||
{
|
||||
StartLBA = Get32(offset);
|
||||
StartPerformance = Get32(offset + 4);
|
||||
EndLBA = Get32(offset + 8);
|
||||
EndPerformance = Get32(offset + 12);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a human readable string representing this object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string str = string.Empty;
|
||||
|
||||
str += "Start LBA=" + StartLBA.ToString();
|
||||
str += ", Start Perf=" + StartPerformance.ToString() + " Kb/sec";
|
||||
str += ", End LBA=" + EndLBA.ToString();
|
||||
str += ", End Perf=" + EndPerformance.ToString() + " Kb/sec";
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
170
Bwg.Scsi/PerformanceList.cs
Normal file
170
Bwg.Scsi/PerformanceList.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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.Collections;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// A list of performance entries from the drive
|
||||
/// </summary>
|
||||
public class PerformanceList : Result, IEnumerable<Performance>, IEnumerable
|
||||
{
|
||||
#region public types
|
||||
/// <summary>
|
||||
/// The type of the data (read or write)
|
||||
/// </summary>
|
||||
public enum DataType
|
||||
{
|
||||
/// <summary>
|
||||
/// This means read data
|
||||
/// </summary>
|
||||
ReadData,
|
||||
|
||||
/// <summary>
|
||||
/// This means write data
|
||||
/// </summary>
|
||||
WriteData
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum ExceptType : byte
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
Nominal = 0,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
Entire = 1,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
Exceptions = 2
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private data members
|
||||
private DataType m_type;
|
||||
private IList<Performance> m_list;
|
||||
private bool m_except;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// The constructor for the class
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="size"></param>
|
||||
public PerformanceList(IntPtr buffer, int size)
|
||||
: base(buffer, size)
|
||||
{
|
||||
m_list = new List<Performance>();
|
||||
|
||||
uint len = Get32(0);
|
||||
int index = 8;
|
||||
Debug.Assert(size >= 8);
|
||||
|
||||
byte b = Get8(4);
|
||||
if ((b & 0x02) != 0)
|
||||
m_type = DataType.WriteData;
|
||||
else
|
||||
m_type = DataType.ReadData;
|
||||
|
||||
if ((b & 0x01) != 0)
|
||||
m_except = true;
|
||||
else
|
||||
m_except = false;
|
||||
|
||||
while (index < len && index + 16 <= len && index + 16 <= size)
|
||||
{
|
||||
Performance p = new Performance(buffer, index, size);
|
||||
m_list.Add(p);
|
||||
|
||||
index += 16;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an indexed entry tino the performance list
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public Performance this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_list[index];
|
||||
}
|
||||
}
|
||||
|
||||
#region properties
|
||||
/// <summary>
|
||||
/// The type of the data
|
||||
/// </summary>
|
||||
public DataType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, this is exception data
|
||||
/// </summary>
|
||||
public bool IsExceptionData
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_except;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public members
|
||||
/// <summary>
|
||||
/// Return an enumerator for this list
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<Performance> GetEnumerator()
|
||||
{
|
||||
return m_list.GetEnumerator();
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return m_list.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
35
Bwg.Scsi/Properties/AssemblyInfo.cs
Normal file
35
Bwg.Scsi/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Bwg.Scsi")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("BwgSoftware")]
|
||||
[assembly: AssemblyProduct("BwgBurn")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2006 by Jack W. Griffin, Jr.")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("d8330703-34ac-4124-a059-ba011391cc2e")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("0.0.7.1")]
|
||||
[assembly: AssemblyFileVersion("0.0.7.1")]
|
||||
205
Bwg.Scsi/Result.cs
Normal file
205
Bwg.Scsi/Result.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is a base class for classes that contain results from SCSI commands. This
|
||||
/// class contains information about whether or not that result is valid and provides functions
|
||||
/// for extract data from the SCSI response.
|
||||
/// </summary>
|
||||
public abstract class Result
|
||||
{
|
||||
#region private data members
|
||||
/// <summary>
|
||||
/// The data buffer containing the data that makes up the result
|
||||
/// </summary>
|
||||
private IntPtr m_buffer ;
|
||||
|
||||
/// <summary>
|
||||
/// The size of the data in the buffer
|
||||
/// </summary>
|
||||
private int m_size ;
|
||||
|
||||
/// <summary>
|
||||
/// This member is true if the result is valid. It is false if an error occurred while
|
||||
/// parsing the SCSI result.
|
||||
/// </summary>
|
||||
protected bool m_valid;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// This is the constructor for the ScsiResult class.
|
||||
/// </summary>
|
||||
/// <param name="buffer">A pointer to the memory area containing the SCSI reply</param>
|
||||
/// <param name="size">The size of the memory area containing the SCSI reply</param>
|
||||
public Result(IntPtr buffer, int size)
|
||||
{
|
||||
m_valid = true;
|
||||
m_buffer = buffer;
|
||||
m_size = size;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
/// <summary>
|
||||
/// This property is true if the result is valid, and false otherwise.
|
||||
/// </summary>
|
||||
public bool Valid
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns the size of the buffer
|
||||
/// </summary>
|
||||
public int BufferSize
|
||||
{
|
||||
get { return m_size; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns the buffer
|
||||
/// </summary>
|
||||
public IntPtr Buffer
|
||||
{
|
||||
get { return m_buffer; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public member functions
|
||||
/// <summary>
|
||||
/// This method returns a byte of data from the memory area associated with the SCSI reply.
|
||||
/// </summary>
|
||||
/// <param name="offset">The location of the byte to return within the reply</param>
|
||||
/// <returns>a byte of data from the reply</returns>
|
||||
public byte Get8(int offset)
|
||||
{
|
||||
if (offset >= m_size)
|
||||
throw new Exception("offset " + offset.ToString() + " is out side the range of the buffer");
|
||||
|
||||
return Marshal.ReadByte(m_buffer, offset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public ushort Get16(int offset)
|
||||
{
|
||||
return (ushort)((Get8(offset) << 8) | Get8(offset + 1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a 16 bit number located in two different places in the buffer
|
||||
/// </summary>
|
||||
/// <param name="msb">offset to the MSB of the number</param>
|
||||
/// <param name="lsb">offset to the LSB of the number</param>
|
||||
/// <returns></returns>
|
||||
public ushort Get16(int msb, int lsb)
|
||||
{
|
||||
return (ushort)((Get8(msb) << 8) | Get8(lsb));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public uint Get24(int offset)
|
||||
{
|
||||
return (UInt32)((Get8(offset) << 16) | (Get8(offset + 1) << 8) | Get8(offset + 2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
public uint Get32(int offset)
|
||||
{
|
||||
return (UInt32)((Get8(offset) << 24) | (Get8(offset + 1) << 16) | (Get8(offset + 2) << 8) | Get8(offset + 3));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method returns a 32 bit integer from an offset in the data buffer. The data is
|
||||
/// ordered as big endian data per the SCSI-3 specification.
|
||||
/// </summary>
|
||||
/// <param name="offset">the offset into the buffer</param>
|
||||
/// <returns></returns>
|
||||
public int Get32Int(int offset)
|
||||
{
|
||||
uint b = Get32(offset);
|
||||
Debug.Assert(b < Int32.MaxValue);
|
||||
return (int)b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="stop"></param>
|
||||
/// <returns></returns>
|
||||
public string GetString(int start, int stop)
|
||||
{
|
||||
string s = "";
|
||||
|
||||
for (int i = start; i <= stop; i++)
|
||||
{
|
||||
byte b = Get8(i);
|
||||
s += (char)b;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a true or false value based on a bit in the buffer
|
||||
/// </summary>
|
||||
/// <param name="offset">offset to the byte containing the bit</param>
|
||||
/// <param name="bit">the specific bit number</param>
|
||||
/// <returns>boolean reflecting the value of the bit</returns>
|
||||
public bool GetBit(int offset, int bit)
|
||||
{
|
||||
byte b = Get8(offset);
|
||||
|
||||
if ((b & (1 << bit)) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
115
Bwg.Scsi/SpeedDescriptor.cs
Normal file
115
Bwg.Scsi/SpeedDescriptor.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class SpeedDescriptor : Result
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly Device.RotationalControl WRC;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool Exact;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool MRW;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly uint EndLBA;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly int ReadSpeed;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly int WriteSpeed;
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="size"></param>
|
||||
public SpeedDescriptor(IntPtr buffer, int offset, int size)
|
||||
: base(buffer, size)
|
||||
{
|
||||
byte b = Get8(offset);
|
||||
|
||||
if (((b & 0x03) >> 3 == 0))
|
||||
WRC = Device.RotationalControl.CLVandNonPureCav ;
|
||||
else if (((b & 0x03) >> 3) == 1)
|
||||
WRC = Device.RotationalControl.PureCav ;
|
||||
|
||||
if ((b & 0x02) == 0)
|
||||
Exact = false ;
|
||||
else
|
||||
Exact = true ;
|
||||
|
||||
if ((b & 0x01) == 0)
|
||||
MRW = false ;
|
||||
else
|
||||
MRW = true ;
|
||||
|
||||
EndLBA = Get32(offset + 4);
|
||||
ReadSpeed = Get32Int(offset + 8);
|
||||
WriteSpeed = Get32Int(offset + 12);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a human readable string representing this object
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string str = string.Empty;
|
||||
|
||||
str += "WRC=" + WRC.ToString();
|
||||
str += ", Exact=" + Exact.ToString();
|
||||
str += ", MRW=" + MRW.ToString();
|
||||
str += ", EndLba=" + EndLBA.ToString();
|
||||
str += ", Read=" + ReadSpeed.ToString();
|
||||
str += ", Write=" + WriteSpeed.ToString();
|
||||
|
||||
return str;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
96
Bwg.Scsi/SpeedDescriptorList.cs
Normal file
96
Bwg.Scsi/SpeedDescriptorList.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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.Collections;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class SpeedDescriptorList : Result, IEnumerable<SpeedDescriptor>, IEnumerable
|
||||
{
|
||||
private IList<SpeedDescriptor> m_list;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="size"></param>
|
||||
public SpeedDescriptorList(IntPtr buffer, int size)
|
||||
: base(buffer, size)
|
||||
{
|
||||
m_list = new List<SpeedDescriptor>();
|
||||
|
||||
uint len = Get32(0) + 4;
|
||||
int index = 8;
|
||||
Debug.Assert(size >= 8);
|
||||
|
||||
while (index < len && index < size)
|
||||
{
|
||||
SpeedDescriptor p = new SpeedDescriptor(buffer, index, size);
|
||||
m_list.Add(p);
|
||||
|
||||
index += 16;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is an indexor into the list of descriptors
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public SpeedDescriptor this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_list[index];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the number of speed descriptors in the list
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get { return m_list.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an enumerator for this list
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<SpeedDescriptor> GetEnumerator()
|
||||
{
|
||||
return m_list.GetEnumerator();
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return m_list.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
121
Bwg.Scsi/SubheaderData.cs
Normal file
121
Bwg.Scsi/SubheaderData.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents subheader data for a given sector
|
||||
/// </summary>
|
||||
public class SubheaderData : Result
|
||||
{
|
||||
#region public types
|
||||
/// <summary>
|
||||
/// The submode type
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum SubmodeType : byte
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
EndOfFile = 0x80,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
RealTimeBlock = 0x40,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
Form2 = 0x20,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
TriggerBlock = 0x10,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
DataBlock = 0x08,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
AudioBlock = 0x04, // Not traditional CD-DA
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
VideoBlock = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// See SCSI MMC spec
|
||||
/// </summary>
|
||||
EndOfRecord = 0x01
|
||||
} ;
|
||||
#endregion
|
||||
|
||||
#region public data members
|
||||
/// <summary>
|
||||
/// File number, see SCSI MMC spec
|
||||
/// </summary>
|
||||
public readonly byte FileNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Channel number, see SCSI MMC spec
|
||||
/// </summary>
|
||||
public readonly byte ChannelNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Submode, see SCSI MMC spec
|
||||
/// </summary>
|
||||
public readonly SubmodeType Submode;
|
||||
|
||||
/// <summary>
|
||||
/// Coding information, see SCSI MMC spec
|
||||
/// </summary>
|
||||
public readonly byte CodingInformation;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Create subheader data information from subheader data read
|
||||
/// </summary>
|
||||
/// <param name="buf">the buffer containing the subheader data</param>
|
||||
/// <param name="size">the size of the data</param>
|
||||
public SubheaderData(IntPtr buf, int size)
|
||||
: base(buf, size)
|
||||
{
|
||||
FileNumber = Get8(0);
|
||||
ChannelNumber = Get8(1);
|
||||
Submode = (SubmodeType)Get8(2);
|
||||
CodingInformation = Get8(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
80
Bwg.Scsi/TocEntry.cs
Normal file
80
Bwg.Scsi/TocEntry.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// A class representing a single TOC entry
|
||||
/// </summary>
|
||||
public class TocEntry : Result
|
||||
{
|
||||
/// <summary>
|
||||
/// The ADR value for this track
|
||||
/// </summary>
|
||||
public byte Adr;
|
||||
|
||||
/// <summary>
|
||||
/// The control value for this track
|
||||
/// </summary>
|
||||
public byte Control;
|
||||
|
||||
/// <summary>
|
||||
/// The track number for this track
|
||||
/// </summary>
|
||||
public byte Number;
|
||||
|
||||
/// <summary>
|
||||
/// The start address (in sector) for this track
|
||||
/// </summary>
|
||||
public uint StartSector ;
|
||||
|
||||
/// <summary>
|
||||
/// The starting MSF for this track
|
||||
/// </summary>
|
||||
public MinuteSecondFrame StartMSF;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new TOC entry
|
||||
/// </summary>
|
||||
/// <param name="buffer">the memory buffer holding the TOC</param>
|
||||
/// <param name="offset">the offset to the TOC entry of interest</param>
|
||||
/// <param name="size">the overall size of the buffer</param>
|
||||
/// <param name="mode">time versus lba mode</param>
|
||||
public TocEntry(IntPtr buffer, int offset, int size, bool mode) : base(buffer, size)
|
||||
{
|
||||
byte b = Get8(offset + 1) ;
|
||||
Adr = (byte)((b >> 4) & 0x0f) ;
|
||||
Control = (byte)(b & 0x0f) ;
|
||||
Number = Get8(offset + 2) ;
|
||||
|
||||
if (mode)
|
||||
StartMSF = new MinuteSecondFrame(Get8(offset + 5), Get8(offset + 6), Get8(offset + 7));
|
||||
else
|
||||
StartSector = Get32(offset + 4) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
204
Bwg.Scsi/TrackInformation.cs
Normal file
204
Bwg.Scsi/TrackInformation.cs
Normal file
@@ -0,0 +1,204 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This data structure contains the results from call ReadTrackInformation() to read
|
||||
/// data about a track
|
||||
/// </summary>
|
||||
public class TrackInformation : Result
|
||||
{
|
||||
#region public types
|
||||
/// <summary>
|
||||
/// This type represents the data mode for the track
|
||||
/// </summary>
|
||||
public enum DataModeType
|
||||
{
|
||||
/// <summary>
|
||||
/// Mode 1 user data (digital data, 2048 bytes per sector)
|
||||
/// </summary>
|
||||
Mode1 = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Mode 2 user data (digital data, multiple forms)
|
||||
/// </summary>
|
||||
Mode2 = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// Audio data, 2352 bytes of audio data per sector
|
||||
/// </summary>
|
||||
Audio = 0x0f
|
||||
} ;
|
||||
#endregion
|
||||
|
||||
#region public Track Information Members
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly ushort TrackNumber;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly ushort SessionNumber;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool Copy;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool Damage;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly byte TrackMode;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool RT;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool Blank;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool Packet;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool FP;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly DataModeType DataMode;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool LRA_V;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly bool NWA_V;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly int TrackStartAddress;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly int NextWritableAddress;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly int FreeBlocks;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly int FixedPacketSize;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly int TrackSize;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly int LastRecordedAddress;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly int ReadCompatLBA;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Contruct a read track result object from the raw data.
|
||||
/// </summary>
|
||||
/// <param name="buf">the raw data buffer</param>
|
||||
/// <param name="size">the size of the raw buffer in bytes</param>
|
||||
public TrackInformation(IntPtr buf, int size) : base(buf, size)
|
||||
{
|
||||
TrackNumber = Get16(32, 2) ;
|
||||
SessionNumber = Get16(33, 3) ;
|
||||
|
||||
Copy = GetBit(5,4) ;
|
||||
Damage = GetBit(5,5) ;
|
||||
TrackMode = (byte)(Get8(5) & 0x0f) ;
|
||||
|
||||
RT = GetBit(6,7) ;
|
||||
Blank = GetBit(6,6) ;
|
||||
Packet = GetBit(6,5) ;
|
||||
FP = GetBit(6,4) ;
|
||||
DataMode = (DataModeType)(Get8(6) & 0x0f);
|
||||
|
||||
LRA_V = GetBit(7, 1) ;
|
||||
NWA_V = GetBit(7, 0) ;
|
||||
|
||||
TrackStartAddress = (int)Get32(8) ;
|
||||
NextWritableAddress = (int)Get32(12) ;
|
||||
FreeBlocks = Get32Int(16) ;
|
||||
FixedPacketSize = Get32Int(20) ;
|
||||
TrackSize = Get32Int(24) ;
|
||||
LastRecordedAddress = (int)Get32(28) ;
|
||||
ReadCompatLBA = (int)Get32(36) ;
|
||||
}
|
||||
|
||||
#region public properties
|
||||
|
||||
/// <summary>
|
||||
/// An alias for fixed packet size depending on the mode of the track.
|
||||
/// </summary>
|
||||
public int BlockingFactor
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedPacketSize;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
190
Bwg.Scsi/WinDev.cs
Normal file
190
Bwg.Scsi/WinDev.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public unsafe class WinDev : IDisposable
|
||||
{
|
||||
//
|
||||
// External functions required to interface to th
|
||||
//
|
||||
[DllImport("Kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr CreateFile(string h, uint acc, uint share, IntPtr sec, uint disp, uint flash, uint temp);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = true)]
|
||||
private static extern bool DeviceIoControl(IntPtr h, uint code, IntPtr inbuf, uint insize, IntPtr outbuf, uint outsize, ref uint returned, IntPtr Overlapped);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = true)]
|
||||
private static extern bool CloseHandle(IntPtr h);
|
||||
|
||||
[DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode)]
|
||||
private static extern uint FormatMessage(uint flags, IntPtr src, uint errcode, uint langid, IntPtr str, uint size, IntPtr vargs) ;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the device
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { CheckOpen() ; return m_name; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns TRUE if the device is open, FALSE otherwise
|
||||
/// </summary>
|
||||
public bool IsOpen { get { return m_handle.ToInt32() != -1; } }
|
||||
|
||||
private string m_name;
|
||||
private IntPtr m_handle;
|
||||
private uint m_last_error;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public WinDev()
|
||||
{
|
||||
m_handle = new IntPtr(-1);
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public uint LastError
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_last_error;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (IsOpen)
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
virtual public bool Open(string name)
|
||||
{
|
||||
string dname = name;
|
||||
|
||||
//
|
||||
// CreateFile
|
||||
// name
|
||||
// accessmode = GenericRead | GenericWrite
|
||||
UInt32 acc = 0x80000000 | 0x40000000;
|
||||
m_handle = CreateFile(dname, acc, 0x01, (IntPtr)0, 3, 0x00000080, (uint)0);
|
||||
if (m_handle.ToInt32() == -1)
|
||||
{
|
||||
m_last_error = (uint)Marshal.GetLastWin32Error();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_name = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="letter"></param>
|
||||
/// <returns></returns>
|
||||
virtual public bool Open(char letter)
|
||||
{
|
||||
string dname = "\\\\.\\" + letter + ":";
|
||||
return Open(dname);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected void CheckOpen()
|
||||
{
|
||||
if (m_handle.ToInt32() == -1)
|
||||
throw new Exception("device is not open") ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="inbuf"></param>
|
||||
/// <param name="insize"></param>
|
||||
/// <param name="outbuf"></param>
|
||||
/// <param name="outsize"></param>
|
||||
/// <param name="ret"></param>
|
||||
/// <param name="overlapped"></param>
|
||||
/// <returns></returns>
|
||||
protected bool Control(uint code, IntPtr inbuf, uint insize, IntPtr outbuf, uint outsize, ref uint ret, IntPtr overlapped)
|
||||
{
|
||||
bool b;
|
||||
|
||||
CheckOpen() ;
|
||||
b = DeviceIoControl(m_handle, code, inbuf, insize, outbuf, outsize, ref ret, overlapped);
|
||||
if (!b)
|
||||
m_last_error = (uint)Marshal.GetLastWin32Error();
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a WIN32 error code to an error string.
|
||||
/// </summary>
|
||||
/// <param name="error">the error code to convert</param>
|
||||
/// <returns>the string for the error code</returns>
|
||||
static public string Win32ErrorToString(uint error)
|
||||
{
|
||||
IntPtr buffer = Marshal.AllocHGlobal(1024) ;
|
||||
uint ret = FormatMessage(0x1000, IntPtr.Zero, error, 0, buffer, 1024, IntPtr.Zero);
|
||||
if (ret == 0)
|
||||
return "cannot find win32 error string for this code (" + error.ToString() + ")";
|
||||
|
||||
string str = Marshal.PtrToStringUni(buffer);
|
||||
str = str.Trim();
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
137
Bwg.Scsi/WriteBuffer.cs
Normal file
137
Bwg.Scsi/WriteBuffer.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is used to buffer data to the SCSI device when
|
||||
/// writing large amounts of data to the SCSI device.
|
||||
/// </summary>
|
||||
public class WriteBuffer : IDisposable
|
||||
{
|
||||
[DllImport("ntdll.dll")]
|
||||
internal static extern void RtlZeroMemory(IntPtr dest, int size);
|
||||
|
||||
[DllImport("ntdll.dll")]
|
||||
internal static extern void RtlFillMemory(IntPtr dest, int size, byte value);
|
||||
|
||||
#region public data members
|
||||
|
||||
/// <summary>
|
||||
/// The size of the buffer associated with this object (in sectors)
|
||||
/// </summary>
|
||||
public int BufferSize;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of data stored in the buffer (in sectors)
|
||||
/// </summary>
|
||||
public int DataSize;
|
||||
|
||||
/// <summary>
|
||||
/// The size of a sector of data stored in this buffer page
|
||||
/// </summary>
|
||||
public int SectorSize;
|
||||
|
||||
/// <summary>
|
||||
/// This contains the logical block address for this block of data
|
||||
/// </summary>
|
||||
public long LogicalBlockAddress;
|
||||
|
||||
/// <summary>
|
||||
/// The source of this buffer, used only for debugging
|
||||
/// </summary>
|
||||
public string SourceString;
|
||||
|
||||
#endregion
|
||||
|
||||
#region private data members
|
||||
|
||||
/// <summary>
|
||||
/// The actual buffer memory
|
||||
/// </summary>
|
||||
private IntPtr m_buffer_ptr;
|
||||
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns a buffer pointer to the internal buffer.
|
||||
/// </summary>
|
||||
public IntPtr BufferPtr
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_buffer_ptr;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region constructors
|
||||
|
||||
/// <summary>
|
||||
/// Create a new buffer object
|
||||
/// </summary>
|
||||
/// <param name="size">the size of the buffer</param>
|
||||
public WriteBuffer(int size)
|
||||
{
|
||||
m_buffer_ptr = Marshal.AllocHGlobal((int)size);
|
||||
BufferSize = size;
|
||||
LogicalBlockAddress = long.MaxValue;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
/// <summary>
|
||||
/// Free the memory associated with this buffer object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Marshal.FreeHGlobal(m_buffer_ptr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill the buffer with all zeros
|
||||
/// </summary>
|
||||
public void Zero()
|
||||
{
|
||||
RtlZeroMemory(m_buffer_ptr, BufferSize) ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill the buffer with data of a specific byte.
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
public void Fill(byte b)
|
||||
{
|
||||
RtlFillMemory(m_buffer_ptr, BufferSize, b);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
284
Bwg.Scsi/WriteBufferPool.cs
Normal file
284
Bwg.Scsi/WriteBufferPool.cs
Normal file
@@ -0,0 +1,284 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class manages a series of buffers that are used to provide data
|
||||
/// for the burning process.
|
||||
/// </summary>
|
||||
public class WriteBufferPool
|
||||
{
|
||||
#region private data members
|
||||
int m_count ;
|
||||
|
||||
private Object m_buffer_list_lock;
|
||||
private IList<WriteBuffer> m_buffer_list;
|
||||
|
||||
private Object m_free_list_lock;
|
||||
private IList<WriteBuffer> m_free_list;
|
||||
|
||||
private bool m_end_of_data;
|
||||
|
||||
private int m_produced;
|
||||
private int m_consumed;
|
||||
|
||||
private int m_pagesize;
|
||||
|
||||
private int m_mult;
|
||||
private bool m_padded;
|
||||
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
/// <summary>
|
||||
/// If this property is true, all data has been pushed into the
|
||||
/// buffer stream.
|
||||
/// </summary>
|
||||
public bool EndOfData
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_end_of_data;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_end_of_data = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns the number of 2k pages that have been produced by
|
||||
/// the generator thread.
|
||||
/// </summary>
|
||||
public int Produced
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_produced;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property returns the number of 2k pages that have been consumed
|
||||
/// by the writer thread.
|
||||
/// </summary>
|
||||
public int Consumed
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_consumed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the size of the pages stored in this buffer pool, in bytes.
|
||||
/// </summary>
|
||||
public int PageSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_pagesize;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the percent of the buffers used
|
||||
/// </summary>
|
||||
public double PercentUsed
|
||||
{
|
||||
get
|
||||
{
|
||||
double v;
|
||||
|
||||
lock (m_buffer_list_lock)
|
||||
{
|
||||
v = (double)m_buffer_list.Count / (double)m_count * 100.0;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the buffer stream by creating the buffers
|
||||
/// </summary>
|
||||
/// <param name="cnt">the number of buffers to create</param>
|
||||
/// <param name="size">the size of each buffer</param>
|
||||
/// <param name="mult">the multiple that each buffer must meet for the device</param>
|
||||
/// <param name="secsize">the size of the sectors in the buffer in bytes</param>
|
||||
public WriteBufferPool(int cnt, int size, int mult, int secsize)
|
||||
{
|
||||
m_count = cnt ;
|
||||
m_end_of_data = false;
|
||||
m_pagesize = size;
|
||||
m_mult = mult;
|
||||
|
||||
//
|
||||
// If the multiple setting is non-zero, we may have to adjust the page size
|
||||
//
|
||||
if (m_mult != 0)
|
||||
{
|
||||
int blocks = size / (mult * secsize);
|
||||
m_pagesize = blocks * mult * secsize;
|
||||
}
|
||||
|
||||
// Used to lock the data buffer list
|
||||
m_buffer_list_lock = new Object();
|
||||
|
||||
// Used to lock the free buffer list
|
||||
m_free_list_lock = new Object();
|
||||
|
||||
// The data buffer list
|
||||
m_buffer_list = new List<WriteBuffer>();
|
||||
|
||||
// THe free buffer list
|
||||
m_free_list = new List<WriteBuffer>() ;
|
||||
|
||||
// Create the buffers and place them all in the
|
||||
// free list.
|
||||
for(int i = 0 ; i < cnt ; i++)
|
||||
m_free_list.Add(new WriteBuffer(size)) ;
|
||||
|
||||
m_produced = 0;
|
||||
m_consumed = 0;
|
||||
|
||||
//
|
||||
// This starts out false and is only set to true if we have to pad
|
||||
// a buffer to reach an appropriate multiple of the multiple count
|
||||
// for this device. We should only have to pad the last buffer sent
|
||||
// to the device. This value is used to detect data being supplied
|
||||
// after having to pad a data buffer, implying that the data put into
|
||||
// the queue did not full the buffer and was not at the end of the
|
||||
// queue.
|
||||
//
|
||||
m_padded = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
/// <summary>
|
||||
/// Get a free write buffer to fill with data
|
||||
/// </summary>
|
||||
/// <returns>a write buffer</returns>
|
||||
public WriteBuffer GetFreeBuffer()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
lock (m_free_list_lock)
|
||||
{
|
||||
if (m_free_list.Count > 0)
|
||||
{
|
||||
Debug.Assert(m_padded == false);
|
||||
WriteBuffer buf = m_free_list[0] ;
|
||||
m_free_list.RemoveAt(0) ;
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (m_end_of_data == true)
|
||||
return null;
|
||||
}
|
||||
|
||||
// Sleep for 10 msec while we wait for buffers to become
|
||||
// availsble.
|
||||
Thread.Sleep(1) ;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a buffer to the list
|
||||
/// </summary>
|
||||
/// <param name="buf"></param>
|
||||
public void SendBufferToDevice(WriteBuffer buf)
|
||||
{
|
||||
lock (m_buffer_list_lock)
|
||||
{
|
||||
if (m_mult != 0 && ((buf.DataSize % m_mult) != 0))
|
||||
System.Diagnostics.Debug.WriteLine("Added a block of " + buf.DataSize.ToString() + " blocks, not an event multiple") ;
|
||||
|
||||
m_buffer_list.Add(buf);
|
||||
m_produced += (int)buf.DataSize;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the next buffer of data from the steam
|
||||
/// </summary>
|
||||
/// <returns>the next buffer stream, or null if all data has been processed</returns>
|
||||
public WriteBuffer GetNextDataBuffer()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
lock (m_buffer_list_lock)
|
||||
{
|
||||
if (m_buffer_list.Count > 0)
|
||||
{
|
||||
WriteBuffer buf = m_buffer_list[0];
|
||||
m_buffer_list.RemoveAt(0);
|
||||
m_consumed += (int)buf.DataSize;
|
||||
|
||||
if (m_mult != 0 && (buf.DataSize % m_mult) != 0)
|
||||
{
|
||||
//
|
||||
// The buffer is not an even multiple of the
|
||||
//
|
||||
m_padded = true;
|
||||
buf.DataSize = ((buf.DataSize / m_mult) + 1) * m_mult;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (m_end_of_data)
|
||||
return null;
|
||||
}
|
||||
|
||||
// Wait for the reader thread to put data into the buffer
|
||||
// stream
|
||||
// Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a buffer back to the free list to be used again
|
||||
/// </summary>
|
||||
/// <param name="buf">the buffer to add to the list</param>
|
||||
public void FreeWriteBuffer(WriteBuffer buf)
|
||||
{
|
||||
lock (m_free_list_lock)
|
||||
{
|
||||
m_free_list.Add(buf);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
267
Bwg.Scsi/WriteBufferStream.cs
Normal file
267
Bwg.Scsi/WriteBufferStream.cs
Normal file
@@ -0,0 +1,267 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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.IO ;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// A stream that pushes the output data through the buffer pool to feed
|
||||
/// the CD/DVD burner.
|
||||
/// </summary>
|
||||
public class WriteBufferStream: Stream
|
||||
{
|
||||
#region private data members
|
||||
|
||||
/// <summary>
|
||||
/// The current length of the stream in bytes
|
||||
/// </summary>
|
||||
private long m_length ;
|
||||
|
||||
/// <summary>
|
||||
/// The buffer pool, used to get buffers to write into and used to send
|
||||
/// buffers to the device.
|
||||
/// </summary>
|
||||
private WriteBufferPool m_pool;
|
||||
|
||||
/// <summary>
|
||||
/// The current buffer we are writing into
|
||||
/// </summary>
|
||||
private WriteBuffer m_buffer;
|
||||
|
||||
/// <summary>
|
||||
/// The size of the sectors that will be sent to the device, in bytes
|
||||
/// </summary>
|
||||
private int m_sector_size;
|
||||
|
||||
/// <summary>
|
||||
/// The number of sectors that fit into a single write buffer
|
||||
/// </summary>
|
||||
private int m_sector_count;
|
||||
|
||||
/// <summary>
|
||||
/// The index into the current write buffer
|
||||
/// </summary>
|
||||
private int m_index;
|
||||
|
||||
/// <summary>
|
||||
/// If true, we are closing
|
||||
/// </summary>
|
||||
private bool m_closing;
|
||||
|
||||
/// <summary>
|
||||
/// The logical block address for the stream data
|
||||
/// </summary>
|
||||
private long m_lba;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructors
|
||||
/// <summary>
|
||||
/// This is a stream class that writes the data to the write buffer pool to be sent
|
||||
/// down to the CD/DVD device.
|
||||
/// </summary>
|
||||
/// <param name="pool">the buffer pool to get pages from and send data to</param>
|
||||
/// <param name="sector_size">the size of the sectors to buffer</param>
|
||||
/// <param name="lba">the logical block address for the first block from this stream</param>
|
||||
public WriteBufferStream(WriteBufferPool pool, int sector_size, long lba)
|
||||
{
|
||||
m_length = 0;
|
||||
m_pool = pool;
|
||||
m_buffer = null;
|
||||
m_index = 0;
|
||||
m_sector_size = sector_size;
|
||||
m_sector_count = m_pool.PageSize / m_sector_size;
|
||||
m_closing = false;
|
||||
m_lba = lba;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override bool CanRead { get { return false; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override bool CanSeek { get { return false; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override bool CanWrite { get { return true ; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override long Length { get { return m_length ; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
|
||||
/// <summary>
|
||||
/// This method flushes any existing data to the device.
|
||||
/// </summary>
|
||||
public override void Flush()
|
||||
{
|
||||
if (m_buffer != null)
|
||||
{
|
||||
//
|
||||
// In general using flush, except when closing the device can be very
|
||||
// dangerous. This method catches those cases where the result sent to
|
||||
// the device would be incorrect and asserts accordingly. Basically we
|
||||
// always send data down to the device in sectors. When we flush we send
|
||||
// down whatever data is left in the buffer. If we are closing, this has
|
||||
// the effect of rounding the last bit of data to a sector boundary. If
|
||||
// we are not closing, it can have the effect of inserting data in the
|
||||
// middle of the data stream. Flusing only works correctly if we are sitting
|
||||
// on the boundary of a sector. Therefore, if this assert has fired it means
|
||||
// we are not closing and not sitting on the boundary of a sector.
|
||||
//
|
||||
Debug.Assert(m_closing || (m_index % m_sector_size) == 0);
|
||||
|
||||
m_buffer.DataSize = m_index / m_sector_size;
|
||||
if ((m_index % m_sector_size) != 0)
|
||||
m_buffer.DataSize++;
|
||||
m_buffer.SectorSize = m_sector_size;
|
||||
|
||||
m_buffer.SourceString = "WriteBufferStream, Flush method";
|
||||
m_buffer.LogicalBlockAddress = m_lba;
|
||||
m_lba = long.MaxValue;
|
||||
m_pool.SendBufferToDevice(m_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="origin"></param>
|
||||
/// <returns></returns>
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="count"></param>
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
while (count > 0)
|
||||
{
|
||||
if (m_buffer == null)
|
||||
{
|
||||
m_buffer = m_pool.GetFreeBuffer();
|
||||
m_index = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Write up to the end of this buffer
|
||||
//
|
||||
int remaining = m_sector_count * m_sector_size - m_index;
|
||||
|
||||
if (remaining > count)
|
||||
remaining = count;
|
||||
|
||||
IntPtr dest = new IntPtr(m_buffer.BufferPtr.ToInt32() + m_index);
|
||||
Marshal.Copy(buffer, offset, dest, remaining);
|
||||
m_index += remaining;
|
||||
m_length += remaining;
|
||||
count -= remaining ;
|
||||
offset += remaining ;
|
||||
|
||||
if (m_index == m_sector_count * m_sector_size)
|
||||
{
|
||||
m_buffer.DataSize = m_index / m_sector_size;
|
||||
m_buffer.SectorSize = m_sector_size;
|
||||
m_buffer.LogicalBlockAddress = m_lba;
|
||||
m_buffer.SourceString = "WriteBufferStream, Write method";
|
||||
m_lba = long.MaxValue;
|
||||
m_pool.SendBufferToDevice(m_buffer);
|
||||
m_buffer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void Close()
|
||||
{
|
||||
m_closing = true;
|
||||
|
||||
Flush();
|
||||
base.Close();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
584
Bwg.Scsi/WriteParameterModePage.cs
Normal file
584
Bwg.Scsi/WriteParameterModePage.cs
Normal file
@@ -0,0 +1,584 @@
|
||||
//
|
||||
// BwgBurn - CD-R/CD-RW/DVD-R/DVD-RW burning program for Windows XP
|
||||
//
|
||||
// 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.Diagnostics;
|
||||
|
||||
namespace Bwg.Scsi
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents mode page 5, Write Parameters Mode Page
|
||||
/// </summary>
|
||||
public class WriteParameterModePage : ModePage
|
||||
{
|
||||
#region public types
|
||||
/// <summary>
|
||||
/// The type of write (packet/incremental, track, session)
|
||||
/// </summary>
|
||||
public enum WriteTypeType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Packet or incremental
|
||||
/// </summary>
|
||||
PacketIncremental = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Track at once
|
||||
/// </summary>
|
||||
TrackAtOnce = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Session at once
|
||||
/// </summary>
|
||||
SessionAtOnce = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Raw data recording
|
||||
/// </summary>
|
||||
Raw = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Layer jump recording
|
||||
/// </summary>
|
||||
LayerJumpRecording = 4
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The multisession state of the write page
|
||||
/// </summary>
|
||||
public enum MultiSessionType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// No B0 pointer, therefore no next session allowed
|
||||
/// </summary>
|
||||
NoNextSession = 0,
|
||||
|
||||
/// <summary>
|
||||
/// B0 pointer equal to 0xFFFFFF, therefore not next session
|
||||
/// allowed
|
||||
/// </summary>
|
||||
CDNoNextSessionFFFF = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Reserved, do not use
|
||||
/// </summary>
|
||||
Reserved = 2,
|
||||
|
||||
/// <summary>
|
||||
/// B0 pointer points to next session
|
||||
/// </summary>
|
||||
NextSessionAllowed = 3
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum TrackModeType : byte
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
TwoChannelAudio = 0x00,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
TwoChannelAudioWithPreemphasis = 0x01,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
DataUninterrupted = 0x04,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
DataIncremental = 0x05,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
FourChannelAudio = 0x08,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
FourChannelAudioWithPreemphasis = 0x09,
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum DataBlockTypeType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Raw data, 2352 bytes
|
||||
/// </summary>
|
||||
RawData = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Raw data with P and Q subchannels, 2368 bytes
|
||||
/// </summary>
|
||||
RawDataWithPAndQ = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Raw data with P - W subchannels packed, 2448 bytes
|
||||
/// </summary>
|
||||
RawDataWithPToWPacked = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Raw data with P - W subchannels raw, 2448 bytes
|
||||
/// </summary>
|
||||
RawDataWithPToWRaw = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Data mode 1, 2048 bytes
|
||||
/// </summary>
|
||||
DataMode1 = 8,
|
||||
|
||||
/// <summary>
|
||||
/// Data mode 2, 2336 bytes
|
||||
/// </summary>
|
||||
DataMode2 = 9,
|
||||
|
||||
/// <summary>
|
||||
/// Data mode 2, sub-header from write params, 2048 bytes
|
||||
/// </summary>
|
||||
DataMode2Form1 = 10,
|
||||
|
||||
/// <summary>
|
||||
/// Data mode 2, sub-header included, 2056 bytes
|
||||
/// </summary>
|
||||
DataMode2Form1Subheader = 11,
|
||||
|
||||
/// <summary>
|
||||
/// Data mode 2, form 2, sub-header from write params, 2324 bytes
|
||||
/// </summary>
|
||||
DataMode2Form2 = 12,
|
||||
|
||||
/// <summary>
|
||||
/// Data mode 2, form 2, sub-header included, 2332 bytes
|
||||
/// </summary>
|
||||
DataMode2Form2Subheader = 13,
|
||||
} ;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum SessionFormatType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// CD DA, CD ROM or other data disk
|
||||
/// </summary>
|
||||
CDDA_CDROM = 0x00,
|
||||
|
||||
/// <summary>
|
||||
/// CD-I disk
|
||||
/// </summary>
|
||||
CD_I = 0x10,
|
||||
|
||||
/// <summary>
|
||||
/// CD-ROM XA Disk
|
||||
/// </summary>
|
||||
CDROM_XA = 0x20,
|
||||
} ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
/// <summary>
|
||||
/// Construct the mode page
|
||||
/// </summary>
|
||||
/// <param name="buffer">pointer to a buffer contains the mode page data</param>
|
||||
/// <param name="size">the size of the buffer area</param>
|
||||
/// <param name="offset">the offset to the mode page</param>
|
||||
public WriteParameterModePage(IntPtr buffer, int size, ref ushort offset)
|
||||
: base(buffer, size, ref offset)
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
/// <summary>
|
||||
/// This property is the burn proof settings on this mode page
|
||||
/// </summary>
|
||||
public bool BurnProof
|
||||
{
|
||||
get
|
||||
{
|
||||
return (m_page_data[2] & 0x40) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
m_page_data[2] |= 0x40;
|
||||
else
|
||||
m_page_data[2] &= 0xbf;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, the link size field is valid. If not true, the link size is assumed to be
|
||||
/// sever (per the SCSI MMC specification).
|
||||
/// </summary>
|
||||
public bool LinkSizeValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return (m_page_data[2] & 0x20) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
m_page_data[2] |= 0x20;
|
||||
else
|
||||
m_page_data[2] &= 0xdf;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, any write will not effect the disk, and the write operation will only be a test. If
|
||||
/// false the writes will go to the disk. This is also known as simulation.
|
||||
/// </summary>
|
||||
public bool TestWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return (m_page_data[2] & 0x10) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
m_page_data[2] |= 0x10;
|
||||
else
|
||||
m_page_data[2] &= 0xef;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property sets the write type
|
||||
/// </summary>
|
||||
public WriteTypeType WriteType
|
||||
{
|
||||
get
|
||||
{
|
||||
return (WriteTypeType)(m_page_data[2] & 0x0f);
|
||||
}
|
||||
set
|
||||
{
|
||||
m_page_data[2] &= 0xf0;
|
||||
m_page_data[2] |= (byte)value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property controls the multi-session mode of the session or track to
|
||||
/// be burned.
|
||||
/// </summary>
|
||||
public MultiSessionType MultiSession
|
||||
{
|
||||
get
|
||||
{
|
||||
return (MultiSessionType)((m_page_data[3] >> 6) & 0x03);
|
||||
}
|
||||
set
|
||||
{
|
||||
Debug.Assert(value != MultiSessionType.Reserved);
|
||||
|
||||
m_page_data[3] &= 0x3F;
|
||||
m_page_data[3] |= (byte)((byte)value << 6);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property controls whether the write mode is fixed packet. This only applies
|
||||
/// if the write type is set to Packet/Incremental.
|
||||
/// </summary>
|
||||
public bool FixedPacket
|
||||
{
|
||||
get
|
||||
{
|
||||
return (m_page_data[3] & 0x20) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
m_page_data[3] |= 0x20;
|
||||
else
|
||||
m_page_data[3] &= 0xdf;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true and the media is CD, SCMS copy protection is enabled.
|
||||
/// </summary>
|
||||
public bool Copy
|
||||
{
|
||||
get
|
||||
{
|
||||
return (m_page_data[3] & 0x10) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
m_page_data[3] |= 0x10;
|
||||
else
|
||||
m_page_data[3] &= 0xef;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The track mode. This should be 5 for DVD media, and is the
|
||||
/// </summary>
|
||||
public TrackModeType TrackMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return (TrackModeType)(m_page_data[3] & 0x0d);
|
||||
}
|
||||
set
|
||||
{
|
||||
m_page_data[3] &= 0xf2;
|
||||
m_page_data[3] |= (byte)value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, digital copy if premitted of the content, otherwise it is not.
|
||||
/// </summary>
|
||||
public bool DigitalCopyPermitted
|
||||
{
|
||||
get
|
||||
{
|
||||
return (m_page_data[3] & 0x02) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
m_page_data[3] |= 0x02;
|
||||
else
|
||||
m_page_data[3] &= 0xfd;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public DataBlockTypeType DataBlockType
|
||||
{
|
||||
get
|
||||
{
|
||||
return (DataBlockTypeType)(m_page_data[4] & 0x0f);
|
||||
}
|
||||
set
|
||||
{
|
||||
m_page_data[4] &= 0xf0;
|
||||
m_page_data[4] |= (byte)value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte LinkSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_page_data[5];
|
||||
}
|
||||
set
|
||||
{
|
||||
m_page_data[5] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte HostApplicationCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)(m_page_data[7] & 0x3f);
|
||||
}
|
||||
set
|
||||
{
|
||||
m_page_data[7] &= 0xc0;
|
||||
m_page_data[7] |= (byte)(value & 0x3f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SessionFormatType SessionFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
return (SessionFormatType)m_page_data[8];
|
||||
}
|
||||
set
|
||||
{
|
||||
m_page_data[8] = (byte)value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int PacketSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return ModeGet32(10);
|
||||
}
|
||||
set
|
||||
{
|
||||
ModeSet32(10, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public ushort AudioPauseLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return ModeGet16(14);
|
||||
}
|
||||
set
|
||||
{
|
||||
ModeSet16(14, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte[] MediaCatalogNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] num = new byte[16];
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
num[i] = m_page_data[16 + i];
|
||||
|
||||
return num;
|
||||
}
|
||||
set
|
||||
{
|
||||
Debug.Assert(value.GetLength(0) == 16);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
m_page_data[16 + i] = value[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte[] InternationalStandardRecordingCode
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] num = new byte[16];
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
num[i] = m_page_data[32 + i];
|
||||
|
||||
return num;
|
||||
}
|
||||
set
|
||||
{
|
||||
Debug.Assert(value.GetLength(0) == 16);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
m_page_data[32 + i] = value[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte SubHeaderByte0
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_page_data[48];
|
||||
}
|
||||
set
|
||||
{
|
||||
m_page_data[48] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte SubHeaderByte1
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_page_data[49];
|
||||
}
|
||||
set
|
||||
{
|
||||
m_page_data[49] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte SubHeaderByte2
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_page_data[50];
|
||||
}
|
||||
set
|
||||
{
|
||||
m_page_data[50] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte SubHeaderByte3
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_page_data[51];
|
||||
}
|
||||
set
|
||||
{
|
||||
m_page_data[51] = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
101
CUETools.Ripper.Console/CUETools.ConsoleRipper.csproj
Normal file
101
CUETools.Ripper.Console/CUETools.ConsoleRipper.csproj
Normal file
@@ -0,0 +1,101 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{9253A314-1821-42BF-B02F-2BF986B1765D}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CUETools.Ripper.Console</RootNamespace>
|
||||
<AssemblyName>CUETools.Ripper.Console</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>..\bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\bin\win32\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>..\bin\win32\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AudioCodecsDotNet\AudioCodecsDotNet.csproj">
|
||||
<Project>{6458A13A-30EF-45A9-9D58-E5031B17BEE2}</Project>
|
||||
<Name>AudioCodecsDotNet</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\CUETools.Ripper.SCSI\CUETools.Ripper.SCSI.csproj">
|
||||
<Project>{8CF07381-BEA2-4AFC-B3DD-9B2F21C65A3A}</Project>
|
||||
<Name>CUETools.Ripper.SCSI</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
146
CUETools.Ripper.Console/Program.cs
Normal file
146
CUETools.Ripper.Console/Program.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
// ****************************************************************************
|
||||
//
|
||||
// CUERipper
|
||||
// Copyright (C) 2008 Gregory S. Chudov (gchudov@gmail.com)
|
||||
//
|
||||
// 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.IO;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using CUETools.Ripper.SCSI;
|
||||
using AudioCodecsDotNet;
|
||||
|
||||
namespace CUETools.ConsoleRipper
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Usage()
|
||||
{
|
||||
Console.WriteLine("Usage : CUETools.Ripper.Console.exe <file.wav>");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
string programVersion = "CUERipper v1.9.3";
|
||||
Console.SetOut(Console.Error);
|
||||
Console.WriteLine("{0}", programVersion);
|
||||
Console.WriteLine("This is free software under the GNU GPLv3+ license; There is NO WARRANTY, to");
|
||||
Console.WriteLine("the extent permitted by law. <http://www.gnu.org/licenses/> for details.");
|
||||
if (args.Length < 1)
|
||||
{
|
||||
Usage();
|
||||
return;
|
||||
}
|
||||
string destFile = args[0];
|
||||
#if !DEBUG
|
||||
try
|
||||
#endif
|
||||
{
|
||||
CDDriveReader audioSource = new CDDriveReader();
|
||||
audioSource.Open('D');
|
||||
|
||||
StreamWriter logWriter = new StreamWriter(Path.ChangeExtension(destFile, ".log"));
|
||||
logWriter.WriteLine("{0}", programVersion);
|
||||
logWriter.WriteLine();
|
||||
logWriter.WriteLine("Extraction logfile from {0}",DateTime.Now);
|
||||
logWriter.WriteLine();
|
||||
logWriter.WriteLine("Used drive : {0}", audioSource.Path);
|
||||
logWriter.WriteLine();
|
||||
logWriter.WriteLine("TOC of the extracted CD");
|
||||
logWriter.WriteLine();
|
||||
logWriter.WriteLine(" Track | Start | Length | Start sector | End sector");
|
||||
logWriter.WriteLine(" ---------------------------------------------------------");
|
||||
for (int track = 0; track < audioSource.TOC.tracks.Count; track++)
|
||||
logWriter.WriteLine("{0,9} | {1,8} | {2,8} | {3,9} | {4,9}",
|
||||
audioSource.TOC.tracks[track].Number,
|
||||
audioSource.TOC.tracks[track].Start.MSF,
|
||||
audioSource.TOC.tracks[track].Length.MSF,
|
||||
audioSource.TOC.tracks[track].Start.Sector,
|
||||
audioSource.TOC.tracks[track].End.Sector);
|
||||
logWriter.Close();
|
||||
|
||||
//audioSource.Close();
|
||||
//return;
|
||||
|
||||
bool toStdout = false;
|
||||
WAVWriter audioDest = new WAVWriter(destFile, audioSource.BitsPerSample, audioSource.ChannelCount, audioSource.SampleRate, toStdout ? Console.OpenStandardOutput() : null);
|
||||
int[,] buff = new int[audioSource.BestBlockSize, audioSource.ChannelCount];
|
||||
|
||||
Console.WriteLine("Filename : {0}", destFile);
|
||||
Console.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.SampleRate, audioSource.ChannelCount, audioSource.BitsPerSample, TimeSpan.FromSeconds(audioSource.Length * 1.0 / audioSource.SampleRate));
|
||||
audioDest.FinalSampleCount = (long) audioSource.Length;
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
TimeSpan lastPrint = TimeSpan.FromMilliseconds(0);
|
||||
|
||||
do
|
||||
{
|
||||
uint samplesRead = audioSource.Read(buff, Math.Min((uint)buff.GetLength(0), (uint)audioSource.Remaining));
|
||||
if (samplesRead == 0) break;
|
||||
audioDest.Write(buff, samplesRead);
|
||||
TimeSpan elapsed = DateTime.Now - start;
|
||||
if ((elapsed - lastPrint).TotalMilliseconds > 60)
|
||||
{
|
||||
Console.Error.Write("\rProgress : {0:00}%; {1:0.00}x; {2}/{3}",
|
||||
100.0 * audioSource.Position / audioSource.Length,
|
||||
audioSource.Position / elapsed.TotalSeconds / audioSource.SampleRate,
|
||||
elapsed,
|
||||
TimeSpan.FromMilliseconds(elapsed.TotalMilliseconds / audioSource.Position * audioSource.Length)
|
||||
);
|
||||
lastPrint = elapsed;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
TimeSpan totalElapsed = DateTime.Now - start;
|
||||
Console.Error.Write("\r \r");
|
||||
Console.WriteLine("Results : {0:0.00}x; {1}",
|
||||
audioSource.Length / totalElapsed.TotalSeconds / audioSource.SampleRate,
|
||||
totalElapsed
|
||||
);
|
||||
audioDest.Close();
|
||||
|
||||
StreamWriter cueWriter = new StreamWriter(Path.ChangeExtension(destFile, ".cue"));
|
||||
cueWriter.WriteLine("REM DISCID {0}", audioSource.TOC._cddbId);
|
||||
cueWriter.WriteLine("REM ACCURATERIPID {0}", audioSource.TOC._ArId);
|
||||
cueWriter.WriteLine("REM COMMENT \"{0}\"", programVersion);
|
||||
if (audioSource.TOC._catalog != null)
|
||||
cueWriter.WriteLine("CATALOG {0}", audioSource.TOC._catalog);
|
||||
cueWriter.WriteLine("FILE \"{0}\" WAVE", destFile);
|
||||
for (int track = 0; track < audioSource.TOC.tracks.Count; track++)
|
||||
{
|
||||
cueWriter.WriteLine(" TRACK {0:00} AUDIO", audioSource.TOC.tracks[track].Number);
|
||||
for (int index = 0; index < audioSource.TOC.tracks[track].indexes.Count; index ++)
|
||||
cueWriter.WriteLine(" INDEX {0:00} {1}", audioSource.TOC.tracks[track].indexes[index].Index, audioSource.TOC.tracks[track].indexes[index].MSF);
|
||||
}
|
||||
cueWriter.Close();
|
||||
|
||||
audioSource.Close();
|
||||
}
|
||||
#if !DEBUG
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Error: {0}", ex.Message);
|
||||
Console.WriteLine("{0}", ex.StackTrace);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
33
CUETools.Ripper.Console/Properties/AssemblyInfo.cs
Normal file
33
CUETools.Ripper.Console/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("CUETools.Ripper.Console")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("CUETools.Ripper.Console")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("2d93abce-7d63-4ac0-aa16-faef013f987e")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
109
CUETools.Ripper.SCSI/CUETools.Ripper.SCSI.csproj
Normal file
109
CUETools.Ripper.SCSI/CUETools.Ripper.SCSI.csproj
Normal file
@@ -0,0 +1,109 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{8CF07381-BEA2-4AFC-B3DD-9B2F21C65A3A}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CUETools.Ripper.SCSI</RootNamespace>
|
||||
<AssemblyName>CUETools.Ripper.SCSI</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>..\bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\bin\win32\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>..\bin\win32\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files (x86)\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SCSIDrive.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AudioCodecsDotNet\AudioCodecsDotNet.csproj">
|
||||
<Project>{6458A13A-30EF-45A9-9D58-E5031B17BEE2}</Project>
|
||||
<Name>AudioCodecsDotNet</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Bwg.Logging\Bwg.Logging.csproj">
|
||||
<Project>{F2DFEB00-BB35-4665-85EA-CB8C7729A6B7}</Project>
|
||||
<Name>Bwg.Logging</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Bwg.Scsi\Bwg.Scsi.csproj">
|
||||
<Project>{A05B6AA6-0EC3-495D-BCC4-ECE1210071A8}</Project>
|
||||
<Name>Bwg.Scsi</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
35
CUETools.Ripper.SCSI/Properties/AssemblyInfo.cs
Normal file
35
CUETools.Ripper.SCSI/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("CUETools.Ripper.SCSI")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("CUETools.Ripper.SCSI")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("f80546ea-7f0c-4a5a-bcf3-fe53820a5bfe")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
452
CUETools.Ripper.SCSI/SCSIDrive.cs
Normal file
452
CUETools.Ripper.SCSI/SCSIDrive.cs
Normal file
@@ -0,0 +1,452 @@
|
||||
// ****************************************************************************
|
||||
//
|
||||
// CUERipper
|
||||
// Copyright (C) 2008 Gregory S. Chudov (gchudov@gmail.com)
|
||||
//
|
||||
// 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.Runtime.InteropServices;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Text;
|
||||
using Bwg.Scsi;
|
||||
using Bwg.Logging;
|
||||
using AudioCodecsDotNet;
|
||||
|
||||
namespace CUETools.Ripper.SCSI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CDDriveReader : IAudioSource
|
||||
{
|
||||
byte[] cdtext = null;
|
||||
private Device m_device;
|
||||
uint _sampleOffset = 0;
|
||||
uint _samplesInBuffer = 0;
|
||||
uint _samplesBufferOffset = 0;
|
||||
uint _samplesBufferSector = 0;
|
||||
const int CB_AUDIO = 588 * 4 + 16;
|
||||
const int NSECTORS = 32;
|
||||
int _currentTrack = -1, _currentIndex = -1, _currentTrackActualStart = -1;
|
||||
Logger m_logger = null;
|
||||
CDImage _toc;
|
||||
|
||||
public CDImage TOC
|
||||
{
|
||||
get
|
||||
{
|
||||
return _toc;
|
||||
}
|
||||
}
|
||||
|
||||
public CDDriveReader()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Open(char Drive)
|
||||
{
|
||||
Device.CommandStatus st;
|
||||
|
||||
// Open the base device
|
||||
m_device = new Device(m_logger);
|
||||
if (!m_device.Open(Drive))
|
||||
throw new Exception("SCSI error");
|
||||
|
||||
//// Open/Initialize the driver
|
||||
//Drive m_drive = new Drive(dev);
|
||||
//DiskOperationError status = m_drive.Initialize();
|
||||
//if (status != null)
|
||||
// throw new Exception("SCSI error");
|
||||
|
||||
// {
|
||||
//Drive.FeatureState readfeature = m_drive.GetFeatureState(Feature.FeatureType.CDRead);
|
||||
//if (readfeature == Drive.FeatureState.Error || readfeature == Drive.FeatureState.NotPresent)
|
||||
// throw new Exception("SCSI error");
|
||||
// }{
|
||||
//st = m_device.GetConfiguration(Device.GetConfigType.OneFeature, 0, out flist);
|
||||
//if (st != Device.CommandStatus.Success)
|
||||
// return CreateErrorObject(st, m_device);
|
||||
|
||||
//Feature f = flist.Features[0];
|
||||
//ParseProfileList(f.Data);
|
||||
// }
|
||||
|
||||
SpeedDescriptorList speed_list;
|
||||
st = m_device.GetSpeed(out speed_list);
|
||||
if (st != Device.CommandStatus.Success)
|
||||
throw new Exception("SCSI error");
|
||||
|
||||
st = m_device.SetCdSpeed(Device.RotationalControl.CLVandNonPureCav, Device.OptimumSpeed, Device.OptimumSpeed);
|
||||
if (st != Device.CommandStatus.Success)
|
||||
throw new Exception("SCSI error");
|
||||
|
||||
IList<TocEntry> toc;
|
||||
st = m_device.ReadToc((byte)0, false, out toc);
|
||||
if (st != Device.CommandStatus.Success)
|
||||
throw new Exception("SCSI error");
|
||||
|
||||
st = m_device.ReadCDText(out cdtext);
|
||||
// new CDTextEncoderDecoder
|
||||
|
||||
_toc = new CDImage(toc[toc.Count - 1].StartSector);
|
||||
uint cddbDiscId = 0;
|
||||
uint discId1 = 0;
|
||||
uint discId2 = 0;
|
||||
for (int iTrack = 0; iTrack < toc.Count - 1; iTrack++)
|
||||
{
|
||||
_toc.tracks.Add(new CDTrack((uint)iTrack + 1, toc[iTrack].StartSector,
|
||||
toc[iTrack + 1].StartSector - toc[iTrack].StartSector));
|
||||
discId1 += toc[iTrack].StartSector;
|
||||
discId2 += (toc[iTrack].StartSector == 0 ? 1 : toc[iTrack].StartSector) * ((uint)iTrack + 1);
|
||||
cddbDiscId += sumDigits((uint)(toc[iTrack].StartSector / 75) + 2);
|
||||
}
|
||||
discId1 += toc[toc.Count - 1].StartSector;
|
||||
discId2 += (toc[toc.Count - 1].StartSector == 0 ? 1 : toc[toc.Count - 1].StartSector) * ((uint)toc.Count);
|
||||
discId1 &= 0xFFFFFFFF;
|
||||
discId2 &= 0xFFFFFFFF;
|
||||
cddbDiscId = (((cddbDiscId % 255) << 24) +
|
||||
(((uint)(toc[toc.Count - 1].StartSector / 75) - (uint)(toc[0].StartSector / 75)) << 8) +
|
||||
(uint)(toc.Count - 1)) & 0xFFFFFFFF;
|
||||
_toc._cddbId = string.Format("{0:X8}", cddbDiscId);
|
||||
_toc._ArId = string.Format("{0:x8}-{1:x8}-{2:x8}", discId1, discId2, cddbDiscId);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
_toc = null;
|
||||
}
|
||||
|
||||
public int BestBlockSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return Math.Min(m_device.MaximumTransferLength / CB_AUDIO, NSECTORS) * 588;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe uint Read(int[,] buff, uint sampleCount)
|
||||
{
|
||||
if (_toc == null)
|
||||
throw new Exception("invalid TOC");
|
||||
if (_sampleOffset >= (uint)Length)
|
||||
return 0;
|
||||
if (_sampleOffset + sampleCount > Length)
|
||||
sampleCount = (uint)Length - _sampleOffset;
|
||||
uint pos = 0;
|
||||
if (_samplesInBuffer > 0)
|
||||
{
|
||||
uint samplesRead = Math.Min(_samplesInBuffer, sampleCount);
|
||||
AudioSamples.BytesToFLACSamples_16(_sectorBuffer, (int)(_samplesBufferSector * (588 * 4 + 16) + _samplesBufferOffset * 4), buff, (int)pos, samplesRead, 2);
|
||||
pos += samplesRead;
|
||||
sampleCount -= samplesRead;
|
||||
_sampleOffset += samplesRead;
|
||||
if (sampleCount == 0)
|
||||
{
|
||||
_samplesInBuffer -= samplesRead;
|
||||
_samplesBufferOffset += samplesRead;
|
||||
return pos;
|
||||
}
|
||||
_samplesInBuffer = 0;
|
||||
_samplesBufferOffset = 0;
|
||||
_samplesBufferSector = 0;
|
||||
}
|
||||
// if (_sampleOffset < PreGapLength && !_overreadIntoPreGap ... ?
|
||||
int firstSector = (int)_sampleOffset / 588;
|
||||
int lastSector = (int)(_sampleOffset + sampleCount + 577) / 588;
|
||||
for (int sector = firstSector; sector < lastSector; sector += NSECTORS)
|
||||
{
|
||||
int Sectors2Read = ((sector + NSECTORS) < lastSector) ? NSECTORS : (lastSector - sector);
|
||||
fixed (byte* data = _sectorBuffer)
|
||||
{
|
||||
Device.CommandStatus st = m_device.ReadCDAndSubChannel(2, 1, true, (uint)sector, (uint)Sectors2Read, (IntPtr)((void*)data), Sectors2Read * (2352 + 16));
|
||||
if (st != Device.CommandStatus.Success)
|
||||
throw new Exception("SCSI error");
|
||||
}
|
||||
for (int iSector = 0; iSector < Sectors2Read; iSector++)
|
||||
{
|
||||
uint samplesRead = Math.Min(sampleCount, 588U) - (_sampleOffset % 588);
|
||||
AudioSamples.BytesToFLACSamples_16(_sectorBuffer, iSector * (588 * 4 + 16) + ((int)_sampleOffset % 588) * 4, buff, (int)pos, samplesRead, 2);
|
||||
{
|
||||
int q_pos = (iSector + 1) * (588 * 4 + 16) - 16;
|
||||
int ctl = _sectorBuffer[q_pos + 0] >> 4;
|
||||
int adr = _sectorBuffer[q_pos + 0] & 7;
|
||||
bool preemph = (ctl == 1);
|
||||
switch (adr)
|
||||
{
|
||||
case 1: // current position
|
||||
{
|
||||
int iTrack = fromBCD(_sectorBuffer[q_pos + 1]);
|
||||
int iIndex = fromBCD(_sectorBuffer[q_pos + 2]);
|
||||
if (iTrack != _currentTrack)
|
||||
{
|
||||
_currentTrack = iTrack;
|
||||
_currentTrackActualStart = sector + iSector;
|
||||
_currentIndex = iIndex;
|
||||
if (_currentIndex == 1)
|
||||
_toc.tracks[iTrack - 1].indexes.Add(new CDTrackIndex(1, _toc.tracks[iTrack - 1].Start.Sector));
|
||||
else if (_currentIndex != 0)
|
||||
throw new Exception("invalid index");
|
||||
}
|
||||
else
|
||||
if (iIndex != _currentIndex)
|
||||
{
|
||||
if (iIndex != _currentIndex + 1)
|
||||
throw new Exception("invalid index");
|
||||
_currentIndex = iIndex;
|
||||
if (_currentIndex == 1)
|
||||
{
|
||||
int pregap = sector + iSector - _currentTrackActualStart;
|
||||
_toc.tracks[iTrack - 1].indexes.Add(new CDTrackIndex(0, (uint)(_toc.tracks[iTrack - 1].Start.Sector - pregap)));
|
||||
_currentTrackActualStart = sector + iSector;
|
||||
}
|
||||
_toc.tracks[iTrack - 1].indexes.Add(new CDTrackIndex((uint)iIndex, (uint)(_toc.tracks[iTrack - 1].Start.Sector + sector + iSector - _currentTrackActualStart)));
|
||||
_currentIndex = iIndex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: // catalog
|
||||
if (_toc._catalog == null)
|
||||
{
|
||||
StringBuilder catalog = new StringBuilder();
|
||||
for (int i = 1; i < 8; i++)
|
||||
catalog.AppendFormat("{0:x2}", _sectorBuffer[q_pos + i]);
|
||||
_toc._catalog = catalog.ToString(0, 13);
|
||||
}
|
||||
break;
|
||||
case 3: //isrc
|
||||
break;
|
||||
}
|
||||
}
|
||||
pos += samplesRead;
|
||||
sampleCount -= samplesRead;
|
||||
_sampleOffset += samplesRead;
|
||||
if (sampleCount == 0)
|
||||
{
|
||||
_samplesBufferSector = (uint)iSector;
|
||||
_samplesBufferOffset = samplesRead;
|
||||
_samplesInBuffer = 588U - samplesRead;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
public ulong Length
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_toc == null)
|
||||
throw new Exception("invalid TOC");
|
||||
return (ulong)588 * _toc.Length.Sector;
|
||||
}
|
||||
}
|
||||
|
||||
public int BitsPerSample
|
||||
{
|
||||
get
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
||||
public int ChannelCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
public int SampleRate
|
||||
{
|
||||
get
|
||||
{
|
||||
return 44100;
|
||||
}
|
||||
}
|
||||
|
||||
public NameValueCollection Tags
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_device.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public ulong Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sampleOffset;
|
||||
}
|
||||
set
|
||||
{
|
||||
_sampleOffset = (uint)value;
|
||||
}
|
||||
}
|
||||
|
||||
public ulong Remaining
|
||||
{
|
||||
get
|
||||
{
|
||||
return Length - Position;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] _sectorBuffer = new byte[CB_AUDIO * NSECTORS];
|
||||
|
||||
private int fromBCD(byte hex)
|
||||
{
|
||||
return (hex >> 4) * 10 + (hex & 15);
|
||||
}
|
||||
|
||||
private uint sumDigits(uint n)
|
||||
{
|
||||
uint r = 0;
|
||||
while (n > 0)
|
||||
{
|
||||
r = r + (n % 10);
|
||||
n = n / 10;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
public class CDTrackIndex
|
||||
{
|
||||
public CDTrackIndex(uint index, uint sector)
|
||||
{
|
||||
_sector = sector;
|
||||
_index = index;
|
||||
}
|
||||
|
||||
public uint Sector
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sector;
|
||||
}
|
||||
}
|
||||
|
||||
public uint Index
|
||||
{
|
||||
get
|
||||
{
|
||||
return _index;
|
||||
}
|
||||
}
|
||||
|
||||
public string MSF
|
||||
{
|
||||
get
|
||||
{
|
||||
return new MinuteSecondFrame(_sector).ToString("M:S:F");
|
||||
}
|
||||
}
|
||||
|
||||
uint _sector;
|
||||
uint _index;
|
||||
}
|
||||
|
||||
public class CDTrack
|
||||
{
|
||||
public CDTrack(uint number, uint start, uint length)
|
||||
{
|
||||
_number = number;
|
||||
_start = start;
|
||||
_length = length;
|
||||
indexes = new List<CDTrackIndex>();
|
||||
}
|
||||
|
||||
public CDTrackIndex Start
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CDTrackIndex(0, _start);
|
||||
}
|
||||
}
|
||||
|
||||
public CDTrackIndex Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CDTrackIndex(0, _length);
|
||||
}
|
||||
}
|
||||
|
||||
public CDTrackIndex End
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CDTrackIndex(0, _start + _length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public uint Number
|
||||
{
|
||||
get
|
||||
{
|
||||
return _number;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<CDTrackIndex> indexes;
|
||||
|
||||
uint _start;
|
||||
uint _length;
|
||||
uint _number;
|
||||
}
|
||||
|
||||
public class CDImage
|
||||
{
|
||||
public CDImage(uint length)
|
||||
{
|
||||
tracks = new List<CDTrack>();
|
||||
_length = length;
|
||||
}
|
||||
|
||||
public IList<CDTrack> tracks;
|
||||
|
||||
public CDTrackIndex Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CDTrackIndex(0, _length);
|
||||
}
|
||||
}
|
||||
|
||||
public string _catalog;
|
||||
public string _cddbId;
|
||||
public string _ArId;
|
||||
uint _length;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user