Jump to content

Recommended Posts

Posted

?

; 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

 

Posted
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

.

Posted

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

 

  • 3 weeks later...
Posted (edited)

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
Posted

Just take the CRLF off of $sDrivesInfo?

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

Posted

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.

 

Posted (edited)
#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
Posted (edited)

Thanks to @jguinch !

But this tested Image:

abcnpxji.jpg

(The main partition on my system - Win7 - is C:\ , continue is D:\ . And with my External HardDisk, it is show up true.)

How to reorder them?.

Edited by meoit
Posted (edited)

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
  • 1 month later...
Posted

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.

  • 2 months later...
Posted (edited)

@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

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
  • Recently Browsing   0 members

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