找回密码
 加入
搜索
查看: 8414|回复: 22

[原创] 利用snapshot --show参数提取磁盘及分区信息!

 火.. [复制链接]
发表于 2016-12-2 09:19:54 | 显示全部楼层 |阅读模式
本帖最后由 bfgxp 于 2016-12-2 11:47 编辑



snapshot.exe下载
#include <Array.au3>
#include <WinAPIFiles.au3>
_Part_info()
Func _Part_info()
        $foo = Run("snapshot.exe --show", "", @SW_HIDE, $STDOUT_CHILD)
        ProcessWaitClose($foo)
        $text = StdoutRead($foo) & @CRLF & @CRLF & "ABC:)"
        ;$Disks = StringRegExp($text, "\b.+Vendor.+", 3)
        $DisksAndParts = StringRegExp($text, "(?s)HD\d+\h+\(FIXED.+?\n\r", 3)
        For $i = 0 To UBound($DisksAndParts) - 1
                $Disk = StringRegExp($DisksAndParts[$i], "\b.+Vendor.+", 3)
                $parts = StringRegExp($DisksAndParts[$i], "\b.+\(S=.+", 3)
                Dim $PartINfoS[UBound($parts)][7]
                For $j = 0 To UBound($parts) - 1
                        $PartInfo = StringSplit(StringStripWS($parts[$j], 4), " ")
                        $PartINfoS[$j][0] = _DriveNum($PartInfo[1])
                        If Not StringRegExp($PartInfo[1], "\:\d") Then $PartINfoS[$j][1] = $PartInfo[1]
                        $PartINfoS[$j][2] = $PartInfo[2]
                        $PartINfoS[$j][3] = StringReplace($PartInfo[3], "(S=", "")
                        $PartINfoS[$j][4] = _PartSize($PartInfo[4])
                        $PartINfoS[$j][5] = Int(DriveSpaceFree($PartInfo[1] & "") / 1024) & " GB"
                        If $PartInfo[0] = 7 Then $PartINfoS[$j][6] = $PartInfo[7]
                Next
                _ArraySort($PartINfoS)
                _ArrayDisplay($PartINfoS, StringStripWS($Disk[0], 4))
        Next
EndFunc   ;==>_Part_info
Func _PartSize($PartInfo4)
        $PartSize = Int(StringRegExpReplace($PartInfo4, "\D", "") / 1024)
        If StringRegExp($PartInfo4, "\dB") Then $PartSize = $PartSize & " KB"
        If StringRegExp($PartInfo4, "\dKB") Then $PartSize = $PartSize & " MB"
        If StringRegExp($PartInfo4, "\dMB") Then $PartSize = $PartSize & " GB"
        Return $PartSize
EndFunc   ;==>_PartSize
Func _DriveNum($PartInfo1)
        If StringRegExp($PartInfo1, "\:\d") Then
                $DriveNum = StringReplace($PartInfo1, "HD", "")
        Else
                $aData = _WinAPI_GetDriveNumber($PartInfo1)
                $DriveNum = Ceiling($aData[1] + 1) & ":" & $aData[2]
        EndIf
        Return $DriveNum
EndFunc   ;==>_DriveNum

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2016-12-2 10:09:31 | 显示全部楼层
回复 1# bfgxp
运行后没显示???
发表于 2016-12-2 10:15:13 | 显示全部楼层
回复 2# chzj589

"F:\论坛案例\路由器自动导入配置文件\提取磁盘及分区信息.au3"(6,70) : error: $STDOUT_CHILD: undeclared global variable.
        $foo = Run("snapshot.exe --show", "", @SW_HIDE, $STDOUT_CHILD)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
 楼主| 发表于 2016-12-2 11:45:05 | 显示全部楼层
你得自己下载snapshot.exe
http://www.drivesnapshot.de/download/snapshot.exe
发表于 2016-12-2 16:53:56 | 显示全部楼层
回复 4# bfgxp
谢谢分享!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
 楼主| 发表于 2016-12-3 13:48:13 | 显示全部楼层
回复 5# chzj589
不谢,你是怎么判断分区中安装的系统的?
发表于 2016-12-3 16:26:46 | 显示全部楼层
回复  chzj589
不谢,你是怎么判断分区中安装的系统的?
bfgxp 发表于 2016-12-3 13:48


自己就显示啊

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2016-12-4 13:55:26 | 显示全部楼层
我也收藏了一份这样功能的脚本,希望对你有帮助!
#include <include\SetupAPI.au3>
#include <array.au3>

For $number = 0 To RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum","count")-1
        Global $Device_0 = "\\.\PhysicalDrive" & $number
        Global $Log_Partition_Array[1][5]
        Global $Master_Partition_Table
        Global $output
        _Get_Partition()
Next

Func _Get_Partition()
        $y = StringRight($Device_0, 1)
        $san = _Device_Read($Device_0, 0, 1)
        $Master_Partition_Table = _GetPartitionTable($san)
        $Partition_Array = Get_Ext_Patition()
        $z = 1
        ReDim $Partition_Array[UBound($Partition_Array)][6]
        For $r = 0 To UBound($Partition_Array) - 1
                If StringInStr($Partition_Array[$r][0],"Pri") Then
                        $Partition_Array[$r][5] = $y + 1 & ":" & $z
                        $z += 1
                EndIf
        Next
        For $i = 0 To UBound($Partition_Array) - 1
                If $Partition_Array[$i][0] = "Ext" Then
                        _Get_Log_partition('0x' & $Partition_Array[$i][3])
                EndIf
        Next

        For $k = 0 To UBound($Partition_Array) - 1
                $Partition_Array[$k][3] = Execute("0x" & $Partition_Array[$k][3])
        Next
        _ArrayDelete($Log_Partition_Array, UBound($Log_Partition_Array) - 1)
        Dim $Number_A = UBound($Partition_Array), $Number_B = UBound($Log_Partition_Array)
        ReDim $Partition_Array[$Number_A + $Number_B][6]
        $k = 0
        For $i = $Number_A To $Number_A + $Number_B - 1
                For $n = 0 To 4
                        $Partition_Array[$i][$n] = $Log_Partition_Array[$k][$n]
                Next
                $k += 1
                $Partition_Array[$i][5] = $y + 1 & ":" & $k + 1 + ($r - 2)
        Next
        _ArrayDisplay($Partition_Array,$Device_0)
EndFunc

Func Get_Ext_Patition()
        Local $Partition[1][5]
        For $i = 0 To 15 Step 4
                $n = UBound($Partition)
                Dim $str = ''
                For $k = $i To $i + 3
                        $str &= $Master_Partition_Table[$k]
                Next
                If $str == '00000000000000000000' Then
                        ExitLoop
                Else
                        ReDim $Partition[$n + 1][5]
                        $Partition[$n - 1][1] = $Master_Partition_Table[$i]
                        $Partition[$n - 1][2] = $Master_Partition_Table[$i + 1]
                        $Partition[$n - 1][3] = $Master_Partition_Table[$i + 2]
                        $Partition[$n - 1][4] = $Master_Partition_Table[$i + 3]
                EndIf
        Next
        For $a = 0 To UBound($Partition) - 2
                $Size = Round(("0x" & $Partition[$a][4])*512/1024/1024,2)
                If $Partition[$a][1] = "80" Then
                        $Partition[$a][0] = "Pri"
                        $Partition[$a][1] = "A"
                        If StringLeft($Partition[$a][2],1) = 1 Then $Partition[$a][1] = "AH"
                        $Partition[$a][4] = $Size
                ElseIf $Partition[$a][2] == '0F' Then
                        $Partition[$a][0] = "Ext"
                        $Partition[$a][1] = ""
                        If StringLeft($Partition[$a][2],1) = 1 Then $Partition[$a][1] = "H"
                        $Partition[$a][4] = $Size
                Else
                        If $Partition[$a][1] = "80" Then
                                $var = "A"
                                If StringLeft($Partition[$a][2],1) = 1 Then $var="AH"
                        Else
                                $var = ""
                                If StringLeft($Partition[$a][2],1) = 1 Then $var="H"
                        EndIf
                        $Partition[$a][0] = "Pri"
                        $Partition[$a][1] = $var
                        $Partition[$a][4] = $Size
                EndIf
        Next
        ReDim $Partition[UBound($Partition) - 1][5]
        Return $Partition
EndFunc   ;==>Get_Ext_Patition


Func _Get_Log_partition($Sector)
        $Log = _Device_Read($Device_0, $Sector, 1)
        $Master_Partition_Table = _GetPartitionTable($Log)

        Local $Log_Partition[1][5]
        For $i = 0 To 15 Step 4
                $n = UBound($Log_Partition)
                Dim $str = ''
                For $k = $i To $i + 3
                        $str &= $Master_Partition_Table[$k]
                Next
                If $str == '00000000000000000000' Then
                        ExitLoop
                Else
                        ReDim $Log_Partition[$n + 1][5]
                        $Log_Partition[$n - 1][0] = "Log"
                        $Log_Partition[$n - 1][1] = $Master_Partition_Table[$i]
                        $Log_Partition[$n - 1][2] = $Master_Partition_Table[$i + 1]
                        $Log_Partition[$n - 1][3] = $Master_Partition_Table[$i + 2]
                        $Log_Partition[$n - 1][4] = $Master_Partition_Table[$i + 3]
                EndIf
        Next

        $Sector_Start = $Sector + Execute('0x' & $Log_Partition[0][3])
        If $Log_Partition[0][1] = '00' Then $Log_Partition[0][1] = ' '
        If StringLeft($Log_Partition[0][2],1) = 1 Then $Log_Partition[0][1]='H'
        $Size = Round(("0x" & $Log_Partition[0][4])*512/1024/1024,2)
        $A_number = UBound($Log_Partition_Array)
        ReDim $Log_Partition_Array[$A_number + 1][5]
        $Log_Partition_Array[$A_number - 1][0] = $Log_Partition[0][0]
        $Log_Partition_Array[$A_number - 1][1] = $Log_Partition[0][1]
        $Log_Partition_Array[$A_number - 1][2] = $Log_Partition[0][2]
        $Log_Partition_Array[$A_number - 1][3] = $Sector_Start
        $Log_Partition_Array[$A_number - 1][4] = $Size

        $Sector1 = Execute('0x' & $Log_Partition[0][3]) + $Sector + Execute('0x' & $Log_Partition[0][4])
        If UBound($Log_Partition) > 2 Then
                _Get_Log_partition($Sector1)
        Else
                Return $Log_Partition_Array
        EndIf
EndFunc   ;==>_Get_Log_partition

Func _Device_Read($DeviceID, $Offset, $Length = 1)
        Local $Pos, $Size, $Result
        If StringInStr($Offset, "0x") Then
                If Not IsBinary($Offset) Then $Pos = Execute(Binary($Offset)) * 512
        Else
                $Pos = $Offset * 512
        EndIf
;MsgBox("","$Pos",$Pos)
        $Size = $Length * 512
;MsgBox("","$Size",$Size)
        $hFile = _CM_Create_File($DeviceID, 0xC0000000, 3, 0, 3, 0)
;MsgBox("","$hFile",$hFile)
        _NtSetInformationFile($hFile, 14, $Pos, 8, "int64*")
        $pBuffer = _CM_Heap_Alloc($Size)
        _CM_Read_Device($hFile, $pBuffer, $Size)
        _CM_Close_Handle($hFile)
        $tBuffer = DllStructCreate("byte Binary[" & $Size & "]", $pBuffer)
        $Result = DllStructGetData($tBuffer, "Binary")
        Return $Result
EndFunc   ;==>_Device_Read

Func _NtSetInformationFile($hFile, $iInfoClass, $vBuffer, $iBuffer, $sBufferType = "ptr")
        Local $iResult, $tStatus, $pStatus
        $tStatus = DllStructCreate("ubyte Status[32]")
        $pStatus = DllStructGetPtr($tStatus)
        $iResult = DllCall("Ntdll.dll", "dword", "NtSetInformationFile", "handle", $hFile, "ptr", $pStatus, $sBufferType, $vBuffer, "ulong", $iBuffer, "dword", $iInfoClass)
        Return SetError($iResult[0], 0, $iResult[0] = 0)
EndFunc   ;==>_NtSetInformationFile

Func _GetPartitionTable($SectorData)
        Const $PriPT_FirstAction = 0x01BE + 1; 1 Byte
        Local $aPartTable
        $PriPT_data = BinaryMid($SectorData, $PriPT_FirstAction, 0x40)
        $aPartTable = StringRegExp(StringTrimLeft($PriPT_data, 2), '(\S{2})\S{6}(\S{2})\S{6}(\S{8})(\S{8})', 3)
        $arraynum = UBound($aPartTable) - 1
        For $i = 0 To $arraynum
                $aPartTable[$i] = _SwapHexData($aPartTable[$i])
        Next
        Return $aPartTable
EndFunc   ;==>_GetPartitionTable

Func _SwapHexData($data)
        Local $Result
        $sLen = StringLen($data)
        For $i = 1 To $sLen Step 2
                $Result = StringMid($data, $i, 2) & $Result
        Next
        Return $Result
EndFunc   ;==>_SwapHexData
发表于 2016-12-4 16:10:45 | 显示全部楼层
回复 8# chishingchan

#include <include\SetupAPI.au3>???
发表于 2016-12-4 16:17:03 | 显示全部楼层
回复 9# chzj589

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2016-12-4 16:32:09 | 显示全部楼层
回复 10# chishingchan
下载了,SetupAPI.au3里缺
LocalSecurityAuthority.au3 ???
发表于 2016-12-4 16:46:17 | 显示全部楼层
我也收藏了一份这样功能的脚本,希望对你有帮助!
chishingchan 发表于 2016-12-4 13:55




没盘符??

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2016-12-6 08:17:28 | 显示全部楼层
學習了!!這是個ˇ不錯的方式!!
 楼主| 发表于 2016-12-6 19:28:37 | 显示全部楼层
回复 7# chzj589


    这个显示的是卷标,可不是安装的系统。
 楼主| 发表于 2016-12-6 19:31:30 | 显示全部楼层
回复 8# chishingchan


    曾经尝试使用这段代码的,纯au3实现,只是SetupAPI.au3有多个版本吧,LocalSecurityAuthority.au3似乎还改过名,忘记了。
所以干脆用第三方程序,snapshot小巧实用,用正则提取,代码也要简单得多。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-4-25 04:25 , Processed in 0.082145 second(s), 21 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表