Sign in to follow this  
Followers 0
joakim

Disk imaging attempt

2 posts in this topic

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

Share this post


Link to post
Share on other sites



Anybody want to have a quick look at the loop and see if anything can be changed to speed it up?

Share this post


Link to post
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
Sign in to follow this  
Followers 0