joakim Posted July 27, 2011 Share Posted July 27, 2011 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; expandcollapse popup#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 More sharing options...
joakim Posted July 29, 2011 Author Share Posted July 29, 2011 Anybody want to have a quick look at the loop and see if anything can be changed to speed it up? Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now