WMI Association of LogicalDisk with DiskPartition

3.1k views Asked by At

I am trying to put together a list which shows all LogicalDisk instances in my Computer System and the drive letters they have been associated with. Coding is in C#.

The WMI classes Win32_LogicalDiskToPartition, Win32_DiskPartition and Win32_LogicalDisk appeared to be the right data sources to get that Job done:

  • Win32_LogicalDiskToPartition contains the property "Antecedent" which obviously links to a "DeviceId" property of class Win32_DiskPartition

  • and Win32_LogicalDiskToPartition contains the property "Dependent" which obviously links to a "DeviceId" property of class Win32_LogicalDisk

And here's my problem:

The Antecedent property of Win32_LogicalDiskToPartition returns a string value like:

\\\\HOME-PC\\root\\cimv2:Win32_DiskPartition.DeviceID=\"Disk #2, Partition #0\

but I need only Disk #2, Partition #0 to match it with the DeviceId property values of class Win32_DiskPartition.

Similar Problem with the Dependent property value.

Is there a way to obtain this substring (except by hard coded string parsing)?

I am afraid a query does not help because I do also need additional information about the logical disk and the associated disk Partition. I am aware that I have to cover Extended partitions with multiple drive letters - this can be done with the StartingAddress property of the Win32_LogicalDiskToPartition instance.

1

There are 1 answers

3
Jimi On BEST ANSWER

This type of enumeration is usually performed using System.Management's
ManagementObjectSearcher building the query using the WQL ASSOCIATORS OF Statement
This is one sequential path you can follow to retrieve information on drives in a system:

Enumerate the Disk Drives => For Each [DeviceID] =>
Enumerate Disk Drive to Partition => For Each [DeviceID]
Enumerate Logical Disk to Partition

Objects in each class have their associated properties:

Disk Drives (MSDN)
Partition (MSDN)
Logical Disk (MSDN)

using System.Management;

 //Define an initial scope for the following queries
 var scope = new ManagementScope(@"\\" + Environment.MachineName + @"\root\CIMV2");

 //Select all Disk Drives
 var query = new SelectQuery("SELECT * FROM Win32_DiskDrive");
 //Options => Timeout infinite to avoid timeouts and forward only for speed
 var options = new EnumerationOptions();
 options.Timeout = EnumerationOptions.InfiniteTimeout;
 options.Rewindable = false;
 options.ReturnImmediately = true;

 //New root Management Object
 var searcher = new ManagementObjectSearcher(scope, query, options);

 //Enumerate all Disk Drives
 foreach (ManagementObject moDisk in searcher.Get())
 {
    //Query the associated partitions of the current DeviceID
    string assocQuery = "Associators of {Win32_DiskDrive.DeviceID='" + 
                        mobDisk.Properties["DeviceID"].Value.ToString() + "'}" +
                        "where AssocClass=Win32_DiskDriveToDiskPartition";
    var assocPart = new ManagementObjectSearcher(assocQuery);
    assocPart.Options.Timeout = EnumerationOptions.InfiniteTimeout;

    //For each Disk Drive, query the associated partitions
    foreach (ManagementObject moPart in assocPart.Get())
    {
       Console.WriteLine("DeviceID: {0}  BootPartition: {1}", 
                         moPart.Properties["DeviceID"].Value.ToString(), 
                         moPart.Properties["BootPartition"].Value.ToString());

       //Query the associated logical disk of the current PartitionID
       string logDiskQuery = "Associators of {Win32_DiskPartition.DeviceID='" + 
                              moPart.Properties["DeviceID"].Value.ToString() + "'} " +
                              "where AssocClass=Win32_LogicalDiskToPartition";

       var logDisk = new ManagementObjectSearcher(logDiskQuery);
       logDisk.Options.Timeout = EnumerationOptions.InfiniteTimeout;

       //For each partition, query the Logical Drives
       foreach (var logDiskEnu in logDisk.Get())
       {
          Console.WriteLine("Volume Name: {0}  Serial Number: {1}  System Name: {2}",
                            logDiskEnu.Properties["VolumeName"].Value.ToString(),
                            logDiskEnu.Properties["VolumeSerialNumber"].Value.ToString(),
                            logDiskEnu.Properties["SystemName"].Value.ToString());
          Console.WriteLine("Description: {0}  DriveType: {1}  MediaType: {2}",
                            logDiskEnu.Properties["Description"].Value.ToString(),
                            logDiskEnu.Properties["DriveType"].Value.ToString(),
                            logDiskEnu.Properties["MediaType"].Value.ToString());
       }
    }
 }