/// <summary> /// This method discover the current ATA device and try to read all its configurations /// </summary> private void Discover() { DriveInfo.Device = Device.IDE_None; DriveInfo.BufferSize = 0; Status xStatus; bool Error = false; //Select Drive SelectDrive(); //Send Identify command CommandReg.Byte = (byte)Cmd.ATA_CMD_IDENTIFY; Wait(); if (StatusReg.Byte == 0) { return; //No Device } while (true) { xStatus = (Status)StatusReg.Byte; if ((xStatus & Status.ATA_SR_ERR) != 0) { Error = true; // If Err, Device is not ATA. break; } if (((xStatus & Status.ATA_SR_BSY) == 0) && ((xStatus & Status.ATA_SR_DRQ) != 0)) { break; //Everything is fine } Wait(); } DriveInfo.Device = Device.IDE_ATA; DriveInfo.BufferSize = 512; // (IV) Probe for ATAPI Devices: if (Error) { ushort xTypeID = (ushort)(LBA2.Byte << 8 | LBA1.Byte); if (xTypeID == 0xEB14 || xTypeID == 0x9669) { DriveInfo.Device = Device.IDE_ATAPI; DriveInfo.BufferSize = 2048; } else { DriveInfo.Device = Device.IDE_None; DriveInfo.BufferSize = 0; return; } //Send Identify packet command CommandReg.Byte = (byte)Cmd.ATA_CMD_IDENTIFY_PACKET; Wait(); } var xBuff = new ushort[256]; DataReg.Read16(xBuff); //ATA/ATAPI COnfig DriveInfo.IsRemovable = (xBuff[(int)Identify.ATA_IDENT_DEVICETYPE] & (1 << 7)) > 0; //CHS configurations DriveInfo.Cylinder = xBuff.ToUInt32((int)Identify.ATA_IDENT_CYLINDERS); DriveInfo.Heads = xBuff.ToUInt32((int)Identify.ATA_IDENT_HEADS); DriveInfo.SectorsPerTrack = xBuff.ToUInt32((int)Identify.ATA_IDENT_SECTORS); DriveInfo.CommandSet = xBuff.ToUInt32((int)Identify.ATA_IDENT_COMMANDSETS); ushort xFieldValid = xBuff[(int)Identify.ATA_IDENT_FIELDVALID]; //1st bit determine weather it support LBA or not DriveInfo.LBASupport = (bool)((xFieldValid & 1) == 1); if ((DriveInfo.CommandSet & (1 << 26)) != 0) { // Device uses 48-Bit Addressing: DriveInfo.Size = xBuff.ToUInt48((int)Identify.ATA_IDENT_MAX_LBA_EXT); } else { // Device uses CHS or 28-bit Addressing: DriveInfo.Size = xBuff.ToUInt32((int)Identify.ATA_IDENT_MAX_LBA); } //Read Model, Firmware, SerialNo. DriveInfo.Model = xBuff.GetString((int)Identify.ATA_IDENT_MODEL, 40); DriveInfo.SerialNo = xBuff.GetString((int)Identify.ATA_IDENT_SERIAL, 20); }