joakim Posted July 27, 2011 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
joakim Posted July 29, 2011 Author 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?
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