-
Dec 4th, 2023, 03:53 PM
#1
Thread Starter
Frenzied Member
What's wrong with DeviceIoControl?
I'm trying to do this in Visual Basic 6. I'm following, to the best of my understanding, how I'm supposed to use the DeviceIoControl API function, and I'm trying to use it with the IOCTL_STORAGE_QUERY_PROPERTY to retrieve info about my harddrive (this includes things like the serial number and the manufacturer ID and product ID). But it keeps giving me error 24, which is ERROR_BAD_LENGTH, according to the Microsoft documentation. I don't know what's wrong.
-
Dec 4th, 2023, 05:46 PM
#2
Re: What's wrong with DeviceIoControl?
The UDTs involved use a lot of unions, bitfields, and c-style arrays, none of which VB supports, so it's very tricky to declare them in a compatible way. And of course the last one requires querying for the required size first.
I know there's several examples of that particular ioctl though, so just search the forum.
-
Dec 4th, 2023, 11:50 PM
#3
Thread Starter
Frenzied Member
Re: What's wrong with DeviceIoControl?
Originally Posted by fafalone
The UDTs involved use a lot of unions, bitfields, and c-style arrays, none of which VB supports, so it's very tricky to declare them in a compatible way. And of course the last one requires querying for the required size first.
I know there's several examples of that particular ioctl though, so just search the forum.
After looking at some other example, I finally figured out how to do it (no thanks to the MS docs, as I'd already read all the applicable docs, but they weren't helping me get past this error). Fortunately I didn't have to deal with bitfields or unions or c-style arrays, for this particular IOCTL. Only thing that I had to account for was the pointers to null terminated strings (which VB6 doesn't support directly, but I was able to write my own function to handle these, using the GetMem1 function of MSVBVM60.DLL to copy the string from a known memory address, one ascii character at a time, until it hit a 0x00 byte). It now does work.
Here's a screenshot of what I was able to get it to print.
Note that I redacted most of the serial number, because I've heard that unique numbers like this can be useful to track people (after all, that number, along with other info, is commonly used in software activation, to lock your software to just one computer, or in online game bans to ban your computer, regardless if you're using a VPN to dodge an IP ban).
Here's the final code I got for this.
Code:
Private Declare Sub GetMem1 Lib "msvbvm60.dll" (ByRef Source As Any, ByRef Destination As Any)
Private Declare Function DeviceIoControl Lib "kernel32.dll" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, ByRef lpInBuffer As Any, ByVal nInBufferSize As Long, ByRef lpOutBuffer As Any, ByVal nOutBufferSize As Long, ByRef lpBytesReturned As Long, ByRef lpOverlapped As Any) As Long
Private Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByRef lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Const FILE_SHARE_READ As Long = 1
Private Const FILE_SHARE_WRITE As Long = 2
Private Const OPEN_EXISTING As Long = 3
Private Const IOCTL_STORAGE_QUERY_PROPERTY As Long = &H2D1400
Private Type STORAGE_PROPERTY_QUERY
PropertyID As Long
QueryType As Long
AdditionalParameters(4095) As Byte
End Type
Private Type STORAGE_DEVICE_DESCRIPTOR
Version As Long
Size As Long
DeviceType As Byte
DeviceTypeModifier As Byte
RemovableMedia As Byte
CommandQueueing As Byte
VendorIdOffset As Long
ProductIdOffset As Long
ProductRevisionOffset As Long
SerialNumberOffset As Long
BusType As Long
RawDeviceProperties(4095) As Byte
End Type
Private Sub Form_Load()
Dim Query As STORAGE_PROPERTY_QUERY
Dim Descriptor As STORAGE_DEVICE_DESCRIPTOR
Dim hDev As Long
Dim RetVal As Long
Dim BytesRead As Long
hDev = CreateFile("\\.\PhysicalDrive0", 0, FILE_SHARE_READ + FILE_SHARE_WRITE, ByVal 0&, OPEN_EXISTING, 0, 0)
If hDev = -1 Then
Print Err.LastDllError
Exit Sub
End If
RetVal = DeviceIoControl(hDev, IOCTL_STORAGE_QUERY_PROPERTY, Query, LenB(Query), Descriptor, LenB(Descriptor), BytesRead, ByVal 0&)
If RetVal = 0 Then
Print Err.LastDllError
CloseHandle hDev
Exit Sub
End If
CloseHandle hDev
With Descriptor
Print "Vendor ID: ";
If .VendorIdOffset > 0 Then PrintStringAtAddr .VendorIdOffset + VarPtr(Descriptor) Else Print ""
Print "Product ID: ";
If .ProductIdOffset > 0 Then PrintStringAtAddr .ProductIdOffset + VarPtr(Descriptor) Else Print ""
Print "Product Revision: ";
If .ProductRevisionOffset > 0 Then PrintStringAtAddr .ProductRevisionOffset + VarPtr(Descriptor) Else Print ""
Print "Serial Number: ";
If .SerialNumberOffset > 0 Then PrintStringAtAddr .SerialNumberOffset + VarPtr(Descriptor) Else Print ""
End With
End Sub
Private Sub PrintStringAtAddr(ByVal MemAddr As Long)
Dim Char As Byte
Dim Buffer As String
Do
GetMem1 ByVal MemAddr, Char
If Char = 0 Then Exit Do
Buffer = Buffer & Chr$(Char)
MemAddr = MemAddr + 1
Loop
Print Trim$(Buffer)
End Sub
One interesting thing I noticed is that with my harddrive, the Vendor ID field is unused. Instead, the company put their name (along with the model number of the harddrive) in the Product ID field.
Last edited by Ben321; Dec 4th, 2023 at 11:53 PM.
-
Dec 5th, 2023, 08:55 AM
#4
Re: What's wrong with DeviceIoControl?
Yeah a lot of this stuff is vendor-specific.
That will get HDD serial numbers. The issue of serial numbers for NVME drives was never resolved unfortunately. I can obtain the NVME_IDENTIFY_CONTROLLER_DATA (same message, but larger buffer needed), but the SN (serial number) field doesn't match, with or without byte order reversal. One of these days I'll buckle down and spend the many hours it would take to follow the path CrystalDiskInfo uses... they've got a huge number of different combinations for different vendors and different drive types.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|