Files
Aaru/DiscImageChef.Server/ViewReport.aspx.cs

608 lines
33 KiB
C#

// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ViewReport.aspx.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : DiscImageChef Server.
//
// --[ Description ] ----------------------------------------------------------
//
// Renders a device report.
//
// --[ License ] --------------------------------------------------------------
//
// 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
// License, or (at your option) any later version.
//
// 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.
//
// 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/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web;
using System.Xml.Serialization;
using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Metadata;
using DiscImageChef.Server.App_Start;
namespace DiscImageChef.Server
{
public partial class ViewReport : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
string manufacturer = Request.QueryString["manufacturer"];
string model = Request.QueryString["model"];
string revision = Request.QueryString["revision"];
// Strip non-ascii, strip slashes and question marks
if(manufacturer != null)
manufacturer = Encoding
.ASCII.GetString(Encoding.Convert(Encoding.UTF8, Encoding.ASCII,
Encoding.UTF8.GetBytes(manufacturer))).Replace('/', '_')
.Replace('\\', '_').Replace('?', '_');
if(model != null)
model = Encoding
.ASCII.GetString(Encoding.Convert(Encoding.UTF8, Encoding.ASCII, Encoding.UTF8.GetBytes(model)))
.Replace('/', '_').Replace('\\', '_').Replace('?', '_');
if(revision != null)
revision = Encoding
.ASCII.GetString(Encoding.Convert(Encoding.UTF8, Encoding.ASCII,
Encoding.UTF8.GetBytes(revision))).Replace('/', '_')
.Replace('\\', '_').Replace('?', '_');
string xmlFile = null;
if(!string.IsNullOrWhiteSpace(manufacturer) && !string.IsNullOrWhiteSpace(model) &&
!string.IsNullOrWhiteSpace(revision)) xmlFile = manufacturer + "_" + model + "_" + revision + ".xml";
else if(!string.IsNullOrWhiteSpace(manufacturer) && !string.IsNullOrWhiteSpace(model))
xmlFile = manufacturer + "_" + model + ".xml";
else if(!string.IsNullOrWhiteSpace(model) && !string.IsNullOrWhiteSpace(revision))
xmlFile = model + "_" + revision + ".xml";
else if(!string.IsNullOrWhiteSpace(model)) xmlFile = model + ".xml";
if(xmlFile == null ||
!File.Exists(Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~"), "Reports", xmlFile)))
{
content.InnerHtml = "<b>Could not find the specified report</b>";
return;
}
lblManufacturer.Text = Request.QueryString["manufacturer"];
lblModel.Text = Request.QueryString["model"];
lblRevision.Text = Request.QueryString["revision"];
DeviceReport report = new DeviceReport();
XmlSerializer xs = new XmlSerializer(report.GetType());
StreamReader sr =
new StreamReader(Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~"), "Reports",
xmlFile));
report = (DeviceReport)xs.Deserialize(sr);
sr.Close();
if(report.USB != null)
{
string usbVendorDescription = null;
string usbProductDescription = null;
GetUsbDescriptions(report.USB.VendorID, report.USB.ProductID, out usbVendorDescription,
out usbProductDescription);
lblUsbManufacturer.Text = HttpUtility.HtmlEncode(report.USB.Manufacturer);
lblUsbProduct.Text = HttpUtility.HtmlEncode(report.USB.Product);
lblUsbVendor.Text = string.Format("0x{0:x4}", report.USB.VendorID);
if(usbVendorDescription != null)
lblUsbVendorDescription.Text =
string.Format("({0})", HttpUtility.HtmlEncode(usbVendorDescription));
lblUsbProductId.Text = string.Format("0x{0:x4}", report.USB.ProductID);
if(usbProductDescription != null)
lblUsbProductDescription.Text =
string.Format("({0})", HttpUtility.HtmlEncode(usbProductDescription));
}
else divUsb.Visible = false;
if(report.FireWire != null)
{
lblFirewireManufacturer.Text = HttpUtility.HtmlEncode(report.FireWire.Manufacturer);
lblFirewireProduct.Text = HttpUtility.HtmlEncode(report.FireWire.Product);
lblFirewireVendor.Text = string.Format("0x{0:x8}", report.FireWire.VendorID);
lblFirewireProductId.Text = string.Format("0x{0:x8}", report.FireWire.ProductID);
}
else divFirewire.Visible = false;
if(report.PCMCIA != null)
{
lblPcmciaManufacturer.Text = HttpUtility.HtmlEncode(report.PCMCIA.Manufacturer);
lblPcmciaProduct.Text = HttpUtility.HtmlEncode(report.PCMCIA.ProductName);
lblPcmciaManufacturerCode.Text = string.Format("0x{0:x4}", report.PCMCIA.ManufacturerCode);
lblPcmciaCardCode.Text = string.Format("0x{0:x4}", report.PCMCIA.CardCode);
lblPcmciaCompliance.Text = HttpUtility.HtmlEncode(report.PCMCIA.Compliance);
Decoders.PCMCIA.Tuple[] tuples = Decoders.PCMCIA.CIS.GetTuples(report.PCMCIA.CIS);
if(tuples != null)
{
Dictionary<string, string> decodedTuples = new Dictionary<string, string>();
foreach(Decoders.PCMCIA.Tuple tuple in tuples)
switch(tuple.Code)
{
case Decoders.PCMCIA.TupleCodes.CISTPL_NULL:
case Decoders.PCMCIA.TupleCodes.CISTPL_END:
case Decoders.PCMCIA.TupleCodes.CISTPL_MANFID:
case Decoders.PCMCIA.TupleCodes.CISTPL_VERS_1: break;
case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICEGEO:
case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICEGEO_A:
Decoders.PCMCIA.DeviceGeometryTuple geom =
Decoders.PCMCIA.CIS.DecodeDeviceGeometryTuple(tuple.Data);
if(geom != null && geom.Geometries != null)
foreach(Decoders.PCMCIA.DeviceGeometry geometry in geom.Geometries)
{
decodedTuples.Add("Device width",
string.Format("{0} bits",
(1 << (geometry.CardInterface - 1)) * 8));
decodedTuples.Add("Erase block",
string.Format("{0} bytes",
(1 << (geometry.EraseBlockSize - 1)) *
(1 << (geometry.Interleaving - 1))));
decodedTuples.Add("Read block",
string.Format("{0} bytes",
(1 << (geometry.ReadBlockSize - 1)) *
(1 << (geometry.Interleaving - 1))));
decodedTuples.Add("Write block",
string.Format("{0} bytes",
(1 << (geometry.WriteBlockSize - 1)) *
(1 << (geometry.Interleaving - 1))));
decodedTuples.Add("Partition alignment",
string.Format("{0} bytes",
(1 << (geometry.EraseBlockSize - 1)) *
(1 << (geometry.Interleaving - 1)) *
(1 << (geometry.Partitions - 1))));
}
break;
case Decoders.PCMCIA.TupleCodes.CISTPL_ALTSTR:
case Decoders.PCMCIA.TupleCodes.CISTPL_BAR:
case Decoders.PCMCIA.TupleCodes.CISTPL_BATTERY:
case Decoders.PCMCIA.TupleCodes.CISTPL_BYTEORDER:
case Decoders.PCMCIA.TupleCodes.CISTPL_CFTABLE_ENTRY:
case Decoders.PCMCIA.TupleCodes.CISTPL_CFTABLE_ENTRY_CB:
case Decoders.PCMCIA.TupleCodes.CISTPL_CHECKSUM:
case Decoders.PCMCIA.TupleCodes.CISTPL_CONFIG:
case Decoders.PCMCIA.TupleCodes.CISTPL_CONFIG_CB:
case Decoders.PCMCIA.TupleCodes.CISTPL_DATE:
case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICE:
case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICE_A:
case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICE_OA:
case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICE_OC:
case Decoders.PCMCIA.TupleCodes.CISTPL_EXTDEVIC:
case Decoders.PCMCIA.TupleCodes.CISTPL_FORMAT:
case Decoders.PCMCIA.TupleCodes.CISTPL_FORMAT_A:
case Decoders.PCMCIA.TupleCodes.CISTPL_FUNCE:
case Decoders.PCMCIA.TupleCodes.CISTPL_FUNCID:
case Decoders.PCMCIA.TupleCodes.CISTPL_GEOMETRY:
case Decoders.PCMCIA.TupleCodes.CISTPL_INDIRECT:
case Decoders.PCMCIA.TupleCodes.CISTPL_JEDEC_A:
case Decoders.PCMCIA.TupleCodes.CISTPL_JEDEC_C:
case Decoders.PCMCIA.TupleCodes.CISTPL_LINKTARGET:
case Decoders.PCMCIA.TupleCodes.CISTPL_LONGLINK_A:
case Decoders.PCMCIA.TupleCodes.CISTPL_LONGLINK_C:
case Decoders.PCMCIA.TupleCodes.CISTPL_LONGLINK_CB:
case Decoders.PCMCIA.TupleCodes.CISTPL_LONGLINK_MFC:
case Decoders.PCMCIA.TupleCodes.CISTPL_NO_LINK:
case Decoders.PCMCIA.TupleCodes.CISTPL_ORG:
case Decoders.PCMCIA.TupleCodes.CISTPL_PWR_MGMNT:
case Decoders.PCMCIA.TupleCodes.CISTPL_SPCL:
case Decoders.PCMCIA.TupleCodes.CISTPL_SWIL:
case Decoders.PCMCIA.TupleCodes.CISTPL_VERS_2:
decodedTuples.Add("Undecoded tuple ID", tuple.Code.ToString());
break;
default:
decodedTuples.Add("Unknown tuple ID", string.Format("0x{0:X2}", (byte)tuple.Code));
break;
}
if(decodedTuples.Count > 0)
{
repPcmciaTuples.DataSource = decodedTuples;
repPcmciaTuples.DataBind();
}
else repPcmciaTuples.Visible = false;
}
else repPcmciaTuples.Visible = false;
}
else divPcmcia.Visible = false;
bool removable = true;
testedMediaType[] testedMedia = null;
bool ata = false;
bool atapi = false;
bool sscMedia = false;
if(report.ATA != null || report.ATAPI != null)
{
ata = true;
List<string> ataOneValue = new List<string>();
Dictionary<string, string> ataTwoValue = new Dictionary<string, string>();
ataType ataReport;
if(report.ATAPI != null)
{
lblAtapi.Text = "PI";
ataReport = report.ATAPI;
atapi = true;
}
else ataReport = report.ATA;
bool cfa = report.CompactFlashSpecified && report.CompactFlash;
if(atapi && !cfa) lblAtaDeviceType.Text = "ATAPI device";
else if(!atapi && cfa) lblAtaDeviceType.Text = "CompactFlash device";
else lblAtaDeviceType.Text = "ATA device";
Ata.Report(ataReport, cfa, atapi, ref removable, ref ataOneValue, ref ataTwoValue, ref testedMedia);
repAtaOne.DataSource = ataOneValue;
repAtaOne.DataBind();
repAtaTwo.DataSource = ataTwoValue;
repAtaTwo.DataBind();
}
else divAta.Visible = false;
if(report.SCSI != null)
{
List<string> scsiOneValue = new List<string>();
Dictionary<string, string> modePages = new Dictionary<string, string>();
Dictionary<string, string> evpdPages = new Dictionary<string, string>();
if(VendorString.Prettify(report.SCSI.Inquiry.VendorIdentification) !=
report.SCSI.Inquiry.VendorIdentification)
lblScsiVendor.Text = string.Format("{0} ({1})", report.SCSI.Inquiry.VendorIdentification,
VendorString.Prettify(report.SCSI.Inquiry
.VendorIdentification));
else lblScsiVendor.Text = report.SCSI.Inquiry.VendorIdentification;
lblScsiProduct.Text = report.SCSI.Inquiry.ProductIdentification;
lblScsiRevision.Text = report.SCSI.Inquiry.ProductRevisionLevel;
scsiOneValue.AddRange(ScsiInquiry.Report(report.SCSI.Inquiry));
if(report.SCSI.SupportsModeSense6) scsiOneValue.Add("Device supports MODE SENSE (6)");
if(report.SCSI.SupportsModeSense10) scsiOneValue.Add("Device supports MODE SENSE (10)");
if(report.SCSI.SupportsModeSubpages) scsiOneValue.Add("Device supports MODE SENSE subpages");
if(report.SCSI.ModeSense != null)
ScsiModeSense.Report(report.SCSI.ModeSense, report.SCSI.Inquiry.VendorIdentification,
report.SCSI.Inquiry.PeripheralDeviceType, ref scsiOneValue, ref modePages);
if(modePages.Count > 0)
{
repModeSense.DataSource = modePages;
repModeSense.DataBind();
}
else divScsiModeSense.Visible = false;
if(report.SCSI.EVPDPages != null)
ScsiEvpd.Report(report.SCSI.EVPDPages, report.SCSI.Inquiry.VendorIdentification, ref evpdPages);
if(evpdPages.Count > 0)
{
repEvpd.DataSource = evpdPages;
repEvpd.DataBind();
}
else divScsiEvpd.Visible = false;
divScsiMmcMode.Visible = false;
divScsiMmcFeatures.Visible = false;
divScsiSsc.Visible = false;
if(report.SCSI.MultiMediaDevice != null)
{
testedMedia = report.SCSI.MultiMediaDevice.TestedMedia;
if(report.SCSI.MultiMediaDevice.ModeSense2A != null)
{
List<string> mmcModeOneValue = new List<string>();
ScsiMmcMode.Report(report.SCSI.MultiMediaDevice.ModeSense2A, ref mmcModeOneValue);
if(mmcModeOneValue.Count > 0)
{
divScsiMmcMode.Visible = true;
repScsiMmcMode.DataSource = mmcModeOneValue;
repScsiMmcMode.DataBind();
}
}
if(report.SCSI.MultiMediaDevice.Features != null)
{
List<string> mmcFeaturesOneValue = new List<string>();
ScsiMmcFeatures.Report(report.SCSI.MultiMediaDevice.Features, ref mmcFeaturesOneValue);
if(mmcFeaturesOneValue.Count > 0)
{
divScsiMmcFeatures.Visible = true;
repScsiMmcFeatures.DataSource = mmcFeaturesOneValue;
repScsiMmcFeatures.DataBind();
}
}
}
else if(report.SCSI.SequentialDevice != null)
{
divScsiSsc.Visible = true;
if(report.SCSI.SequentialDevice.BlockSizeGranularitySpecified)
lblScsiSscGranularity.Text = report.SCSI.SequentialDevice.BlockSizeGranularity.ToString();
else lblScsiSscGranularity.Text = "Unspecified";
if(report.SCSI.SequentialDevice.MaxBlockLengthSpecified)
lblScsiSscMaxBlock.Text = report.SCSI.SequentialDevice.MaxBlockLength.ToString();
else lblScsiSscMaxBlock.Text = "Unspecified";
if(report.SCSI.SequentialDevice.MinBlockLengthSpecified)
lblScsiSscMinBlock.Text = report.SCSI.SequentialDevice.MinBlockLength.ToString();
else lblScsiSscMinBlock.Text = "Unspecified";
if(report.SCSI.SequentialDevice.SupportedDensities != null)
{
repScsiSscDensities.DataSource = report.SCSI.SequentialDevice.SupportedDensities;
repScsiSscDensities.DataBind();
}
else repScsiSscDensities.Visible = false;
if(report.SCSI.SequentialDevice.SupportedMediaTypes != null)
{
repScsiSscMedias.DataSource = report.SCSI.SequentialDevice.SupportedMediaTypes;
repScsiSscMedias.DataBind();
}
else repScsiSscMedias.Visible = false;
if(report.SCSI.SequentialDevice.TestedMedia != null)
{
List<string> mediaOneValue = new List<string>();
SscTestedMedia.Report(report.SCSI.SequentialDevice.TestedMedia, ref mediaOneValue);
if(mediaOneValue.Count > 0)
{
sscMedia = true;
repTestedMedia.DataSource = mediaOneValue;
repTestedMedia.DataBind();
}
else divTestedMedia.Visible = false;
}
else divTestedMedia.Visible = false;
}
else if(report.SCSI.ReadCapabilities != null)
{
removable = false;
scsiOneValue.Add("");
if(report.SCSI.ReadCapabilities.BlocksSpecified &&
report.SCSI.ReadCapabilities.BlockSizeSpecified)
{
scsiOneValue.Add(string.Format("Device has {0} blocks of {1} bytes each",
report.SCSI.ReadCapabilities.Blocks,
report.SCSI.ReadCapabilities.BlockSize));
if(report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1024 /
1024 > 1000000)
scsiOneValue.Add(string.Format("Device size: {0} bytes, {1} Tb, {2:F2} TiB",
report.SCSI.ReadCapabilities.Blocks *
report.SCSI.ReadCapabilities.BlockSize,
report.SCSI.ReadCapabilities.Blocks *
report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000 /
1000 / 1000,
(double)(report.SCSI.ReadCapabilities.Blocks *
report.SCSI.ReadCapabilities.BlockSize) / 1024 /
1024 / 1024 / 1024));
else if(
report.SCSI.ReadCapabilities.Blocks * report.SCSI.ReadCapabilities.BlockSize / 1024 /
1024 > 1000)
scsiOneValue.Add(string.Format("Device size: {0} bytes, {1} Gb, {2:F2} GiB",
report.SCSI.ReadCapabilities.Blocks *
report.SCSI.ReadCapabilities.BlockSize,
report.SCSI.ReadCapabilities.Blocks *
report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000 /
1000,
(double)(report.SCSI.ReadCapabilities.Blocks *
report.SCSI.ReadCapabilities.BlockSize) / 1024 /
1024 / 1024));
else
scsiOneValue.Add(string.Format("Device size: {0} bytes, {1} Mb, {2:F2} MiB",
report.SCSI.ReadCapabilities.Blocks *
report.SCSI.ReadCapabilities.BlockSize,
report.SCSI.ReadCapabilities.Blocks *
report.SCSI.ReadCapabilities.BlockSize / 1000 / 1000,
(double)(report.SCSI.ReadCapabilities.Blocks *
report.SCSI.ReadCapabilities.BlockSize) / 1024 /
1024));
}
if(report.SCSI.ReadCapabilities.MediumTypeSpecified)
scsiOneValue.Add(string.Format("Medium type code: {0:X2}h",
report.SCSI.ReadCapabilities.MediumType));
if(report.SCSI.ReadCapabilities.DensitySpecified)
scsiOneValue.Add(string.Format("Density code: {0:X2}h",
report.SCSI.ReadCapabilities.Density));
if((report.SCSI.ReadCapabilities.SupportsReadLong ||
report.SCSI.ReadCapabilities.SupportsReadLong16) &&
report.SCSI.ReadCapabilities.LongBlockSizeSpecified)
scsiOneValue.Add(string.Format("Long block size: {0} bytes",
report.SCSI.ReadCapabilities.LongBlockSize));
if(report.SCSI.ReadCapabilities.SupportsReadCapacity)
scsiOneValue.Add("Device supports READ CAPACITY (10) command.");
if(report.SCSI.ReadCapabilities.SupportsReadCapacity16)
scsiOneValue.Add("Device supports READ CAPACITY (16) command.");
if(report.SCSI.ReadCapabilities.SupportsRead)
scsiOneValue.Add("Device supports READ (6) command.");
if(report.SCSI.ReadCapabilities.SupportsRead10)
scsiOneValue.Add("Device supports READ (10) command.");
if(report.SCSI.ReadCapabilities.SupportsRead12)
scsiOneValue.Add("Device supports READ (12) command.");
if(report.SCSI.ReadCapabilities.SupportsRead16)
scsiOneValue.Add("Device supports READ (16) command.");
if(report.SCSI.ReadCapabilities.SupportsReadLong)
scsiOneValue.Add("Device supports READ LONG (10) command.");
if(report.SCSI.ReadCapabilities.SupportsReadLong16)
scsiOneValue.Add("Device supports READ LONG (16) command.");
}
else testedMedia = report.SCSI.RemovableMedias;
repScsi.DataSource = scsiOneValue;
repScsi.DataBind();
}
else divScsi.Visible = false;
if(report.MultiMediaCard != null)
{
List<string> mmcOneValue = new List<string>();
if(report.MultiMediaCard.CID != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCID(report.MultiMediaCard.CID)
.Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
if(report.MultiMediaCard.CSD != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCSD(report.MultiMediaCard.CSD)
.Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
if(report.MultiMediaCard.ExtendedCSD != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyExtendedCSD(report.MultiMediaCard.ExtendedCSD)
.Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
if(report.MultiMediaCard.OCR != null)
{
mmcOneValue.Add(Decoders.MMC.Decoders.PrettifyCSD(report.MultiMediaCard.OCR)
.Replace("\n", "<br/>"));
mmcOneValue.Add("");
}
repMMC.DataSource = mmcOneValue;
repMMC.DataBind();
}
else divMMC.Visible = false;
if(report.SecureDigital != null)
{
List<string> sdOneValue = new List<string>();
if(report.SecureDigital.CID != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCID(report.SecureDigital.CID)
.Replace("\n", "<br/>"));
sdOneValue.Add("");
}
if(report.SecureDigital.CSD != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.CSD)
.Replace("\n", "<br/>"));
sdOneValue.Add("");
}
if(report.SecureDigital.SCR != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifySCR(report.SecureDigital.SCR)
.Replace("\n", "<br/>"));
sdOneValue.Add("");
}
if(report.SecureDigital.OCR != null)
{
sdOneValue.Add(Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.OCR)
.Replace("\n", "<br/>"));
sdOneValue.Add("");
}
repSD.DataSource = sdOneValue;
repSD.DataBind();
}
else divSD.Visible = false;
if(removable && !sscMedia && testedMedia != null)
{
List<string> mediaOneValue = new List<string>();
TestedMedia.Report(testedMedia, ata, ref mediaOneValue);
if(mediaOneValue.Count > 0)
{
sscMedia = true;
repTestedMedia.DataSource = mediaOneValue;
repTestedMedia.DataBind();
}
else divTestedMedia.Visible = false;
}
else divTestedMedia.Visible &= sscMedia;
}
catch(Exception)
{
content.InnerHtml = "<b>Could not load device report</b>";
#if DEBUG
throw;
#endif
}
}
static void GetUsbDescriptions(ushort vendor, ushort product, out string vendorDescription,
out string productDescription)
{
vendorDescription = null;
productDescription = null;
if(!File.Exists(Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~"), "usb.ids"))) return;
StreamReader tocStream =
new StreamReader(Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~"), "usb.ids"));
string _line;
bool inManufacturer = false;
ushort number;
while(tocStream.Peek() >= 0)
{
_line = tocStream.ReadLine();
if(_line.Length == 0 || _line[0] == '#') continue;
if(inManufacturer)
{
// Finished with the manufacturer
if(_line[0] != '\t') return;
number = Convert.ToUInt16(_line.Substring(1, 4), 16);
if(number != product) continue;
productDescription = _line.Substring(7);
return;
}
else
{
// Skip products
if(_line[0] == '\t') continue;
try { number = Convert.ToUInt16(_line.Substring(0, 4), 16); }
catch(FormatException) { continue; }
if(number != vendor) continue;
vendorDescription = _line.Substring(6);
inManufacturer = true;
}
}
}
}
}