Reputation: 11
I like to see every Partition/volume (also the hidden system volumes) on all physical disks. The Information of the Volume should contain
In my opinion "WMI" can be the right choice to solve this task.
The sample Output can look similar to this:
- PHYSICALDRIVE4
- --> 0 - m: - Data - 2TB
- PHYSICALDRIVE1
- --> 0 - '' - System Reserved - 100MB
- --> 1 - c: - Windows - 100GB
- --> 2 - d: - Programs - 200GB
- PHYSICALDRIVE2
- --> 0 - '' - Hidden Recovery Partition - 50GB
- --> 1 - f: - data - 1TB
I found several solutions in the web to get the driveletter (c:) combined with the diskid (disk0). One of those solution can be found here.
public Dictionary<string, string> GetDrives()
{
var result = new Dictionary<string, string>();
foreach ( var drive in new ManagementObjectSearcher( "Select * from Win32_LogicalDiskToPartition" ).Get().Cast<ManagementObject>().ToList() )
{
var driveLetter = Regex.Match( (string)drive[ "Dependent" ], @"DeviceID=""(.*)""" ).Groups[ 1 ].Value;
var driveNumber = Regex.Match( (string)drive[ "Antecedent" ], @"Disk #(\d*)," ).Groups[ 1 ].Value;
result.Add( driveLetter, driveNumber );
}
return result;
}
The Problem with this solution is that it ignores the hidden partitions. The output dictionary will only contain 4 entries (m,4 - c,1 - d,1 - f,2).
This is because of combining "win32_logicalDisk" with "win32_diskpartion" using "Win32_LogicalDiskToPartition". But "win32_logicalDisk" does not contain unassigned volumes.
I can find unassigned volumes only in "win32_volume" but I am not able to combine "win32_volume" with "win32_diskpartition".
Simplified my Dataclasses should look like this:
public class Disk
{
public string Diskname; //"Disk0" or "0" or "PHYSICALDRIVE0"
public List<Partition> PartitionList;
}
public class Partition
{
public ushort Index //can be of type string too
public string Letter;
public string Label;
public uint Capacity;
//Example for Windows Partition
// Index = "1" or "Partition1"
// Letter = "c" or "c:"
// Label = "Windows"
// Capacity = "1000202039296"
//
//Example for System-reserved Partition
// Index = "0" or "Partition0"
// Letter = "" or ""
// Label = "System-reserved"
// Capacity = "104853504"
}
Maybe anyone can help :-)
Upvotes: 0
Views: 2040
Reputation: 1125
MSFT_Partition in root\microsoft\windows\storage has all of the partitions, including the hidden ones. I grab the DiskNumber and Offset from that class, and then match them against the DiskIndex and StartingOffset value in Win32_DiskPartition. That combination should provide a unique identifier.
Start with Win32_DiskDrive, then get partitions using the method above. The MSFT_Partition object also has a property called AccessPaths, which will contain the DeviceID from Win32_Volume that you can check against to correlate volumes to partitions. Win32_LogicalDisk can then also be checked against the partition using the method you described, something like:
using (ManagementObjectSearcher LogicalDiskSearcher = new ManagementObjectSearcher(new ManagementScope(ManagementPath.DefaultPath), new ObjectQuery(String.Format("ASSOCIATORS OF {{Win32_DiskPartition.DeviceID=\"{0}\"}} WHERE AssocClass = Win32_LogicalDiskToPartition", ((string)Partition["DeviceID"]).Replace("\\", "\\\\")))))
This will get a collection of LogicalDisks from the partition, if any exist. Hope this kind of answers the question in case anyone else was having a similar issue. Unfortunately MSFT_Partition is only available on Windows 8/Server 2012 and later.
Upvotes: 0