kxing 发表于 2012-2-7 13:38:58

请问关于AHCI模式下的硬盘ID获取不到的问题

本帖最后由 kxing 于 2012-2-8 14:39 编辑

请问有些硬盘为什么获取不到序列号呢
用过了本坛所有代码都是获取不到。
cpu序列号就正常。
还望高手指点指点!!!

netegg 发表于 2012-2-7 14:42:18

#Include <WinAPIEx.au3>
_Winapi_GetDiskSerialNumber

epac 发表于 2012-2-7 16:14:45

来学习了……

kxing 发表于 2012-2-7 18:23:40

多谢,我在帮助里面没找到这个函数呢

kxing 发表于 2012-2-7 19:11:08

表达错了,应该是获取硬盘ID。
听说现在AHCI的硬盘都无法获取到硬盘ID,请问是这样的吗

boyhong 发表于 2012-2-7 19:23:27

回复 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:29:35

本帖最后由 netegg 于 2012-2-7 20:32 编辑

回复 6# boyhong
这个就是那个函数的原型,kxing要的可能是harddisk0,harddisk1,。。。这些东西,或者是部署linux前面的那些hd0,hd1,一类的玩意

seniors 发表于 2012-2-7 21:29:56

下面这个是能显示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

kxing 发表于 2012-2-7 21:43:24

回复 8# seniors


   
我是想获取硬盘的ID呢,不是盘符。。。

另外 boyhong 的估计不行,我在本论坛所有能获取的都尝试过了。。。

afan 发表于 2012-2-7 23:15:49

序列号在哪看?P版的帖子试过没?

80ren 发表于 2012-2-8 00:31:18

楼主解决了吗?

kxing 发表于 2012-2-8 14:34:02

没啊,只要把AHCI模式改成IDE就正常获取到硬盘的ID
回afan,应该不算是序列号,是ID。

kxing 发表于 2012-2-8 14:39:29

afan大说的是这个帖子吧,都试过了。不行!!!
http://autoitx.com/forum.php?mod=viewthread&tid=9507&highlight=%D3%B2%C5%CC

zch11230 发表于 2012-2-8 17:04:15

AHCI下很多专业软件都无法获取硬盘信息 比如通电时间 缓存大小 至于序列号这个没关注如果实在不能获取我觉得也可以理解。

kxing 发表于 2012-2-9 11:17:22

那就麻烦了,软件需要通过获取硬盘id来绑定使用。。。
获取不到就没辙了!!!!!!!
页: [1] 2
查看完整版本: 请问关于AHCI模式下的硬盘ID获取不到的问题