#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