2017-06-03 01:10:46 +01:00
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ScsiModeSense.cs
2017-12-19 03:50:57 +00:00
// Author(s) : Natalia Portillo <claunia@claunia.com>
2017-06-03 01:10:46 +01:00
//
2017-12-19 03:50:57 +00:00
// Component : DiscImageChef Server.
2017-06-03 01:10:46 +01:00
//
// --[ Description ] ----------------------------------------------------------
//
2017-12-19 03:50:57 +00:00
// Decodes SCSI MODE PAGEs from reports.
2017-06-03 01:10:46 +01:00
//
// --[ License ] --------------------------------------------------------------
//
2017-12-19 03:50:57 +00:00
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
2017-06-03 01:10:46 +01:00
// License, or (at your option) any later version.
//
2017-12-19 03:50:57 +00:00
// This library 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
// Lesser General Public License for more details.
2017-06-03 01:10:46 +01:00
//
2017-12-19 03:50:57 +00:00
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
2017-06-03 01:10:46 +01:00
//
// ----------------------------------------------------------------------------
2017-12-19 03:50:57 +00:00
// Copyright © 2011-2018 Natalia Portillo
2017-06-03 01:10:46 +01:00
// ****************************************************************************/
2017-12-19 03:50:57 +00:00
2017-06-03 01:19:47 +01:00
using System.Collections.Generic ;
using DiscImageChef.Decoders.SCSI ;
2017-12-19 19:33:46 +00:00
using DiscImageChef.Metadata ;
2017-06-03 01:10:46 +01:00
namespace DiscImageChef.Server.App_Start
{
2017-06-03 01:19:47 +01:00
public static class ScsiModeSense
2017-06-03 01:10:46 +01:00
{
2017-12-23 02:57:47 +00:00
/// <summary>
/// Takes the MODE PAGEs part of a device report and prints it as a list of values and another list of key=value pairs to be sequenced by ASP.NET in the rendering
/// </summary>
/// <param name="modeSense">MODE PAGEs part of a device report</param>
/// <param name="vendor">SCSI vendor string</param>
/// <param name="deviceType">SCSI peripheral device type</param>
/// <param name="scsiOneValue">List to put values on</param>
/// <param name="modePages">List to put key=value pairs on</param>
2017-12-19 20:33:03 +00:00
public static void Report ( modeType modeSense , string vendor , PeripheralDeviceTypes deviceType ,
ref List < string > scsiOneValue , ref Dictionary < string , string > modePages )
2017-06-03 01:10:46 +01:00
{
2017-06-03 01:19:47 +01:00
if ( modeSense . MediumTypeSpecified )
2017-12-21 17:58:51 +00:00
scsiOneValue . Add ( $"Medium type is {modeSense.MediumType:X2}h" ) ;
2017-12-19 20:33:03 +00:00
if ( modeSense . WriteProtected ) scsiOneValue . Add ( "Device is write protected." ) ;
2017-06-03 01:19:47 +01:00
if ( modeSense . BlockDescriptors ! = null )
foreach ( blockDescriptorType descriptor in modeSense . BlockDescriptors )
if ( descriptor . BlocksSpecified & & descriptor . BlockLengthSpecified )
2017-12-21 17:58:51 +00:00
scsiOneValue . Add ( $"Density code {descriptor.Density:X2}h has {descriptor.Blocks} blocks of {descriptor.BlockLength} bytes each" ) ;
else scsiOneValue . Add ( $"Density code {descriptor.Density:X2}h" ) ;
2017-12-19 20:33:03 +00:00
if ( modeSense . DPOandFUA ) scsiOneValue . Add ( "Drive supports DPO and FUA bits" ) ;
if ( modeSense . BlankCheckEnabled ) scsiOneValue . Add ( "Blank checking during write is enabled" ) ;
2017-06-03 01:19:47 +01:00
if ( modeSense . BufferedModeSpecified )
switch ( modeSense . BufferedMode )
{
case 0 :
scsiOneValue . Add ( "Device writes directly to media" ) ;
break ;
case 1 :
scsiOneValue . Add ( "Device uses a write cache" ) ;
break ;
case 2 :
scsiOneValue . Add ( "Device uses a write cache but doesn't return until cache is flushed" ) ;
break ;
default :
2017-12-21 17:58:51 +00:00
scsiOneValue . Add ( $"Unknown buffered mode code 0x{modeSense.BufferedMode:X2}" ) ;
2017-06-03 01:19:47 +01:00
break ;
}
2017-12-21 06:06:19 +00:00
if ( modeSense . ModePages = = null ) return ;
foreach ( modePageType page in modeSense . ModePages )
switch ( page . page )
{
case 0x00 :
2017-06-03 01:19:47 +01:00
{
2017-12-21 06:06:19 +00:00
if ( deviceType = = PeripheralDeviceTypes . MultiMediaDevice & & page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_00_SFF ( page . value ) ) ;
else
2017-12-19 20:33:03 +00:00
{
2017-12-22 18:17:36 +00:00
modePages
. Add ( page . subpage ! = 0 ? $"MODE page {page.page:X2}h subpage {page.subpage:X2}h" : $"MODE page {page.page:X2}h" ,
"Unknown vendor mode page" ) ;
2017-12-19 20:33:03 +00:00
}
2017-12-21 06:06:19 +00:00
break ;
}
case 0x01 :
{
if ( page . subpage = = 0 )
2017-12-22 18:17:36 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
deviceType = = PeripheralDeviceTypes . MultiMediaDevice
? Modes . PrettifyModePage_01_MMC ( page . value )
: Modes . PrettifyModePage_01 ( page . value ) ) ;
2017-12-21 06:06:19 +00:00
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x02 :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_02 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x03 :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_03 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x04 :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_04 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x05 :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_05 ( page . value ) ) ;
else goto default ;
break ;
}
case 0x06 :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_06 ( page . value ) ) ;
else goto default ;
break ;
}
case 0x07 :
{
if ( page . subpage = = 0 )
2017-12-22 18:17:36 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
deviceType = = PeripheralDeviceTypes . MultiMediaDevice
? Modes . PrettifyModePage_07_MMC ( page . value )
: Modes . PrettifyModePage_07 ( page . value ) ) ;
2017-12-21 06:06:19 +00:00
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x08 :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_08 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x0A :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_0A ( page . value ) ) ;
else if ( page . subpage = = 1 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_0A_S01 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x0B :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_0B ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x0D :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_0D ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x0E :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_0E ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x0F :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_0F ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x10 :
{
if ( page . subpage = = 0 )
2017-12-22 18:17:36 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
deviceType = = PeripheralDeviceTypes . SequentialAccess
? Modes . PrettifyModePage_10_SSC ( page . value )
: Modes . PrettifyModePage_10 ( page . value ) ) ;
2017-12-21 06:06:19 +00:00
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x11 :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_11 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x12 :
case 0x13 :
case 0x14 :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_12_13_14 ( page . value ) ) ;
else goto default ;
2017-12-19 20:33:03 +00:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x1A :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_1A ( page . value ) ) ;
else if ( page . subpage = = 1 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_1A_S01 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x1B :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_1B ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x1C :
{
if ( page . subpage = = 0 )
2017-12-22 18:17:36 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
deviceType = = PeripheralDeviceTypes . MultiMediaDevice
? Modes . PrettifyModePage_1C_SFF ( page . value )
: Modes . PrettifyModePage_1C ( page . value ) ) ;
2017-12-21 06:06:19 +00:00
else if ( page . subpage = = 1 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_1C_S01 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x1D :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_1D ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x21 :
{
if ( vendor = = "CERTANCE" )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyCertanceModePage_21 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x22 :
{
if ( vendor = = "CERTANCE" )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyCertanceModePage_22 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x24 :
{
if ( vendor = = "IBM" )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyIBMModePage_24 ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x2A :
{
if ( page . subpage = = 0 )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyModePage_2A ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x2F :
{
if ( vendor = = "IBM" )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyIBMModePage_2F ( page . value ) ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
}
case 0x30 :
{
if ( Modes . IsAppleModePage_30 ( page . value ) )
modePages . Add ( "MODE page 30h" , "Drive identifies as an Apple OEM drive" ) ;
else goto default ;
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
break ;
2017-06-03 01:19:47 +01:00
}
2017-12-21 06:06:19 +00:00
case 0x3B :
{
if ( vendor = = "HP" )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyHPModePage_3B ( page . value ) ) ;
else goto default ;
break ;
}
case 0x3C :
{
if ( vendor = = "HP" )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyHPModePage_3C ( page . value ) ) ;
else goto default ;
break ;
}
case 0x3D :
{
if ( vendor = = "IBM" )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyIBMModePage_3D ( page . value ) ) ;
else if ( vendor = = "HP" )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyHPModePage_3D ( page . value ) ) ;
else goto default ;
break ;
}
case 0x3E :
{
if ( vendor = = "FUJITSU" )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyFujitsuModePage_3E ( page . value ) ) ;
else if ( vendor = = "HP" )
2017-12-21 17:58:51 +00:00
modePages . Add ( $"MODE page {page.page:X2}h" ,
2017-12-21 06:06:19 +00:00
Modes . PrettifyHPModePage_3E ( page . value ) ) ;
else goto default ;
break ;
}
default :
{
2017-12-22 18:17:36 +00:00
modePages . Add ( page . subpage ! = 0 ? $"MODE page {page.page:X2}h subpage {page.subpage:X2}h" : $"MODE page {page.page:X2}h" ,
"Unknown mode page" ) ;
2017-12-21 06:06:19 +00:00
}
break ;
}
2017-06-03 01:19:47 +01:00
2017-12-21 06:06:19 +00:00
Dictionary < string , string > newModePages = new Dictionary < string , string > ( ) ;
foreach ( KeyValuePair < string , string > kvp in modePages )
if ( string . IsNullOrWhiteSpace ( kvp . Value ) ) newModePages . Add ( kvp . Key , "Undecoded" ) ;
else newModePages . Add ( kvp . Key , kvp . Value . Replace ( "\n" , "<br/>" ) ) ;
2017-12-19 20:33:03 +00:00
2017-12-21 06:06:19 +00:00
modePages = newModePages ;
2017-06-03 01:10:46 +01:00
}
}
2017-12-19 20:33:03 +00:00
}