请问关于AHCI模式下的硬盘ID获取不到的问题
本帖最后由 kxing 于 2012-2-8 14:39 编辑请问有些硬盘为什么获取不到序列号呢
用过了本坛所有代码都是获取不到。
cpu序列号就正常。
还望高手指点指点!!! #Include <WinAPIEx.au3>
_Winapi_GetDiskSerialNumber 来学习了…… 多谢,我在帮助里面没找到这个函数呢 表达错了,应该是获取硬盘ID。
听说现在AHCI的硬盘都无法获取到硬盘ID,请问是这样的吗 回复 1# kxing
试试这个呢?------来源于本论坛:
#include <WinAPI.au3>
$tSCIP = 0
$tSCOP = 0
$tQuery = 0
$tDescr = 0
Local $num=_GetDiskNum(0) ;这个0是硬盘的序号。 有几个硬盘就是几减1。 比如,想获取第三个硬盘的硬盘号,则是_GetDiskNum(2)
MsgBox(0,"",$num)
Func _GetDiskNum($DiskID = "0")
$sPhysDisk="\\.\PhysicalDrive"&$DiskID
Const $IOCTL_STORAGE_BASE = 0x2D
Const $IOCTL_STORAGE_QUERY_PROPERTY = _MakeCtrlCode($IOCTL_STORAGE_BASE, 0x500)
Const $DFP_RECEIVE_DRIVE_DATA = 0x7C088
Const $tagSTORAGEPROPERTYQUERY = "int PropertyId;int QueryType;byte AdditionalParams"
Const $tagSTORAGEDEVICEDESCRIPTOR = "ulong Version;ulong Size;byte DeviceType;" & _
"byte DeviceTypeModifier;byte RemovableMedia;" & _
"byte CommandQueueing;ulong VendorIdOffset;" & _
"ulong ProductIdOffset;ulong ProductRevisionOffset;" & _
"ulong SerialNumberOffset;int BusType;" & _
"ulong RawPropertiesLength;byte RawDeviceProperties"
Const $tagDRIVERSTATUS = "byte DriverError;byte IDEStatus;byte Reserved1;dword Reserved2"
Const $tagIDEREGS = "byte Features;byte SectorCount;byte SectorNumber;byte CylLow;" & _
"byte CylHigh;byte DriveHead;byte Command;byte Reserved"
Const $tagSENDCMDOUTPARAMS = "dword Size;" & $tagDRIVERSTATUS
Const $tagSENDCMDINPARAMS = "dword Size;" & $tagIDEREGS & ";byte DriveNumber;" & _
"byte Reserved1;dword Reserved2;byte Buffer"
$hDisk = _WinAPI_CreateFile($sPhysDisk, 2, 6, 6, 1)
If $hDisk = -1 Then
Return @error
EndIf
$tSCIP = DllStructCreate($tagSENDCMDINPARAMS)
$tSCOP = DllStructCreate($tagSENDCMDOUTPARAMS & ";char Buffer")
$tQuery = DllStructCreate($tagSTORAGEPROPERTYQUERY)
$tDescr = DllStructCreate($tagSTORAGEDEVICEDESCRIPTOR)
DllStructSetData($tQuery, "PropertyId", 0)
DllStructSetData($tQuery, "QueryType", 0)
$iResult = _DeviceIoControl($hDisk, $IOCTL_STORAGE_QUERY_PROPERTY, _
$tQuery, DllStructGetSize($tQuery), _
$tDescr, DllStructGetSize($tDescr))
If $iResult = 0 Then
Return @error
EndIf
If DllStructGetData($tDescr, "BusType") = 2 Then
DllStructSetData($tSCIP, "Command", 0xA1)
Else
DllStructSetData($tSCIP, "Command", 0xEC)
EndIf
$iResult = _DeviceIoControl($hDisk, $DFP_RECEIVE_DRIVE_DATA, _
$tSCIP, DllStructGetSize($tSCIP), _
$tSCOP, DllStructGetSize($tSCOP))
If $iResult = 0 Then
MsgBox(16,"错误!","_DeviceIoControl fails, error code: " & @error ,5)
Exit
EndIf
Dim $sSerialNum
For $i = 21 to 40 Step 2
$sSerialNum &= DllStructGetData($tSCOP, "Buffer", $i + 1)
$sSerialNum &= DllStructGetData($tSCOP, "Buffer", $i)
Next
$sSerialNum = StringReplace($sSerialNum, " ", "")
;输出显示
;Msgbox(0, "", $sPhysDisk & "'s serial number: " & $sSerialNum)
Return $sSerialNum
_WinAPI_CloseHandle($hDisk)
EndFunc
Func _MakeCtrlCode($iDevType, $iFunction, $iMethod = 0, $iAccess = 0)
Return bitOR(bitShift($iDevType,-16),bitShift($iAccess, -14),bitShift($iFunction, -2), $iMethod)
EndFunc ;==>_MakeCtrlCode
Func _DeviceIoControl($hDevice, $iCtrlCode, $pIn, $iIn, $pOut, $iOut, $pOverlapped = 0)
Local $iResult
If IsDllStruct($pIn) Then $pIn = DllStructGetPtr($pIn)
If IsDllStruct($pOut) Then $pOut = DllStructGetPtr($pOut)
If IsDllStruct($pOverlapped) Then $pOverlapped = DllStructGetPtr($pOverLapped)
$iResult = DllCall("Kernel32.dll", "int", "DeviceIoControl", "ptr", $hDevice, _
"dword", $iCtrlCode, "ptr", $pIn, "dword", $iIn, _
"ptr", $pOut, "dword", $iOut, "int*", 0, "ptr", $pOverlapped)
Return SetError(_WinAPI_GetLastError(), $iResult, $iResult)
EndFunc ;==>_DeviceIoControl
本帖最后由 netegg 于 2012-2-7 20:32 编辑
回复 6# boyhong
这个就是那个函数的原型,kxing要的可能是harddisk0,harddisk1,。。。这些东西,或者是部署linux前面的那些hd0,hd1,一类的玩意 下面这个是能显示hd0,hd1,hd2的
GetPartionMsg("", 1) ;GetPartionMsg 的第一个参数可以是 USB、IDE 等;如果不带任何参数,则是检测所有磁盘分区
;第二个参数可以是 1、0,1 表示 TRUE,0 表示 FALSE;如果第一个参数为空,则第二个必需为 1
Func GetPartionMsg($Interface, $b)
$objWMIService = ObjGet("winmgmts:\\.\root\cimv2")
$colItems = $objWMIService.ExecQuery ("Select * from Win32_LogicalDiskToPartition")
$DiskInfo = ""
$DiskInfoCombo = ""
For $objItem In $colItems
MsgBox(64,"",$objItem.Dependent)
$DiskFH = StringLeft(StringRight($objItem.Dependent, 3), 2)
$PartNum = QueryDiskNum($DiskFH)
$PartMsg = QueryPartitionVolume($DiskFH)
If $Interface <> "" Then
If $b = 1 Then
If StringMid($PartNum, 2, 3) = $Interface Then
$DiskInfo = $DiskInfo & $PartNum & $DiskFH & $PartMsg & @CRLF
EndIf
ElseIf $b = 0 Then
If StringMid($PartNum, 2, 3) <> $Interface Then
$DiskInfo = $DiskInfo & $PartNum & $DiskFH & $PartMsg & @CRLF
EndIf
EndIf
Else
$DiskInfo = $DiskInfo & $PartNum & $DiskFH & $PartMsg & @CRLF
EndIf
Next
MsgBox(64, "磁盘信息", $DiskInfo)
EndFunc ;==>GetPartionMsg
Func QueryDiskInterface($n)
$objWMIService = ObjGet("winmgmts:\\.\root\cimv2")
$colItems = $objWMIService.ExecQuery ("Select * from Win32_DiskDrive Where Index=" & $n)
For $objItem In $colItems
Return $objItem.InterfaceType
Next
EndFunc ;==>QueryDiskInterface
Func QueryPartitionVolume($v)
$objWMIService = ObjGet("winmgmts:\\.\root\cimv2")
$colItems = $objWMIService.ExecQuery ("Select * from Win32_LogicalDisk Where DeviceID='" & $v & "'")
For $objItem In $colItems
Return $objItem.VolumeName & "" & $objItem.FileSystem & "_" & CalcKMG($objItem.Size) & "_" & $objItem.Description
Next
EndFunc ;==>QueryPartitionVolume
Func QueryDiskNum($d)
$objWMIService = ObjGet("winmgmts:\\.\root\cimv2")
$colItems = $objWMIService.ExecQuery ("Associators of {win32_LogicalDisk.DeviceID='" & $d & "'} where ResultClass = Win32_DiskPartition")
For $colItem In $colItems
Return "(" & QueryDiskInterface($colItem.DiskIndex) & ":hd" & $colItem.DiskIndex & ")"
Next
EndFunc ;==>QueryDiskNum
Func CalcKMG($n)
If $n < 1024 Then
Return $n & "Byte"
ElseIf $n < 1048576 Then
Return Round($n / 1024, 2) & "KB"
ElseIf $n < 1073741824 Then
Return Round($n / 1048576, 2) & "MB"
Else
Return Round($n / 1073741824, 2) & "GB"
EndIf
EndFunc ;==>CalcKMG 回复 8# seniors
我是想获取硬盘的ID呢,不是盘符。。。
另外 boyhong 的估计不行,我在本论坛所有能获取的都尝试过了。。。 序列号在哪看?P版的帖子试过没? 楼主解决了吗? 没啊,只要把AHCI模式改成IDE就正常获取到硬盘的ID
回afan,应该不算是序列号,是ID。 afan大说的是这个帖子吧,都试过了。不行!!!
http://autoitx.com/forum.php?mod=viewthread&tid=9507&highlight=%D3%B2%C5%CC AHCI下很多专业软件都无法获取硬盘信息 比如通电时间 缓存大小 至于序列号这个没关注如果实在不能获取我觉得也可以理解。 那就麻烦了,软件需要通过获取硬盘id来绑定使用。。。
获取不到就没辙了!!!!!!!
页:
[1]
2