Jump to content

Disk imaging attempt


Recommended Posts

I just wanted to create a sample disk imager that will make a sector by sector copy of a physical disk to a file. The code works, but I'm wondering if there's anything obvious in the loop that affects the speed of the imaging, and can be improved? Is there for instance a rule of thumb for what to configure $block to be? Here it is;

#include <winapi.au3>
#Include <WinAPIEx.au3>
#Include <APIConstants.au3>
Global  $nBytes, $tBuffer, $hFile, $hFile0
Global $sDrivePath = '\\.\PhysicalDrive', $sDriveNumber = '2'
$begin = TimerInit()
$block = 8388608 
Global $hFile0 = _WinAPI_CreateFile("\\.\" & $sDrivePath & $sDriveNumber,2,2,2)
If $hFile0 = 0 then exit
$DiskInfo = _WinAPI_GetDriveGeometryEx($sDriveNumber)
$DiskSize = DllStructGetData($DiskInfo, "DiskSize")
$remainder = 0
$sizediff = $DiskSize/$block
$maxblocks = Ceiling($sizediff)
$maxblocks_low = Floor($sizediff)
$sizediff2 = $sizediff-$maxblocks_low
$remainder = $sizediff2 * $block
If @error Then
    ConsoleWrite("@error = " & @error & @crlf)
    ConsoleWrite("@extended = " & @extended & @crlf)
EndIf
ProgressOn("AutoIt disk imaging in progress", "Opening target", "", -1, -1, 16)
$outputimage = "\\.\c:\temp\image.dd"
Global $hFile = _WinAPI_CreateFile($outputimage, 3, 6, 7)
If $hFile = 0 then
    ConsoleWrite("Error occured when creating file." & @crlf)
    _WinAPI_CloseHandle($hFile0)
    _WinAPI_CloseHandle($hFile)
    Exit
EndIf
_WinAPI_SetFilePointerEx($hFile, $DiskSize)
_WinAPI_SetEndOfFile($hFile)
_WinAPI_FlushFileBuffers($hFile)
_WinAPI_SetFilePointerEx($hFile, 0)
For $i = 0 To $maxblocks
    If $i = $maxblocks Then
        $block = $remainder
    EndIf
    $tBuffer=DllStructCreate("byte[" & $block & "]")
    $read = _WinAPI_ReadFile($hFile0, DllStructGetPtr($tBuffer), $block, $nBytes)
    If $read = 0 then
        ConsoleWrite("Error when reading at block: " & $i & @crlf)
        _WinAPI_CloseHandle($hFile0)
        Exit
    EndIf
    _WinAPI_WriteFile($hFile, DllStructGetPtr($tBuffer), $block, $nBytes)
    If @error Then ConsoleWrite("Error occured when writing to file." & @crlf)
    ProgressSet(Round((($i/$maxblocks)*100), 1),Round(($i/$maxblocks)*100, 1) & "  % finished imaging", "")
    If $i = $maxblocks Then
        _WinAPI_FlushFileBuffers($hFile)
        ExitLoop
    EndIf
    _WinAPI_SetFilePointerEx($hFile, $i*$block)
    _WinAPI_SetFilePointerEx($hFile0, $i*$block)
Next
ProgressOff()
_WinAPI_CloseHandle($hFile)
_WinAPI_CloseHandle($hFile0)
$diff = TimerDiff($begin)
$diff = Round(($diff/1000),2)
$BytesPerSec = Round(($DiskSize/$diff),0)
$DiskSizeKB = $DiskSize/1024
$KBPerSec = Round(($DiskSizeKB/$diff),0)
$DiskSizeMB = $DiskSize/1024/1024
$MBPerSec = Round(($DiskSizeMB/$diff),1)
$MBPerMin = $MBPerSec * 60
MsgBox(0,"Finished imaging","Job took: " & $diff & " seconds" & @crlf _
& "Performed " & $MBPerMin & " MB per minute")
Exit
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...