Jump to content

Get DiskName without DiskPart, WMI, WMIC


meoit
 Share

Recommended Posts

?

; https://www.autoitscript.com/forum/topic/91598-get-disk-number-from-drive-letter/?do=findComment&comment=659721
; by trancexx

; $sDDriveLetter = "C"

#include <array.au3>

Global $aDiskArray[1][2]
$aDiskArray[0][0] = "Total disks found ="
For $i = 97 To 122
    $sDDriveLetter = Chr($i)
    $iDiskNumber = _GetDiskNimberForDrive($sDDriveLetter)
    If Not @error Then
        $aDiskArray[0][1] += 1
        ReDim $aDiskArray[UBound($aDiskArray) + 1][2]
        $aDiskArray[UBound($aDiskArray) - 1][0] = Chr($i)
        $aDiskArray[UBound($aDiskArray) - 1][1] = "disk" & $iDiskNumber
    EndIf
Next
_ArrayDisplay($aDiskArray)

#cs
    If @error Then
    MsgBox(48, "Error", "Error Number " & @error & @CRLF)
    Else
    MsgBox(64, "_GetDiskNimberForDrive", "Drive " & StringUpper($sDDriveLetter) & " is on disk #" & $iDiskNumber)
    EndIf
#ce


Func _GetDiskNimberForDrive($sDriveLetter)

    Local $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFile", _
            "str", "\\.\" & $sDriveLetter & ":", _; logical drive
            "dword", 0, _
            "dword", 0, _
            "ptr", 0, _
            "dword", 3, _; OPEN_EXISTING
            "dword", 128, _; FILE_ATTRIBUTE_NORMAL
            "ptr", 0)

    If @error Then
        Return SetError(1, 0, -1); your system is very old. Do something.
    EndIf

    If $a_hCall[0] = -1 Then
        Return SetError(2, 0, -1); non-existing drive
    EndIf

    Local $hDevice = $a_hCall[0]

    Local $tIOCTL_STORAGE_GET_DEVICE_NUMBER = DllStructCreate("dword DeviceType;" & _
            "dword DeviceNumber;" & _
            "int PartitionNumber")

    Local $a_iCall = DllCall("kernel32.dll", "int", "DeviceIoControl", _
            "hwnd", $hDevice, _
            "dword", 0x2D1080, _; IOCTL_STORAGE_GET_DEVICE_NUMBER
            "ptr", 0, _
            "dword", 0, _
            "ptr", DllStructGetPtr($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _
            "dword", DllStructGetSize($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _
            "dword*", 0, _
            "ptr", 0)

    If @error Or Not $a_hCall[0] Then
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice)
        Return SetError(3, 0, -1); DeviceIoControl failed for some reason
    EndIf

    DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice)

    ; will write some data
    ConsoleWrite("Drive " & StringUpper($sDriveLetter) & ": " & @CRLF)
    ConsoleWrite(@TAB & "DeviceType: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") & @CRLF)
    ConsoleWrite(@TAB & "DeviceNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber") & @CRLF)
    ConsoleWrite(@TAB & "PartitionNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "PartitionNumber") & @CRLF)
    ConsoleWrite(@CRLF)
    ; end writing

    If DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") = 7 Then; FILE_DEVICE_DISK
        Return SetError(0, 0, DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber"))
    EndIf

    Return SetError(4, 0, -1); not a disk partition

EndFunc   ;==>_GetDiskNimberForDrive

 

Link to comment
Share on other sites

22 minutes ago, KaFu said:

?

; https://www.autoitscript.com/forum/topic/91598-get-disk-number-from-drive-letter/?do=findComment&comment=659721
; by trancexx

; $sDDriveLetter = "C"

#include <array.au3>

Global $aDiskArray[1][2]
$aDiskArray[0][0] = "Total disks found ="
For $i = 97 To 122
    $sDDriveLetter = Chr($i)
    $iDiskNumber = _GetDiskNimberForDrive($sDDriveLetter)
    If Not @error Then
        $aDiskArray[0][1] += 1
        ReDim $aDiskArray[UBound($aDiskArray) + 1][2]
        $aDiskArray[UBound($aDiskArray) - 1][0] = Chr($i)
        $aDiskArray[UBound($aDiskArray) - 1][1] = "disk" & $iDiskNumber
    EndIf
Next
_ArrayDisplay($aDiskArray)

#cs
    If @error Then
    MsgBox(48, "Error", "Error Number " & @error & @CRLF)
    Else
    MsgBox(64, "_GetDiskNimberForDrive", "Drive " & StringUpper($sDDriveLetter) & " is on disk #" & $iDiskNumber)
    EndIf
#ce


Func _GetDiskNimberForDrive($sDriveLetter)

    Local $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFile", _
            "str", "\\.\" & $sDriveLetter & ":", _; logical drive
            "dword", 0, _
            "dword", 0, _
            "ptr", 0, _
            "dword", 3, _; OPEN_EXISTING
            "dword", 128, _; FILE_ATTRIBUTE_NORMAL
            "ptr", 0)

    If @error Then
        Return SetError(1, 0, -1); your system is very old. Do something.
    EndIf

    If $a_hCall[0] = -1 Then
        Return SetError(2, 0, -1); non-existing drive
    EndIf

    Local $hDevice = $a_hCall[0]

    Local $tIOCTL_STORAGE_GET_DEVICE_NUMBER = DllStructCreate("dword DeviceType;" & _
            "dword DeviceNumber;" & _
            "int PartitionNumber")

    Local $a_iCall = DllCall("kernel32.dll", "int", "DeviceIoControl", _
            "hwnd", $hDevice, _
            "dword", 0x2D1080, _; IOCTL_STORAGE_GET_DEVICE_NUMBER
            "ptr", 0, _
            "dword", 0, _
            "ptr", DllStructGetPtr($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _
            "dword", DllStructGetSize($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _
            "dword*", 0, _
            "ptr", 0)

    If @error Or Not $a_hCall[0] Then
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice)
        Return SetError(3, 0, -1); DeviceIoControl failed for some reason
    EndIf

    DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice)

    ; will write some data
    ConsoleWrite("Drive " & StringUpper($sDriveLetter) & ": " & @CRLF)
    ConsoleWrite(@TAB & "DeviceType: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") & @CRLF)
    ConsoleWrite(@TAB & "DeviceNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber") & @CRLF)
    ConsoleWrite(@TAB & "PartitionNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "PartitionNumber") & @CRLF)
    ConsoleWrite(@CRLF)
    ; end writing

    If DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") = 7 Then; FILE_DEVICE_DISK
        Return SetError(0, 0, DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber"))
    EndIf

    Return SetError(4, 0, -1); not a disk partition

EndFunc   ;==>_GetDiskNimberForDrive

 

Thanks to @KaFu !

This is result testing:

Ka_Fu_Mini_XP.jpg

.

Link to comment
Share on other sites

I don't understand why my previous code does not work.

Can you try this one ?

#include <WinAPIFiles.au3>
#include <Array.au3>


Local $aDriveInfo, $iLastDevNumber = -1
Local $aFixed = DriveGetDrive('FIXED'), $aRemovable = DriveGetDrive('REMOVABLE')
Local $aDrives[  (IsArray($aFixed) ? $aFixed[0] : 0) + (IsArray($aRemovable) ? $aRemovable[0] : 0) ][3]

Local $iDrive = 0
For $i = 1 To UBound($aFixed) - 1
    $aDrives[$iDrive][0] = $aFixed[$i]
    $aDriveInfo = _WinAPI_GetDriveNumber($aFixed[$i])
    If Not @error Then
        $aDrives[$iDrive][1] = $aDriveInfo[1]
        $aDrives[$iDrive][2] = $aDriveInfo[2]
    EndIf
    $iDrive += 1
Next
For $i = 1 To UBound($aRemovable) - 1
    $aDrives[$iDrive][0] = $aRemovable[$i]
    $aDriveInfo = _WinAPI_GetDriveNumber($aRemovable[$i])
    If Not @error Then
        $aDrives[$iDrive][1] = $aDriveInfo[1]
        $aDrives[$iDrive][2] = $aDriveInfo[2]
    EndIf
    $iDrive += 1
Next


_ArraySort($aDrives, 0, 0, 0, 1)

Local $sDrivesInfo = "Drive list :" & @CRLF
For $i = 0 To UBound($aDrives) - 1
    If IsNumber($aDrives[$i][1]) Then
        If $aDrives[$i][1] <> $iLastDevNumber Then
            $sDrivesInfo &= @CRLF & "Disk #" & $aDrives[$i][1] & " [" & _GetDiskNameByNumber($aDrives[$i][1]) & "]" & @CRLF
            $iLastDevNumber = $aDrives[$i][1]
        EndIf
        $sDrivesInfo &= " - Partition #" & $aDrives[$i][2] & "  " & DriveGetLabel($aDrives[$i][0]) & " - " & $aDrives[$i][0] & @CRLF
    EndIf
Next

MsgBox(0, "", $sDrivesInfo)


Func _GetDiskNameByNumber($iDiskNumber)
    Local $iCount = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", "Count")
    Local $sDiskKey = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", String($iDiskNumber))
    If @error Then Return SetError(1, 0, 0)

    Local $sDiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $sDiskKey, "FriendlyName")
    If $sDiskName = "" Then $sDiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $sDiskKey, "DeviceDesc")

    Return $sDiskName
EndFunc

 

Link to comment
Share on other sites

  • 3 weeks later...

Hello @jguinch !. I sent for you but not see you back.

Your code at #46 of comment is working fine for XP/Vista/7/8/8.1/10.

I have one question. How to convert the value of the disk array of letters in the same line ?.

Example:

Disk# - Disk name - The letters of that Disk# (Show only on one line. Because I want to set data for ComboBox.)

Thanks to your support.

Edited by meoit
Link to comment
Share on other sites

Just take the CRLF off of $sDrivesInfo?

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Non. Example this:

Disk0 - SAMSUNG HDD D500 - [C:\, D:\, E:\]

Disk1 - SONY USB FLASH - [F:\]

Disk2 - ADATA Portable HDD 1TB - [G:\, H:\, I:\, J:\]

Disk3 - SSK SD Card Reader - [K:\]

.............

Show for each Disk.

 

Link to comment
Share on other sites

#include <WinAPIFiles.au3>
#include <Array.au3>


Local $aDriveInfo, $iLastDevNumber = -1
Local $aFixed = DriveGetDrive('FIXED'), $aRemovable = DriveGetDrive('REMOVABLE')
Local $aDrives[  (IsArray($aFixed) ? $aFixed[0] : 0) + (IsArray($aRemovable) ? $aRemovable[0] : 0) ][3]

Local $iDrive = 0
For $i = 1 To UBound($aFixed) - 1
    $aDrives[$iDrive][0] = $aFixed[$i]
    $aDriveInfo = _WinAPI_GetDriveNumber($aFixed[$i])
    If Not @error Then
        $aDrives[$iDrive][1] = $aDriveInfo[1]
        $aDrives[$iDrive][2] = $aDriveInfo[2]
    EndIf
    $iDrive += 1
Next
For $i = 1 To UBound($aRemovable) - 1
    $aDrives[$iDrive][0] = $aRemovable[$i]
    $aDriveInfo = _WinAPI_GetDriveNumber($aRemovable[$i])
    If Not @error Then
        $aDrives[$iDrive][1] = $aDriveInfo[1]
        $aDrives[$iDrive][2] = $aDriveInfo[2]
    EndIf
    $iDrive += 1
Next

_ArraySort($aDrives, 0, 0, 0, 1)
Local $aDisks[ UBound($aDrives) ] [2]
Local $sDrivesInfo = "Drive list :" & @CRLF
Local $sOutput = ""

For $i = 0 To UBound($aDrives) - 1
    If IsNumber($aDrives[$i][1]) Then
        If $aDrives[$i][1] <> $iLastDevNumber Then
            $iLastDevNumber = $aDrives[$i][1]
            $aDisks[ $iLastDevNumber ][0] = "Disk " & $aDrives[$i][1] & " - " & _GetDiskNameByNumber($aDrives[$i][1]) & " - "
        EndIf
        $aDisks[ $iLastDevNumber ][1] &= $aDrives[$i][0] & ";"
    EndIf
Next
Redim $aDisks[$iLastDevNumber + 1][2]

For $i = 0 To UBound($aDisks) - 1
    $sOutput &= $aDisks[$i][0] & " ["

    $aSplit = StringRegExp($aDisks[$i][1], "[^;]+", 3)
    _ArraySort($aSplit)
    For $j = 0 To UBound($aSplit) - 1
        $sOutput &= $aSplit[$j] & "\, "
    Next
    $sOutput &= "]" & @CRLF
Next
$sOutput = StringReplace($sOutput, ", ]", "]")

MsgBox(0, "", $sOutput)



Func _GetDiskNameByNumber($iDiskNumber)
    Local $iCount = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", "Count")
    Local $sDiskKey = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum", String($iDiskNumber))
    If @error Then Return SetError(1, 0, 0)

    Local $sDiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $sDiskKey, "FriendlyName")
    If $sDiskName = "" Then $sDiskName = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" & $sDiskKey, "DeviceDesc")

    Return $sDiskName
EndFunc

 

Edited by jguinch
Link to comment
Share on other sites

Hello @jguinch !

Today, I found a bug when I insert a SD-Card Reader. The code did not recognize this device.
In Registry, I saw this device there. And I try with BootICE, it show up.

getdisk_bugslsly.png

And in this Registry Key, I see the Name called "CompatibleIDs", the value of it is:

USBSTOR\Disk
USBSTOR\RAW

(When running the script, I do not format the memory card in the SD-Card Reader that.)

getdisk_bug2vckth.png

How to fix this problem ?.

Thanks.

Edited by meoit
Link to comment
Share on other sites

  • 1 month later...

Hello @jguinch and all !

I plan to create a thread to ask about the detection of the drive type (example: Hard Disk, USB Disk), comes with code that @jguinch have helped me before. But here I think writing is reasonable.

I realize that there are two kinds of hard drives, a Built-in hard drive (Internal Hard Drive), External Hard Drive two.

Internal Hard Drive is connected via SATA.
External Hard Drive is connected via USB.

Can you help me detection of the drive type ?.

Thanks all.

Link to comment
Share on other sites

  • 2 months later...

@KaFu

If know the disk Disk number and partition index number, how to get the Partition letter and volume label?

example:know the (\\.\PhysicalDrive0) disk 0  the first partition,how to get “C:” and "operate system"?

Thanks!

Edited by haijie1223
Link to comment
Share on other sites

  • Moderators

@haijie1223 in the future, please just hit the reply button rather than quoting previous posts; it just pads the thread unnecessarily.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...