7

I need to perform a check on all drives and see if any of the VIDs/PID match a specific one, if it does I need to get the drive letter of that flash drive. Thanks to all!

user1172635
  • 287
  • 1
  • 6
  • 11

3 Answers3

1

WMI should be able to handle this...

You will have to add a Reference to the System.Management dll and you will need to have the: "using System.Management;" line... See Link At Bottom for Screenshots, more thorough explanation...

using System.Management;
// Get all the disk drives

ManagementObjectSearcher mosDisks = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");

// Loop through each object (disk) retrieved by WMI

foreach (ManagementObject moDisk in mosDisks.Get())

{

    // Add the HDD to the list (use the Model field as the item's caption)

    cmbHdd.Items.Add(moDisk["Model"].ToString());

}


private void cmbHdd_SelectedIndexChanged(object sender, EventArgs e)

{

// Get all the disk drives from WMI that match the Model name selected in the ComboBox

ManagementObjectSearcher mosDisks = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive WHERE Model = '" + cmbHdd.SelectedItem + "'");

// Loop through the drives retrieved, although it should normally be only one loop going on here

foreach (ManagementObject moDisk in mosDisks.Get())

{

    // Set all the fields to the appropriate values

    lblType.Text = "Type: " + moDisk["MediaType"].ToString();

    lblModel.Text = "Model: " + moDisk["Model"].ToString();

    lblSerial.Text = "Serial: " + moDisk["SerialNumber"].ToString();

    lblInterface.Text = "Interface: " + moDisk["InterfaceType"].ToString();

    // The capacity in gigabytes is easily calculated 

    lblCapacity.Text = "Capacity: " + moDisk["Size"].ToString() + " bytes (" + Math.Round(((((double)Convert.ToDouble(moDisk["Size"]) / 1024) / 1024) / 1024), 2) + " GB)";

    lblPartitions.Text = "Partitions: " + moDisk["Partitions"].ToString();

    lblSignature.Text = "Signature: " + moDisk["Signature"].ToString();

    lblFirmware.Text = "Firmware: " + moDisk["FirmwareRevision"].ToString();

    lblCylinders.Text = "Cylinders: " + moDisk["TotalCylinders"].ToString();

    lblSectors.Text = "Sectors: " + moDisk["TotalSectors"].ToString();

    lblHeads.Text = "Heads: " + moDisk["TotalHeads"].ToString();

    lblTracks.Text = "Tracks: " + moDisk["TotalTracks"].ToString();

    lblBytesPerSect.Text = "Bytes per Sector: " + moDisk["BytesPerSector"].ToString();

    lblSectorsPerTrack.Text = "Sectors per Track: " + moDisk["SectorsPerTrack"].ToString();

    lblTracksPerCyl.Text = "Tracks per Cylinder: " + moDisk["TracksPerCylinder"].ToString();

    }

}

From MSDN the win32 Class for CIM_DiskDrive has the following parameters:

*It looks as if "DeviceID" is what you want...

class Win32_DiskDrive : CIM_DiskDrive
{
  uint16   Availability;
  uint32   BytesPerSector;
  uint16   Capabilities[];
  string   CapabilityDescriptions[];
  string   Caption;
  string   CompressionMethod;
  uint32   ConfigManagerErrorCode;
  boolean  ConfigManagerUserConfig;
  string   CreationClassName;
  uint64   DefaultBlockSize;
  string   Description;
  string   DeviceID;
  boolean  ErrorCleared;
  string   ErrorDescription;
  string   ErrorMethodology;
  string   FirmwareRevision;
  uint32   Index;
  datetime InstallDate;
  string   InterfaceType;
  uint32   LastErrorCode;
  string   Manufacturer;
  uint64   MaxBlockSize;
  uint64   MaxMediaSize;
  boolean  MediaLoaded;
  string   MediaType;
  uint64   MinBlockSize;
  string   Model;
  string   Name;
  boolean  NeedsCleaning;
  uint32   NumberOfMediaSupported;
  uint32   Partitions;
  string   PNPDeviceID;
  uint16   PowerManagementCapabilities[];
  boolean  PowerManagementSupported;
  uint32   SCSIBus;
  uint16   SCSILogicalUnit;
  uint16   SCSIPort;
  uint16   SCSITargetId;
  uint32   SectorsPerTrack;
  string   SerialNumber;
  uint32   Signature;
  uint64   Size;
  string   Status;
  uint16   StatusInfo;
  string   SystemCreationClassName;
  string   SystemName;
  uint64   TotalCylinders;
  uint32   TotalHeads;
  uint64   TotalSectors;
  uint64   TotalTracks;
  uint32   TracksPerCylinder;
};

Top Portion oF Code Taken From:

http://www.geekpedia.com/tutorial233_Getting-Disk-Drive-Information-using-WMI-and-Csharp.html

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
John Bartels
  • 2,583
  • 3
  • 19
  • 26
1

If you only need to check when the device is connected the problem is much simpler. You need to check for the DBT_DEVICEARRIVAL event. If you are creating a Windows Forms application this can be done by implementing IMessageFilter interface and pass it to the AddMessageFiler function in Application. If you are not using a Forms app you will need to derive a class from NativeWindow and override WndProc. Remeber to call CreateHandle so it will be added to the windows message queue.

Once you have the way to receive DBT_DEVICEARRIVAL you will need to parse it out. (the following was not written in a IDE so it has not been tested)

// Constants from from Dbt.h
const int WM_DEVICECHANGE = 0x219;
const int DBT_DEVICEARRIVAL = 0x8000; 
const uint DBT_DEVTYP_DEVICEINTERFACE = 0x05;
const Guid GUID_DEVINTERFACE_USB_DEVICE = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED");


bool PreFilterMessage(ref Message m)
{
    if(m.Msg == case WM_DEVICECHANGE && m.WParam == DBT_DEVICEARRIVAL)
        var broadcast = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(pnt, typeof(DEV_BROADCAST_HDR));
        if(broadcast.dbch_DeviceType == DBT_DEVTYP_DEVICEINTERFACE)
        {
            var devInterface = (DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(pnt, typeof(DEV_BROADCAST_DEVICEINTERFACE));
            if(devInterface.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE)
            {
                // devInterface.dbcc_name will contain the VID and PID for example:
                // \\?\USB#Vid_067b&Pid_2517#6&12115ad4&2&1#{GUID}
                DoSomthingSpecial(devInterface.dbcc_name);
            }
        }
    }
    return false;
}

[StructLayout(LayoutKind.Sequential)]
struct DEV_BROADCAST_HDR {
   public uint dbch_Size;
   public uint dbch_DeviceType;
   public uint dbch_Reserved;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
        public int dbcc_size;
        public int dbcc_devicetype;
        public int dbcc_reserved;
        public Guid dbcc_classguid;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=255)]
        public string dbcc_name;
}

If you need to enumerate all devices already connected I would just recommend using the WMI method. If you want to see how to do it without WMI check out the code to USBView in the Windows Driver Development Kit, it may help you get you started.

Community
  • 1
  • 1
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
1
public static bool GetDriveVidPid(string szDriveName, ref ushort wVID, ref ushort wPID)
{
   bool bResult = false;
   string szSerialNumberDevice = null;

   ManagementObject oLogicalDisk = new ManagementObject("Win32_LogicalDisk.DeviceID='" + szDriveName.TrimEnd('\\') + "'");
   foreach(ManagementObject oDiskPartition in oLogicalDisk.GetRelated("Win32_DiskPartition"))
   {
      foreach(ManagementObject oDiskDrive in oDiskPartition.GetRelated("Win32_DiskDrive"))
      {
         string szPNPDeviceID = oDiskDrive["PNPDeviceID"].ToString();
         if(!szPNPDeviceID.StartsWith("USBSTOR"))
            throw new Exception(szDriveName + " ist kein USB-Laufwerk.");

         string[] aszToken = szPNPDeviceID.Split(new char[] { '\\', '&' });
         szSerialNumberDevice = aszToken[aszToken.Length - 2];
      }
   }

   if(null != szSerialNumberDevice)
   {
      ManagementObjectSearcher oSearcher = new ManagementObjectSearcher(@"root\CIMV2", "Select * from Win32_USBHub");
      foreach(ManagementObject oResult in oSearcher.Get())
      {
         object oValue = oResult["DeviceID"];
         if(oValue == null)
            continue;

         string szDeviceID = oValue.ToString();
         string[] aszToken = szDeviceID.Split(new char[] { '\\' });
         if(szSerialNumberDevice != aszToken[aszToken.Length - 1])
            continue;

         int nTemp = szDeviceID.IndexOf(@"VID_");
         if(0 > nTemp)
            continue;

         nTemp += 4;
         wVID = ushort.Parse(szDeviceID.Substring(nTemp, 4), System.Globalization.NumberStyles.AllowHexSpecifier);

         nTemp += 4;
         nTemp = szDeviceID.IndexOf(@"PID_", nTemp);
         if(0 > nTemp)
            continue;

         nTemp += 4;
         wPID = ushort.Parse(szDeviceID.Substring(nTemp, 4), System.Globalization.NumberStyles.AllowHexSpecifier);

         bResult = true;
         break;
      }
   }

   return bResult;
}