#include <WinAPI.au3>
#include <Crypt.au3>
MsgBox(0,0,_ReadPhysicalDriveInNTWithZeroRights())
Func _ReadPhysicalDriveInNTWithZeroRights($METHOD = 'SerialNumber', $ID = 0) ;非管理员权限
Local Const $tagSTORAGEPROPERTYQUERY = "int PropertyId;int QueryType;byte AdditionalParams[1]"
Local 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"
Local Const $sPhysDisk = "\\.\PhysicalDrive" & $ID
Local $aResult = DllCall("kernel32.dll", "handle", "CreateFileW", "wstr", $sPhysDisk, "dword", 0, "dword", BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), _
"struct*", Null, "dword", $OPEN_EXISTING, "dword", 0, "ptr", Null)
If @error Or ($aResult[0] = $INVALID_HANDLE_VALUE) Then Return SetError(@error, @extended, 'CreateFile fails,error code:' & @error)
Local $hDisk = $aResult[0]
Local $tQuery = DllStructCreate($tagSTORAGEPROPERTYQUERY)
Local $tDescr = DllStructCreate($tagSTORAGEDEVICEDESCRIPTOR)
Local $tDescrSize = DllStructGetSize($tDescr)
Local $tBuffer = DllStructCreate($tagSTORAGEDEVICEDESCRIPTOR & ";char Buffer[1024]")
DllStructSetData($tQuery, "PropertyId", 0)
DllStructSetData($tQuery, "QueryType", 0)
Local $iResult = _WinAPI_DeviceIoControl($hDisk, $IOCTL_STORAGE_QUERY_PROPERTY, _
$tQuery, DllStructGetSize($tQuery), _
$tBuffer, DllStructGetSize($tBuffer))
If $iResult = 0 Then Return SetError(@error, @extended, '_DeviceIoControl IOCTL_STORAGE_QUERY_PROPERTY fails, error code: ' & @error)
Local $ProductIdOffset = DllStructGetData($tBuffer, 'ProductIdOffset')
Local $SerialNumberOffset = DllStructGetData($tBuffer, 'SerialNumberOffset')
Local $ProductRevisionOffset = DllStructGetData($tBuffer, 'ProductRevisionOffset')
Local $BusType = DllStructGetData($tBuffer, 'BusType')
DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hDisk)
Local $ReturnVal
Switch StringLower($METHOD)
Case 'productid'
Dim $sModel
If $ProductIdOffset <= 0 Then Return SetError(-1, 0, 'Unknown ProductId')
Local $i = $ProductIdOffset - $tDescrSize + 4
While True
Local $GetByte = DllStructGetData($tBuffer, "Buffer", $i)
If $GetByte <> Chr(0) Then
$sModel &= $GetByte
Else
ExitLoop
EndIf
$i += 1
WEnd
$ReturnVal = StringStripWS(_CodeBytes($sModel), 3)
Case 'serialnumber'
If $SerialNumberOffset <= 0 Then Return SetError(-1, 0, 'Unknown SerialNumber')
Dim $sSerialNum
Local $i = $SerialNumberOffset - $tDescrSize + 4
While True
Local $GetByte = DllStructGetData($tBuffer, "Buffer", $i)
If $GetByte <> Chr(0) Then
$sSerialNum &= $GetByte
Else
ExitLoop
EndIf
$i += 1
WEnd
$ReturnVal = StringStripWS(_CodeBytes($sSerialNum), 8)
Case 'productrevision'
If $ProductRevisionOffset <= 0 Then Return SetError(-1, 0, 'Unknown ProductRevision')
Dim $sProductRevision
Local $i = $ProductRevisionOffset - $tDescrSize + 4
While True
Local $GetByte = DllStructGetData($tBuffer, "Buffer", $i)
If $GetByte <> Chr(0) Then
$sProductRevision &= $GetByte
Else
ExitLoop
EndIf
$i += 1
WEnd
$ReturnVal = StringStripWS(_CodeBytes($sProductRevision), 3)
Case 'bustype'
Switch Hex($BusType, 2)
Case '00'
$ReturnVal = 'Unknown'
Case '01'
$ReturnVal = 'Scsi'
Case '02'
$ReturnVal = 'Atapi'
Case '03'
$ReturnVal = 'Ata'
Case '04'
$ReturnVal = '1394'
Case '05'
$ReturnVal = 'Ssa'
Case '06'
$ReturnVal = 'Fibre'
Case '07'
$ReturnVal = 'Usb'
Case '08'
$ReturnVal = 'RAID'
Case '09'
$ReturnVal = 'iScsi'
Case '0A'
$ReturnVal = 'Sas'
Case '0B'
$ReturnVal = 'Sata'
Case '0C'
$ReturnVal = 'Sd'
Case '0D'
$ReturnVal = 'Mmc'
Case '0E'
$ReturnVal = 'Virtual'
Case '0F'
$ReturnVal = 'FileBackedVirtual'
Case '10'
$ReturnVal = 'Max'
Case '7F'
$ReturnVal = 'MaxReserved'
EndSwitch
Case Else
$tQuery = 0
$tDescr = 0
$tBuffer = 0
Return SetError(-1, 0, 'Unknown Method')
EndSwitch
$tQuery = 0
$tDescr = 0
$tBuffer = 0
Return SetError(0, 0, $ReturnVal)
EndFunc ;==>_ReadPhysicalDriveInNTWithZeroRights
Func _CodeBytes($str)
Local $ReturnVal
If StringRegExp($str, '[^0-9A-Fa-f]') Then Return $str
Local $aStr = StringSplit($str, '', 2)
If Mod(UBound($aStr), 2) <> 0 Then Return $str
If StringRegExp($str, '^(00[0-9A-Fa-f]{2})+$') Then ;utf16 大编码
$ReturnVal = BinaryToString('0x' & $str, 3)
If StringRegExp($ReturnVal, '^([\x20-\x7e])+$') Then
Return $ReturnVal
Else
Return $str
EndIf
ElseIf StringRegExp($str, '^([0-9A-Fa-f]{2}00)+$') Then ;utf16 小编码
$ReturnVal = BinaryToString('0x' & $str, 2)
If StringRegExp($ReturnVal, '^([\x20-\x7e])+$') Then
Return $ReturnVal
Else
Return $str
EndIf
ElseIf StringRegExp($str, '^([2-6][0-9A-Fa-f]|7[0-9A-Ea-e])+$') Then ;utf8 编码 \x20-\x7e
If Mod(UBound($aStr), 4) = 0 Then
Local $NewStr
For $i = 0 To UBound($aStr) - 1 Step 4
$NewStr &= $aStr[$i + 2]
$NewStr &= $aStr[$i + 3]
$NewStr &= $aStr[$i + 0]
$NewStr &= $aStr[$i + 1]
Next
$ReturnVal = BinaryToString('0x' & $NewStr, 4)
Else
$ReturnVal = BinaryToString('0x' & $str, 4)
EndIf
If StringRegExp($ReturnVal, '^([\x20-\x7e])+$') Then
Return $ReturnVal
Else
Return $str
EndIf
Else
Return $str
EndIf
EndFunc ;==>_CodeBytes