[RESOLVED] Get physical drive number given a drive letter
You can retrieve the physical serial number, model number and firmware revision given a drive number, (0, 1, etc..., where drive 0 is the primary master.)
How can I get the drive number associated with a drive letter?
Re: Get physical drive number given a drive letter
I already know how to get the physical drive's serial number, model number and firmware revision. The code on how to do it was posted to the Codeback within the last couple days, plus I also found the original vbnet submission (that your link copied verbatim) when I went searching for an answer to the OP.
My question is more specific. When you download that code and look at it, the function that gets the drive information takes a numeric Drive parameter: 0 for primary master, 1 for primary slave, 2 for secondary master, 3 for secondary slave, etc...
What I'd like is to be able to call that function with a logical drive letter instead of a physical drive number. eg: "C:" instead of 0.
Re: Get physical drive number given a drive letter
Thanks for the effort, but that's also a no-go. I use code similar to that as well, but the problem with the serial number is that it isn't permanent; it can be altered. (I'm not entirely sure how; I've heard that you can change it by reformatting the drive, but I suspect you'd have to low-level format it to change the serial number.)
The physical drive serial number is branded into the drive; it cannot be changed. (And it's an alpha-numeric, as opposed to the numeric serial number.)
Anyone know how to get the physical IDE drive number based on a logical drive letter?
Re: Get physical drive number given a drive letter
Note: I am not asking about serial numbers. I already have the code to do that. The issue is that it expects a drive number, and I really want to send a drive letter instead.
the examples on these pages show that you can return the DeviceID which is the physical drive, also the caption or name, one of which should be the drive letter, probably you will have to loop through the drives to get the drive letter you want, also of course more than one drive letter can be on the same physical drive
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case. Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete
Re: Get physical drive number given a drive letter
Thanks for the links; that last one works.
The only problem with it is that I'd like to incorporate this solution into my reference-less library, and that solution requires a reference to Microsoft WMI Scripting Library in the project references.
That's a deal-breaker IMO, so I'll probably just leave it as a physical drive number. For branding purposes, that probably is enough anyway.
Is there any way to obtain the drive letter (as demonstrated in the third link above) without requiring a reference?
Re: Get physical drive number given a drive letter
you can use the createfile api to return the device no, then use DeviceIoControl to get much other info from the device including serial number disk number and partionnumber
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case. Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete
Re: Get physical drive number given a drive letter
i mucked around with some code for it, but didn't figure if it was working correctly, but can post if you want, hard to find any good info about DeviceIOControl api
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case. Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete
Re: Get physical drive number given a drive letter
here is a project i created to play with, very little of it written by me, it is real messy as i kept pasting in more code from different internet sources as i found more information
i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case. Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next
dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part
come back and mark your original post as resolved if your problem is fixed
pete
Re: Get physical drive number given a drive letter
I had the same issue needing to get the logical drive # from the drive letter. I used the code that was posted and cleaned it up to do only that.
The function accepts a drive letter, ie "C:"( no "\") and returns its device type, logical drive #, and partition #.
Code:
Option Explicit
Private Enum IOCOMMANDS
IOCTL_STORAGE_GET_DEVICE_NUMBER = &H2D1080
End Enum
Private Declare Function DeviceIoControl Lib "kernel32" _
(ByVal hDevice As Long, _
ByVal dwIoControlCode As Long, _
lpInBuffer As Any, _
ByVal nInBufferSize As Long, _
lpOutBuffer As Any, _
ByVal nOutBufferSize As Long, _
lpBytesReturned As Long, _
lpOverlapped As Any) As Long
Private Declare Function CreateFile Lib "kernel32" _
Alias "CreateFileA" _
(ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
lpSecurityAttributes As Any, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Const INVALID_HANDLE_VALUE As Long = -1&
Private Const GENERIC_READ As Long = &H80000000
Private Const FILE_SHARE_READ As Long = &H1
Private Const FILE_SHARE_WRITE As Long = &H2
Private Const OPEN_EXISTING As Long = 3
Type ddevicetype
DEVICE_TYPE As Long
deviceno As Long
partionno As Long
End Type
Public Function DeviceCheckMedia(sDrive As String) As ddevicetype
Dim hDevice As Long
Dim bytesReturned As Long
Dim success As Long
Dim sdn As ddevicetype
'Open a handle to drive
hDevice = CreateFile("\\.\" & sDrive, _
GENERIC_READ, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
ByVal 0&, _
OPEN_EXISTING, _
0&, 0&)
'Issue GET_DEVICE_NUMBER command to DeviceIoControl
If hDevice <> INVALID_HANDLE_VALUE Then
success = DeviceIoControl(hDevice, _
IOCTL_STORAGE_GET_DEVICE_NUMBER, _
0&, _
0&, _
sdn, _
Len(sdn), _
bytesReturned, _
ByVal 0&)
End If
'Close Handle to drive
Call CloseHandle(hDevice)
'Return sdn contianing drive type, drive #, and partition #
DeviceCheckMedia = sdn
End Function
Re: Get physical drive number given a drive letter
Here's some code i wrote a long time ago that finds all drives by their letter.
Code:
Declare Function GetDriveType& Lib "kernel32" Alias "GetDriveTypeA" (ByVal _
nDrive As String)
privat sub whatever()
For Cl = 97 To 97 + 26
dt = 0
dt = GetDriveType(Chr(Cl) + ":\")
If Cl < 102 Then MsgBox dt
If dt <> 1 Then
msgbox "Found drive " & Chr(Cl) + ":"
End If
Next Cl
end sub
Re: Get physical drive number given a drive letter
Try this API
Code:
Private Declare Function PathGetDriveNumber Lib "shlwapi.dll" _
Alias "PathGetDriveNumberA" (ByVal pszPath As String) As Long
It will return a number for any letter you pass, from "A:" to "Z:". So, you must be sure that Drive letter is Valid.
But, it seems that the drive number is always the same for a given letter, can it really be so simple?
Example, Add a multiline Textbox and this code..
Code:
Dim i As Long, lDriveLetter As String
Text1.Text = vbNullString
For i = 65 To 90 'From A to Z
lDriveLetter = Chr(i) & ":"
Text1.Text = Text1.Text & lDriveLetter & vbTab & _
PathGetDriveNumber(lDriveLetter) & vbNewLine
Next
Re: Get physical drive number given a drive letter
See my code above. that determines if the drive letter is valid. PathGetDriveNumber is designed to parse a string for a drive letter and tell you the number, so there isn't any checking in it. The docs i read on it indicate that they are always the same. Coupling this with my experience of using DEBUG, which uses the number instead of the letter, i will be inclined to agree that they don't change.
Re: Get physical drive number given a drive letter
Thanks, Mystic, I'll take a look at that. I'm concerned about your use of the term "logical" instead of "physical" when describing the drive number, but I'm holding out hope.
jcis and Lord Orwell, I don't think it's that simple. Let's say you have a 100 gig hard drive that you partition into two logical drives: C: and D:. They are the same physical drive, but they are different logical drives. So in such an instance, I need both C: and D: to return the same number. It's possible that PathGetDriveNumber does, but sadly I don't have a partitioned hard drive to test it out on.
My purpose is to read the physical drive's serial number. I have code to do that, but it uses the physical drive number as a parameter. Also of note is that I don't think it works for SCSI drives, because the enumerated "physical drive numbers" it accepts are defined as:
1: Primary IDE Master
2: Primary IDE Slave
3: Secondary IDE Master
4: Secondary IDE Slave
5: Teritiary IDE Master
6: Tertiary IDE Slave
...etc...
Re: Get physical drive number given a drive letter
Sorry, I mis-spoke there. I did mean physical drive.
I'm not sure if this will help you generating the input you listed, this will give you the physical drive numbers as they are listed in the drive managment console. I'm not sure how you would find out which controller it is connected to becasue windows will assign a drive number the same whether you add a second drive to an IDE controller or plug in a USB drive. There may be a way to get the serial number directly with DeviceIoControl instead?
Just to clarify. The function returns 3 things
sdn.DEVICE_TYPE - type of drive, 7 for fixed disk, there is a list of the other return codes somewhere if you need them. I was only concerned with fixed disks.
sdn.deviceno - the device number or phycial disk number of the drive, 0 for first physical drive, 1 for 2nd, etc...
sdn.partitionno - the number of the partition, 1st partion on a physical disk is 1, second is 2 etc...
So, using your 100GB dirve with 2 partitons as an example