Click here to Skip to main content
15,867,704 members
Articles / Desktop Programming / Win32
Tip/Trick

Get a list of physical disks and the partitions on them in VB.NET the easy way

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
8 Jun 2012CPOL2 min read 61.3K   2.8K   9   23
Use DeviceIoControl, QueryDosDevice and WNetOpenEnum to get information about your system.

 Image 1

Introduction

Have you ever needed to know how many hard disks there are in the computer your app is running on? Which partitions are on which hard disks? Which drives are network drives, and what their UNC paths may be? What the dos name and number of the CD/DVDRoms in the system may be? In this example project you will find the class clsDiskInfoEx - which is a compilation of code I use to accomplish these ends. This code runs correctly on Windows 7, Vista, 2003 and XP. 

Background  

Recently I've been working on code to accomplish faster file copies in Windows. There are some 3rd party utilities, I know - but I wanted to be able to integrate this into my code. Eventually I found myself trying to figure out why concurrent reading and writing sometimes slowed things down. A little searching revealed the ugly truth - that reading and writing to the same hard drive concurrently was the problem. I set about trying to figure out which partitions were on the same hard drive to compensate, and this class was the result. 

This code was not entirely written by me - jo0l's .NET stuff and pinvoke.net were great starting points, and if you haven't already you should check them out.

Using the code  

  • clsDiskInfoEx does quite a bit behind the scene, and has several useful methods. Instantiate it with new the way you normally would with any class.
  • GetNetworkComputers - Returns a list(Of String) of the available computers in your network.
  • GetNetworkDrives - Returns a list(Of String) of network drives and their UNC paths, separated by "=".
  • GetUncPathOfMappedDrive - I think this is self explanatory.
  • GetPhysicalDisks - returns a list(Of String) of all the drives in the system and their respective parent device, be it an Physical disk, UNC path or dos CD Rom number formatted as follows: "C:=\\.\PhysicalDisk0"
  • GetPhysicalDiskParentFor(logicalDisk As String) As String - This is the one that gets all the use in this example project. When you instantiate the class, it fills an internal list with information about all the drives in your system. Feed this method the root directory of a drive (i.e.: "c:\") and it gives you the parent drive for that partition. To update the disk information (i.e.: someone plugged in a flash drive or inserted a CD), use the Refresh() method.

Here's a quick look at the code that adds the drive information into a listview in the example project's main form:

VB
Private Sub GetDriveInfo()
 
    Dim count As Int32 = 0
    Dim driveInfoEx As New clsDiskInfoEx
    Dim multipleParents() As String = Nothing
    Dim parentDrives As String = Nothing

    lvDriveInfo.Items.Clear()

    For Each drive As System.IO.DriveInfo In System.IO.DriveInfo.GetDrives

        parentDrives = driveInfoEx.GetPhysicalDiskParentFor(drive.RootDirectory.ToString)
        If parentDrives.Contains(", ") Then
            ' We have multiple parent drives:
            multipleParents = Split(parentDrives, ", ")
            ' Enumerate them backwards so the lowest numbered drives are reported 1st
            For more As Int32 = (multipleParents.Length - 1) To 0 Step -1
                If more = (multipleParents.Length - 1) Then
                    lvDriveInfo.Items.Add("")
                    lvDriveInfo.Items(count).SubItems.Add(drive.RootDirectory.ToString.Replace("\", ""))
                    lvDriveInfo.Items(count).SubItems.Add(multipleParents(more)) ' Parent drive
                    lvDriveInfo.Items(count).SubItems.Add(drive.DriveType.ToString)

                    If drive.IsReady Then
                        lvDriveInfo.Items(count).SubItems.Add(drive.DriveFormat)
                        lvDriveInfo.Items(count).SubItems.Add((drive.TotalSize / 1000000).ToString("N0") & " MB")
                        lvDriveInfo.Items(count).SubItems.Add((drive.AvailableFreeSpace / 1000000).ToString("N0") & " MB")
                    Else
                        lvDriveInfo.Items(count).SubItems.Add("No Disc")
                        lvDriveInfo.Items(count).SubItems.Add("-")
                        lvDriveInfo.Items(count).SubItems.Add("-")
                    End If
                Else
                    count += 1
                    lvDriveInfo.Items.Add("")
                    lvDriveInfo.Items(count).SubItems.Add(drive.RootDirectory.ToString.Replace("\", ""))
                    lvDriveInfo.Items(count).SubItems.Add(multipleParents(more)) ' Parent drive
                    lvDriveInfo.Items(count).SubItems.Add("Mirror or Span")
                    If drive.IsReady Then
                        lvDriveInfo.Items(count).SubItems.Add(drive.DriveFormat)
                    Else
                        lvDriveInfo.Items(count).SubItems.Add("")
                    End If
                    lvDriveInfo.Items(count).SubItems.Add("-")
                    lvDriveInfo.Items(count).SubItems.Add("-")
                End If
            Next
            count += 1
        Else
            ' Just one parent drive for this partition.
            lvDriveInfo.Items.Add("")
            lvDriveInfo.Items(count).SubItems.Add(drive.RootDirectory.ToString.Replace("\", ""))
            lvDriveInfo.Items(count).SubItems.Add(parentDrives) ' Parent drive
            lvDriveInfo.Items(count).SubItems.Add(drive.DriveType.ToString)

            If drive.IsReady Then
                lvDriveInfo.Items(count).SubItems.Add(drive.DriveFormat)
                lvDriveInfo.Items(count).SubItems.Add((drive.TotalSize / 1000000).ToString("N0") & " MB")
                lvDriveInfo.Items(count).SubItems.Add((drive.AvailableFreeSpace / 1000000).ToString("N0") & " MB")
            Else
                lvDriveInfo.Items(count).SubItems.Add("No Disc")
                lvDriveInfo.Items(count).SubItems.Add("-")
                lvDriveInfo.Items(count).SubItems.Add("-")
            End If
            count += 1
        End If
    Next
End Sub

Points of Interest

This class also correctly reports partitions that span drives, like mirrors, stripes or spanned volumes. However, it has only been tested in a machine with mirrored drives. If it behaves badly in systems with alternate configurations, I'd love to know it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
President Doxtader Industries LLC
United States United States
I've been in IT for the last 25 years in one capacity or another - always as either a network engineer or a developer... or both. At the moment I have an IT consultancy in Long Island, NY offering software development and network engineer services.

Comments and Discussions

 
PraiseThis is awesome - useful for datahoarder with powershell... Pin
chrisstorer14-Feb-23 10:27
chrisstorer14-Feb-23 10:27 
GeneralRe: This is awesome - useful for datahoarder with powershell... Pin
pdoxtader17-Feb-23 5:47
professionalpdoxtader17-Feb-23 5:47 
QuestionBig thanks Pin
Duc Axenn23-May-21 7:26
Duc Axenn23-May-21 7:26 
AnswerRe: Big thanks Pin
pdoxtader25-Jun-21 4:11
professionalpdoxtader25-Jun-21 4:11 
QuestionThanks ... greate share Pin
jerix_jex24-Sep-19 12:25
jerix_jex24-Sep-19 12:25 
AnswerRe: Thanks ... greate share Pin
pdoxtader7-Nov-19 5:21
professionalpdoxtader7-Nov-19 5:21 
QuestionThank you Pin
c0rrupt0r4-Apr-19 2:41
c0rrupt0r4-Apr-19 2:41 
AnswerRe: Thank you Pin
pdoxtader23-May-19 13:30
professionalpdoxtader23-May-19 13:30 
QuestionListing unmapped partitions Pin
oliwan31-Jan-13 8:15
oliwan31-Jan-13 8:15 
AnswerRe: Listing unmapped partitions Pin
pdoxtader3-Apr-13 4:32
professionalpdoxtader3-Apr-13 4:32 
QuestionCompatibility Pin
rctaubert2-Jul-12 3:43
rctaubert2-Jul-12 3:43 
GeneralRe: Compatibility Pin
pdoxtader2-Jul-12 3:46
professionalpdoxtader2-Jul-12 3:46 
GeneralMy vote of 5 Pin
rctaubert2-Jul-12 3:35
rctaubert2-Jul-12 3:35 
GeneralRe: My vote of 5 Pin
pdoxtader2-Jul-12 3:36
professionalpdoxtader2-Jul-12 3:36 
QuestionTesting the Program Pin
ledtech38-Jun-12 3:01
ledtech38-Jun-12 3:01 
AnswerRe: Testing the Program Pin
pdoxtader8-Jun-12 3:08
professionalpdoxtader8-Jun-12 3:08 
GeneralRe: Testing the Program Pin
ledtech38-Jun-12 3:16
ledtech38-Jun-12 3:16 
GeneralRe: Testing the Program Pin
pdoxtader8-Jun-12 3:47
professionalpdoxtader8-Jun-12 3:47 
GeneralRe: Testing the Program Pin
ledtech38-Jun-12 3:55
ledtech38-Jun-12 3:55 
GeneralRe: Testing the Program Pin
pdoxtader8-Jun-12 4:15
professionalpdoxtader8-Jun-12 4:15 
GeneralRe: Testing the Program Pin
ledtech38-Jun-12 4:18
ledtech38-Jun-12 4:18 
GeneralRe: Testing the Program Pin
pdoxtader8-Jun-12 4:26
professionalpdoxtader8-Jun-12 4:26 
GeneralRe: Testing the Program Pin
ledtech38-Jun-12 4:40
ledtech38-Jun-12 4:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.