ioa747 Posted December 5, 2023 Share Posted December 5, 2023 the information is also in the register Computer\HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 1\Target Id 0\Logical Unit Id 0 r2du-soft 1 I know that I know nothing Link to comment Share on other sites More sharing options...
Andreik Posted December 5, 2023 Share Posted December 5, 2023 6 minutes ago, ioa747 said: the information is also in the register Computer\HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 1\Target Id 0\Logical Unit Id 0 Doesn't look very reliable but I might be wrong. r2du-soft 1 Link to comment Share on other sites More sharing options...
argumentum Posted December 5, 2023 Share Posted December 5, 2023 14 minutes ago, Andreik said: Looks fine for me. Because these are not NVMe https://crystalmark.info/en/download/ also gives out the right SN r2du-soft 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
argumentum Posted December 5, 2023 Share Posted December 5, 2023 11 minutes ago, ioa747 said: Computer\HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\.... also has the wrong data r2du-soft 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Andreik Posted December 5, 2023 Share Posted December 5, 2023 3 minutes ago, argumentum said: Because these are not NVMe https://crystalmark.info/en/download/ also gives out the right SN I'll have a look later, it's 6 AM here and I didn't sleep yet. r2du-soft 1 Link to comment Share on other sites More sharing options...
argumentum Posted December 5, 2023 Share Posted December 5, 2023 1 minute ago, Andreik said: it's 6 AM ..bright and early. Good time to start the day coding This ( https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddstor/ne-ntddstor-_storage_protocol_nvme_data_type ) may bring some light into he dilemma. g'night r2du-soft 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
r2du-soft Posted December 6, 2023 Author Share Posted December 6, 2023 (edited) Thank you to all friends, Especially Andreik I didn't want to use wmic because I was getting errors on some computers. I tested Andreik's code on the computer where I was receiving the error and it displayed the serial code in the output without any problem. You can also guide me about the following codes? expandcollapse popup#include <MsgBoxConstants.au3> #include <WinAPI.au3> MsgBox($MB_ICONINFORMATION,"_Win32_ComputerSystem", _Win32_ComputerSystem()) MsgBox($MB_ICONINFORMATION,"_WinAPI_GetPhysicallyInstalledSystemMemory", __WinAPI_GetPhysicallyInstalledSystemMemory()) MsgBox($MB_ICONINFORMATION,"_Win32_ComputerSystemProduct", _Win32_ComputerSystemProduct()) MsgBox($MB_ICONINFORMATION,"_Win32_VideoController", _Win32_VideoController()) MsgBox($MB_ICONINFORMATION,"_Win32_Processor", _Win32_Processor()) Func _Win32_ComputerSystem() $Obj_WMIService = ObjGet("winmgmts:\\" & "localhost" & "\root\cimv2") $Obj_Services = $Obj_WMIService.ExecQuery("Select * from Win32_ComputerSystem") For $Obj_Item In $Obj_Services $manufacturer = $Obj_Item.Manufacturer $Motherboard_System_Model_Info = $Obj_Item.Model Next IF ($Motherboard_System_Model_Info) Then Return $Motherboard_System_Model_Info Else Return "Error" EndIF EndFunc Func __WinAPI_GetPhysicallyInstalledSystemMemory() $Installed_RAM_Info = _WinAPI_GetPhysicallyInstalledSystemMemory() IF Not ($Installed_RAM_Info) OR ($Installed_RAM_Info == "0") Then $Installed_RAM_Info = "not available" ELSE $Installed_RAM_Info = $Installed_RAM_Info /1024 /1000 & " GB" EndIF Return $Installed_RAM_Info EndFunc Func _Win32_ComputerSystemProduct() $oWMIService = ObjGet("winmgmts:\\" & "localhost" & "\root\cimv2") $oSysProd = $oWMIService.ExecQuery("Select * From Win32_ComputerSystemProduct") For $oSysProp In $oSysProd $Device_UUID = $oSysProp.UUID Next IF ($Device_UUID) Then Return $Device_UUID Else Return "Error" EndIF EndFunc Func _Win32_VideoController() $Obj_WMIService = ObjGet("winmgmts:\\" & "localhost" & "\root\cimv2") $Obj_Services = $Obj_WMIService.ExecQuery("Select * from Win32_VideoController") For $Obj_Item In $Obj_Services $Graphic_Info = $Obj_Item.Name Next IF ($Graphic_Info) Then Return $Graphic_Info Else Return "Error" EndIF EndFunc Func _Win32_Processor() $Obj_WMIService = ObjGet("winmgmts:\\" & "localhost" & "\root\cimv2") $Obj_Services = $Obj_WMIService.ExecQuery("Select * from Win32_Processor") For $Obj_Item In $Obj_Services $Cpu_Info = $Obj_Item.Name Next IF ($Cpu_Info) Then Return $Cpu_Info Else Return "Error" EndIF EndFunc I want to produce the output like hard disk serial without using wmic Regards Edited December 6, 2023 by r2du-soft Link to comment Share on other sites More sharing options...
Andreik Posted December 6, 2023 Share Posted December 6, 2023 5 hours ago, r2du-soft said: I didn't want to use wmic because I was getting errors on some computers. As you probably noticed, to get some info you need admin privileges. So this might be a reason why sometimes it doesn't work. Have you tried to get these info using command line and parse the output or power shell? Link to comment Share on other sites More sharing options...
r2du-soft Posted December 30, 2023 Author Share Posted December 30, 2023 (edited) On 12/6/2023 at 10:02 PM, Andreik said: As you probably noticed, to get some info you need admin privileges. So this might be a reason why sometimes it doesn't work. Have you tried to get these info using command line and parse the output or power shell? Andreik I apologize for my late reply, No, I haven't done this, but I know that the access level of the items I have this problem with is the administrator, and the program is also run at the administrator level! At the moment, I don't know where the problem is, if I get more information, I will put more detailed information . Now I have a question, during the execution of the code that you send us, I was testing it on my work system and I noticed that the hardware serial is not generated. The error occurs in the following code section Local $aDevice = _WinAPI_GetDriveNumber ($sDriveLetter) If @error Then Return SetError(1, @error, Null) And the serial output is empty. I tried to solve the error using the following method: Local $aDevice = _WinAPI_GetDriveNumber($sDriveLetter) ;If @error Then Return SetError(1, @error, Null) If IsArray($aDevice) THEN $aDeviceNum = $aDevice[1] Else $aDeviceNum = 0 ENDIF Local $hDevice = _WinAPI_CreateFile('\\.\PhysicalDrive' & $aDeviceNum, 2, 2, 6) But I think it is not right to do this! I think what I did is not good, but it works and shows me the right hard drive! What do you think is the best way to solve the problem? in another way i import functions _WinAPI_GetDriveNumber and __CheckErrorCloseHandle to my app, and just edit and comment line ;If Not $iCurErr And Not $aCall[0] Then $iCurErr = 10 now serial generate, But I still don't know if this is true or not Doesn't it cause problems and errors later? Edited December 30, 2023 by r2du-soft Add more details Link to comment Share on other sites More sharing options...
KaFu Posted December 30, 2023 Share Posted December 30, 2023 (edited) I use this in SMF which doesn't require admin access. Not quite sure, but I think @trancexx provided a lot to this code. expandcollapse popup#include <array.au3> #include <WinAPI.au3> $h_DLL_Kernel32 = DllOpen("kernel32.dll") $aData = _Drive_GetHardwareInfos_SMF("c") _ArrayDisplay($aData) Func _Drive_GetHardwareInfos_SMF($DriveLetter) Local $a_Info_Drive_Hardware_temp[4] Local $ret, $tTemp, $ptrTemp $ret = DllCall($h_DLL_Kernel32, 'ptr', 'CreateFileW', _ 'wStr', '\\.\' & $DriveLetter & ':', _ 'dword', 0, _ 'dword', 7, _ 'ptr', 0, _ 'dword', 3, _ 'dword', 0, _ 'ptr', 0 _ ) If @error Then Return SetError(1, 0, $a_Info_Drive_Hardware_temp) If $ret[0] = 0xFFFFFFFF Then Return SetError(2, 0, $a_Info_Drive_Hardware_temp) Local $hDevice = $ret[0] Local Const $tagSTORAGE_PROPERTY_QUERY = 'ULONG_PTR PropertyId;ULONG_PTR QueryType;byte AdditionalParameters[4]' Local Const $tagSTORAGE_DESCRIPTOR_HEADER = 'ulong Version;ulong Size' Local $tSTORAGE_PROPERTY_QUERY = DllStructCreate($tagSTORAGE_PROPERTY_QUERY) DllStructSetData($tSTORAGE_PROPERTY_QUERY, 'PropertyId', 0) DllStructSetData($tSTORAGE_PROPERTY_QUERY, 'QueryType', 0) Local $tSTORAGE_DESCRIPTOR_HEADER = DllStructCreate($tagSTORAGE_DESCRIPTOR_HEADER) ; IOCTL_STORAGE_QUERY_PROPERTY = 0x002d1400 $ret = DllCall($h_DLL_Kernel32, 'int', 'DeviceIoControl', _ 'handle', $hDevice, _ 'dword', 0x002D1400, _ 'ptr', DllStructGetPtr($tSTORAGE_PROPERTY_QUERY), _ 'dword', DllStructGetSize($tSTORAGE_PROPERTY_QUERY), _ 'PTR', DllStructGetPtr($tSTORAGE_DESCRIPTOR_HEADER), _ 'dword', DllStructGetSize($tSTORAGE_DESCRIPTOR_HEADER), _ 'dword*', 0, _ 'ptr', 0 _ ) If DllStructGetData($tSTORAGE_DESCRIPTOR_HEADER, "Size") Then ; https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddstor/ns-ntddstor-_storage_device_descriptor Local Const $tagSTORAGE_DEVICE_DESCRIPTOR = 'ulong Version;ulong Size;char DeviceType;char DeviceTypeModifier;byte RemovableMedia;byte CommandQueueing;ulong VendorIdOffset;ulong ProductIdOffset;ulong ProductRevisionOffset;ulong SerialNumberOffset;ulong BusType;ulong RawPropertiesLength;byte RawDeviceProperties[' & DllStructGetData($tSTORAGE_DESCRIPTOR_HEADER, "Size") & ']' Local $tSTORAGE_DEVICE_DESCRIPTOR = DllStructCreate($tagSTORAGE_DEVICE_DESCRIPTOR) $ret = DllCall($h_DLL_Kernel32, 'int', 'DeviceIoControl', _ 'handle', $hDevice, _ 'dword', 0x002D1400, _ 'PTR', DllStructGetPtr($tSTORAGE_PROPERTY_QUERY), _ 'dword', DllStructGetSize($tSTORAGE_PROPERTY_QUERY), _ 'PTR', DllStructGetPtr($tSTORAGE_DEVICE_DESCRIPTOR), _ 'dword', DllStructGetSize($tSTORAGE_DEVICE_DESCRIPTOR), _ 'dword*', 0, _ 'PTR', 0 _ ) ;ConsoleWrite("VendorIdOffset " & DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "VendorIdOffset") & @CRLF) If DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "VendorIdOffset") Then $ptrTemp = DllStructGetPtr($tSTORAGE_DEVICE_DESCRIPTOR) + DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "VendorIdOffset") $tTemp = DllStructCreate("char Temp[" & _WinAPI_StringLenA($ptrTemp) & "]", $ptrTemp) $a_Info_Drive_Hardware_temp[0] = DllStructGetData($tTemp, "Temp") ; ConsoleWrite($a_Info_Drive_Hardware_temp[0] & @CRLF) EndIf ;ConsoleWrite("ProductIdOffset " & DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "ProductIdOffset") & @CRLF) If DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "ProductIdOffset") Then $ptrTemp = DllStructGetPtr($tSTORAGE_DEVICE_DESCRIPTOR) + DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "ProductIdOffset") $tTemp = DllStructCreate("char Temp[" & _WinAPI_StringLenA($ptrTemp) & "]", $ptrTemp) $a_Info_Drive_Hardware_temp[1] = DllStructGetData($tTemp, "Temp") ; ConsoleWrite($a_Info_Drive_Hardware_temp[1] & @CRLF) EndIf ;ConsoleWrite("ProductRevisionOffset " & DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "ProductRevisionOffset") & @CRLF) If DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "ProductRevisionOffset") Then $ptrTemp = DllStructGetPtr($tSTORAGE_DEVICE_DESCRIPTOR) + DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "ProductRevisionOffset") $tTemp = DllStructCreate("char Temp[" & _WinAPI_StringLenA($ptrTemp) & "]", $ptrTemp) $a_Info_Drive_Hardware_temp[2] = DllStructGetData($tTemp, "Temp") ; ConsoleWrite($a_Info_Drive_Hardware_temp[2] & @CRLF) EndIf ;ConsoleWrite("SerialNumberOffset " & DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "SerialNumberOffset") & @CRLF) If "0x" & Hex(DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "SerialNumberOffset")) <> "0xFFFFFFFF" Then $ptrTemp = DllStructGetPtr($tSTORAGE_DEVICE_DESCRIPTOR) + DllStructGetData($tSTORAGE_DEVICE_DESCRIPTOR, "SerialNumberOffset") $tTemp = DllStructCreate("char Temp[" & _WinAPI_StringLenA($ptrTemp) & "]", $ptrTemp) $a_Info_Drive_Hardware_temp[3] = DllStructGetData($tTemp, "Temp") ; ConsoleWrite($a_Info_Drive_Hardware_temp[3] & @CRLF) EndIf EndIf $a_Info_Drive_Hardware_temp[0] = _StringToReadable($a_Info_Drive_Hardware_temp[0]) $a_Info_Drive_Hardware_temp[1] = _StringToReadable($a_Info_Drive_Hardware_temp[1]) $a_Info_Drive_Hardware_temp[2] = _StringToReadable($a_Info_Drive_Hardware_temp[2]) $a_Info_Drive_Hardware_temp[3] = _SwapStringOrder(_StringToReadable($a_Info_Drive_Hardware_temp[3])) DllCall($h_DLL_Kernel32, 'int', 'CloseHandle', 'hwnd', $hDevice) Return $a_Info_Drive_Hardware_temp EndFunc ;==>_Drive_GetHardwareInfos_SMF Func _StringToReadable($sString) Local $sString_Return, $iAscCode Local $aString = StringSplit($sString, "") For $i = 1 To $aString[0] $iAscCode = Asc($aString[$i]) Switch $iAscCode ; Case 32 to 126 Case 32, 48 To 57, 65 To 90, 97 To 122 $sString_Return &= $aString[$i] EndSwitch Next Return $sString_Return EndFunc ;==>_StringToReadable Func _SwapStringOrder($sString) Local $sString_Return, $iAscCode ; ConsoleWrite($sString & @TAB & StringLen($sString) & @CRLF) Local $aString = StringSplit($sString, "") For $i = 1 To $aString[0] Step 2 If $i + 1 > $aString[0] Then $sString_Return &= $aString[$i] ExitLoop EndIf $sString_Return &= $aString[$i + 1] & $aString[$i] ; ConsoleWrite($i & @TAB & $aString[0] & @CRLF) Next Return $sString_Return EndFunc ;==>_SwapStringOrder Edited December 30, 2023 by KaFu r2du-soft 1 OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Andreik Posted December 30, 2023 Share Posted December 30, 2023 (edited) 2 hours ago, r2du-soft said: I tried to solve the error using the following method: Local $aDevice = _WinAPI_GetDriveNumber($sDriveLetter) ;If @error Then Return SetError(1, @error, Null) If IsArray($aDevice) THEN $aDeviceNum = $aDevice[1] Else $aDeviceNum = 0 ENDIF Local $hDevice = _WinAPI_CreateFile('\\.\PhysicalDrive' & $aDeviceNum, 2, 2, 6) But I think it is not right to do this! I think what I did is not good, but it works and shows me the right hard drive! What do you think is the best way to solve the problem? This might work in certain conditions but the result it's not guaranteed. Since you can pass the drive letter as parameter to GetDiskSerial() if you have multiple hard drives certain drive letters for sure won't be mapped to PhysicalDrive0. 2 hours ago, r2du-soft said: in another way i import functions _WinAPI_GetDriveNumber and __CheckErrorCloseHandle to my app, and just edit and comment line ;If Not $iCurErr And Not $aCall[0] Then $iCurErr = 10 now serial generate, But I still don't know if this is true or not Doesn't it cause problems and errors later? It looks like a fail in calling DeviceIoControl() for IOCTL_STORAGE_GET_DEVICE_NUMBER control code. And since the members of the resulting structure is not filled with any data your happy result it's 0 by luck as the above hard coded value. You can test this by calling this function instead of _WinAPI_GetDriveNumber(): Func __WinAPI_GetDriveNumber($sDrive) Local $hFile = _WinAPI_CreateFileEx('\\.\' & $sDrive, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE) If @error Then Return SetError(@error + 20, @extended, 0) Local $tSDN = DllStructCreate('dword;dword;dword') Local $aCall = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x002D1080, 'ptr', 0, _ 'dword', 0, 'struct*', $tSDN, 'dword', DllStructGetSize($tSDN), 'dword*', 0, 'ptr', 0) ConsoleWrite(IsArray($aCall) & @CRLF) ; <<< Added this line _WinAPI_CloseHandle($hFile) ; And close the file handle without aditional checks Local $aRet[3] For $i = 0 To 2 $aRet[$i] = DllStructGetData($tSDN, $i + 1) Next Return $aRet EndFunc Edit: looking at @KaFu's example it looks like you don't require admin privileges if DesiredAccess of _WinAPI_CreateFile() it's 0. Actually you can omit to get the actual physical drive if you are interested to use the function just with drive letter as parameter. Here is the modified version of the previous function: expandcollapse popup#include <WinAPIFiles.au3> #include <WinAPIHObj.au3> MsgBox(0, 'Serial', 'Disk serial: ' & GetDiskSerial(@HomeDrive)) Func GetDiskSerial($sDriveLetter) Local Const $IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400 Local $tagSTORAGE_PROPERTY_QUERY = 'int PropertyId; int QueryType; byte AdditionalParameters[1];' Local $tagSTORAGE_DESCRIPTOR_HEADER = 'dword Version;dword Size;' Local $tagSTORAGE_DEVICE_DESCRIPTOR = 'dword Version;dword Size; byte DeviceType;byte DeviceTypeModifier; boolean RemovableMedia;' & _ 'boolean CommandQueueing;dword VendorIdOffset;dword ProductIdOffset;dword ProductRevisionOffset;dword SerialNumberOffset;int BusType;' & _ 'dword RawPropertiesLength;byte RawDeviceProperties[1];' Local $hDevice = _WinAPI_CreateFile('\\.\' & $sDriveLetter, 2, 0, 6, 0, 0) If @error Then Return SetError(1, @error, Null) Local $tSTORAGE_PROPERTY_QUERY = DllStructCreate($tagSTORAGE_PROPERTY_QUERY) $tSTORAGE_PROPERTY_QUERY.PropertyId = 0 ; StorageDeviceProperty $tSTORAGE_PROPERTY_QUERY.QueryType = 0 ; PropertyStandardQuery Local $tSTORAGE_DESCRIPTOR_HEADER = DllStructCreate($tagSTORAGE_DESCRIPTOR_HEADER) If Not _WinAPI_DeviceIoControl($hDevice, $IOCTL_STORAGE_QUERY_PROPERTY, _ DllStructGetPtr($tSTORAGE_PROPERTY_QUERY), DllStructGetSize($tSTORAGE_PROPERTY_QUERY), _ DllStructGetPtr($tSTORAGE_DESCRIPTOR_HEADER), DllStructGetSize($tSTORAGE_DESCRIPTOR_HEADER)) _ Then _WinAPI_CloseHandle($hDevice) Return SetError(2, 0, Null) EndIf Local $tBuffer = DllStructCreate('byte[' & $tSTORAGE_DESCRIPTOR_HEADER.Size & ']') If Not _WinAPI_DeviceIoControl($hDevice, $IOCTL_STORAGE_QUERY_PROPERTY, _ DllStructGetPtr($tSTORAGE_PROPERTY_QUERY), DllStructGetSize($tSTORAGE_PROPERTY_QUERY), _ DllStructGetPtr($tBuffer), DllStructGetSize($tBuffer)) _ Then _WinAPI_CloseHandle($hDevice) Return SetError(3, 0, Null) EndIf Local $tSTORAGE_DEVICE_DESCRIPTOR = DllStructCreate($tagSTORAGE_DEVICE_DESCRIPTOR, DllStructGetPtr($tBuffer)) If $tSTORAGE_DEVICE_DESCRIPTOR.SerialNumberOffset = 0 Then _WinAPI_CloseHandle($hDevice) Return SetError(4, 0, Null) EndIf Local $tSerial = DllStructCreate('char Serial[32]', DllStructGetPtr($tBuffer) + $tSTORAGE_DEVICE_DESCRIPTOR.SerialNumberOffset) _WinAPI_CloseHandle($hDevice) Return $tSerial.Serial EndFunc Edited December 30, 2023 by Andreik Link to comment Share on other sites More sharing options...
argumentum Posted December 30, 2023 Share Posted December 30, 2023 NVMe drives right ?. They are a different animal. The name and hardware firmware revision are right, but the hardware drive serial needs a look at: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddstor/ne-ntddstor-_storage_protocol_nvme_data_type Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
r2du-soft Posted January 24 Author Share Posted January 24 (edited) On 12/5/2023 at 2:54 AM, Andreik said: The promised code: expandcollapse popup#RequireAdmin #include <WinAPIFiles.au3> #include <WinAPIHObj.au3> MsgBox(0, 'Serial', 'Disk serial: ' & GetDiskSerial(@HomeDrive)) Func GetDiskSerial($sDriveLetter) Local Const $IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400 Local $tagSTORAGE_PROPERTY_QUERY = 'int PropertyId; int QueryType; byte AdditionalParameters[1];' Local $tagSTORAGE_DESCRIPTOR_HEADER = 'dword Version;dword Size;' Local $tagSTORAGE_DEVICE_DESCRIPTOR = 'dword Version;dword Size; byte DeviceType;byte DeviceTypeModifier; boolean RemovableMedia;' & _ 'boolean CommandQueueing;dword VendorIdOffset;dword ProductIdOffset;dword ProductRevisionOffset;dword SerialNumberOffset;int BusType;' & _ 'dword RawPropertiesLength;byte RawDeviceProperties[1];' Local $aDevice = _WinAPI_GetDriveNumber ($sDriveLetter) If @error Then Return SetError(1, @error, Null) Local $hDevice = _WinAPI_CreateFile('\\.\PhysicalDrive' & $aDevice[1], 2, 2, 6) If @error Then Return SetError(2, @error, Null) Local $tSTORAGE_PROPERTY_QUERY = DllStructCreate($tagSTORAGE_PROPERTY_QUERY) $tSTORAGE_PROPERTY_QUERY.PropertyId = 0 ; StorageDeviceProperty $tSTORAGE_PROPERTY_QUERY.QueryType = 0 ; PropertyStandardQuery Local $tSTORAGE_DESCRIPTOR_HEADER = DllStructCreate($tagSTORAGE_DESCRIPTOR_HEADER) If Not _WinAPI_DeviceIoControl($hDevice, $IOCTL_STORAGE_QUERY_PROPERTY, _ DllStructGetPtr($tSTORAGE_PROPERTY_QUERY), DllStructGetSize($tSTORAGE_PROPERTY_QUERY), _ DllStructGetPtr($tSTORAGE_DESCRIPTOR_HEADER), DllStructGetSize($tSTORAGE_DESCRIPTOR_HEADER)) _ Then _WinAPI_CloseHandle($hDevice) Return SetError(3, 0, Null) EndIf Local $tBuffer = DllStructCreate('byte[' & $tSTORAGE_DESCRIPTOR_HEADER.Size & ']') If Not _WinAPI_DeviceIoControl($hDevice, $IOCTL_STORAGE_QUERY_PROPERTY, _ DllStructGetPtr($tSTORAGE_PROPERTY_QUERY), DllStructGetSize($tSTORAGE_PROPERTY_QUERY), _ DllStructGetPtr($tBuffer), DllStructGetSize($tBuffer)) _ Then _WinAPI_CloseHandle($hDevice) Return SetError(4, 0, Null) EndIf Local $tSTORAGE_DEVICE_DESCRIPTOR = DllStructCreate($tagSTORAGE_DEVICE_DESCRIPTOR, DllStructGetPtr($tBuffer)) If $tSTORAGE_DEVICE_DESCRIPTOR.SerialNumberOffset = 0 Then _WinAPI_CloseHandle($hDevice) Return SetError(5, 0, Null) EndIf Local $tSerial = DllStructCreate('char Serial[32]', DllStructGetPtr($tBuffer) + $tSTORAGE_DEVICE_DESCRIPTOR.SerialNumberOffset) _WinAPI_CloseHandle($hDevice) Return $tSerial.Serial EndFunc Hello I was checking on Windows 7 installed on Virtualbox when I came across the following: Each one shows something different! 1-CMD: Longer hex string 2-Autoit: Shorter hex string 3-Hwinfo: String value different from CMD and Autoit string output I am really confused and I don't know what the problem is Edited January 24 by r2du-soft Link to comment Share on other sites More sharing options...
KaFu Posted January 24 Share Posted January 24 (edited) VB 58 3a 07 93 -d ce 29 f0 0 BV 85 a3 70 39 d- ec 92 0f 0 Edit: $s = "VB583a0793-dce29f00" MsgBox(0,"",$s & @crlf & @crlf & _SwapStringOrder($s)) Func _SwapStringOrder($sString) Local $sString_Return, $iAscCode ; ConsoleWrite($sString & @TAB & StringLen($sString) & @CRLF) Local $aString = StringSplit($sString, "") For $i = 1 To $aString[0] Step 2 If $i + 1 > $aString[0] Then $sString_Return &= $aString[$i] ExitLoop EndIf $sString_Return &= $aString[$i + 1] & $aString[$i] ; ConsoleWrite($i & @TAB & $aString[0] & @CRLF) Next Return $sString_Return EndFunc ;==>_SwapStringOrder Edited January 24 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
guaikahenguai Posted January 26 Share Posted January 26 On 12/30/2023 at 8:27 PM, Andreik said: This might work in certain conditions but the result it's not guaranteed. Since you can pass the drive letter as parameter to GetDiskSerial() if you have multiple hard drives certain drive letters for sure won't be mapped to PhysicalDrive0. It looks like a fail in calling DeviceIoControl() for IOCTL_STORAGE_GET_DEVICE_NUMBER control code. And since the members of the resulting structure is not filled with any data your happy result it's 0 by luck as the above hard coded value. You can test this by calling this function instead of _WinAPI_GetDriveNumber(): Func __WinAPI_GetDriveNumber($sDrive) Local $hFile = _WinAPI_CreateFileEx('\\.\' & $sDrive, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE) If @error Then Return SetError(@error + 20, @extended, 0) Local $tSDN = DllStructCreate('dword;dword;dword') Local $aCall = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x002D1080, 'ptr', 0, _ 'dword', 0, 'struct*', $tSDN, 'dword', DllStructGetSize($tSDN), 'dword*', 0, 'ptr', 0) ConsoleWrite(IsArray($aCall) & @CRLF) ; <<< Added this line _WinAPI_CloseHandle($hFile) ; And close the file handle without aditional checks Local $aRet[3] For $i = 0 To 2 $aRet[$i] = DllStructGetData($tSDN, $i + 1) Next Return $aRet EndFunc Edit: looking at @KaFu's example it looks like you don't require admin privileges if DesiredAccess of _WinAPI_CreateFile() it's 0. Actually you can omit to get the actual physical drive if you are interested to use the function just with drive letter as parameter. Here is the modified version of the previous function: expandcollapse popup#include <WinAPIFiles.au3> #include <WinAPIHObj.au3> MsgBox(0, 'Serial', 'Disk serial: ' & GetDiskSerial(@HomeDrive)) Func GetDiskSerial($sDriveLetter) Local Const $IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400 Local $tagSTORAGE_PROPERTY_QUERY = 'int PropertyId; int QueryType; byte AdditionalParameters[1];' Local $tagSTORAGE_DESCRIPTOR_HEADER = 'dword Version;dword Size;' Local $tagSTORAGE_DEVICE_DESCRIPTOR = 'dword Version;dword Size; byte DeviceType;byte DeviceTypeModifier; boolean RemovableMedia;' & _ 'boolean CommandQueueing;dword VendorIdOffset;dword ProductIdOffset;dword ProductRevisionOffset;dword SerialNumberOffset;int BusType;' & _ 'dword RawPropertiesLength;byte RawDeviceProperties[1];' Local $hDevice = _WinAPI_CreateFile('\\.\' & $sDriveLetter, 2, 0, 6, 0, 0) If @error Then Return SetError(1, @error, Null) Local $tSTORAGE_PROPERTY_QUERY = DllStructCreate($tagSTORAGE_PROPERTY_QUERY) $tSTORAGE_PROPERTY_QUERY.PropertyId = 0 ; StorageDeviceProperty $tSTORAGE_PROPERTY_QUERY.QueryType = 0 ; PropertyStandardQuery Local $tSTORAGE_DESCRIPTOR_HEADER = DllStructCreate($tagSTORAGE_DESCRIPTOR_HEADER) If Not _WinAPI_DeviceIoControl($hDevice, $IOCTL_STORAGE_QUERY_PROPERTY, _ DllStructGetPtr($tSTORAGE_PROPERTY_QUERY), DllStructGetSize($tSTORAGE_PROPERTY_QUERY), _ DllStructGetPtr($tSTORAGE_DESCRIPTOR_HEADER), DllStructGetSize($tSTORAGE_DESCRIPTOR_HEADER)) _ Then _WinAPI_CloseHandle($hDevice) Return SetError(2, 0, Null) EndIf Local $tBuffer = DllStructCreate('byte[' & $tSTORAGE_DESCRIPTOR_HEADER.Size & ']') If Not _WinAPI_DeviceIoControl($hDevice, $IOCTL_STORAGE_QUERY_PROPERTY, _ DllStructGetPtr($tSTORAGE_PROPERTY_QUERY), DllStructGetSize($tSTORAGE_PROPERTY_QUERY), _ DllStructGetPtr($tBuffer), DllStructGetSize($tBuffer)) _ Then _WinAPI_CloseHandle($hDevice) Return SetError(3, 0, Null) EndIf Local $tSTORAGE_DEVICE_DESCRIPTOR = DllStructCreate($tagSTORAGE_DEVICE_DESCRIPTOR, DllStructGetPtr($tBuffer)) If $tSTORAGE_DEVICE_DESCRIPTOR.SerialNumberOffset = 0 Then _WinAPI_CloseHandle($hDevice) Return SetError(4, 0, Null) EndIf Local $tSerial = DllStructCreate('char Serial[32]', DllStructGetPtr($tBuffer) + $tSTORAGE_DEVICE_DESCRIPTOR.SerialNumberOffset) _WinAPI_CloseHandle($hDevice) Return $tSerial.Serial EndFunc Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now