Browse Source

fix issue when copying last block

Tobias Simetsreiter 4 years ago
parent
commit
a005cfaa90
1 changed files with 74 additions and 23 deletions
  1. 74 23
      WinImager.ps1

+ 74 - 23
WinImager.ps1

@@ -23,39 +23,58 @@ Function Main()
         $disk = Get-PhysDev
         $disknum = $disk.Number
         $diskname = $disk.FriendlyName
+        $diskserial = $disk.SerialNumber
 
-        if ((-not $disknum -is [int]) -or $disknum -eq $null){
+        if ((-not $disknum -is [int]) -or $disknum -eq $null -or $disknum -lt 0){
             Write-Output "No Disk Selected"
         } else {
 
             $dialog = @"
-Going to Write "${filename}" to Drive "${diskname}" 
+Going to write Image:
+
+"${filename}"
+
+to Drive:
+
+"${diskname} ${diskserial}" 
+
 Would you like to contine?
 "@ 
-            $continue = [System.windows.forms.messagebox]::show($dialog, 'Continue','YesNoCancel','Warn')
+            $continue = Ask-Continue $dialog
 
 
             if ($continue -eq "Yes"){
 
                 Reset-Disk $disknum
-                sleep 5
-                WinDD $filename ("\\.\PHYSICALDRIVE{0,1}" -f $disknum)
+                WinDD $filename ("\\.\PHYSICALDRIVE{0}" -f $disknum)
+                Fix-CHS $disknum
 
             }
         }
+
         $dialog = @"
-Write same image to another Drive?
+Write image 
+
+"${filename}"
+
+to another Drive?
 "@
-        $continue = [System.windows.forms.messagebox]::show($dialog, 'Continue','YesNoCancel','Info')
+        $continue = Ask-Continue $dialog
 
     }
 
 }
 
+Function Ask-Continue($text)
+{
+    [System.Windows.Forms.MessageBox]::Show($text, 'Continue','YesNo','Info')
+}
+
 Function Reset-Disk($disknum)
 {
+    $ErrorActionPreference = "Stop"
     
-    if ((-not $disknum -is [int]) -or $disknum -eq $null){
+    if ((-not $disknum -is [int]) -or $disknum -eq $null -or $disknum -lt 0){
         Break
     }
     @"
@@ -63,7 +82,24 @@ list disk
 select disk $disknum
 list partition
 clean
-"@ | diskpart
+"@  | diskpart
+
+    Write-Output "Sleeping 10s to make sure drive is available..."
+    sleep 10
+}
+
+Function Fix-CHS($disknum){
+    $ErrorActionPreference = "Stop"
+    
+    if ((-not $disknum -is [int]) -or $disknum -eq $null -or $disknum -lt 0){
+        Break
+    }
+    @"
+y
+c
+w
+y
+"@  | .\fixparts-windows-1.0.6\fixparts64 ("\\.\PHYSICALDRIVE{0}" -f $disknum)
 
 }
 
@@ -72,7 +108,7 @@ Function Get-FileName($initialDirectory = "C:\", $title = "Select File")
 
     $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
     $OpenFileDialog.initialDirectory = $initialDirectory
-    $OpenFileDialog.filter = "All files (*.*)| *.*"
+    $OpenFileDialog.filter = "Images (*.img;*.afp;*.usb;*.iso)| *.img;*.afp;*.usb;*.iso|All files (*.*)| *.*"
     $OpenFileDialog.Title = $title
     $OpenFileDialog.ShowDialog() | Out-Null
     $OpenFileDialog.filename
@@ -81,9 +117,13 @@ Function Get-FileName($initialDirectory = "C:\", $title = "Select File")
 Function Get-PhysDev()
 {  
     $cdisk = Get-Volume -DriveLetter C|Get-Partition|Get-Disk
-    $disks = Get-Disk
-    $disks_noc = $disks |Where {$_.Number -ne $cdisk.Number}
+    $disks = Get-Disk |
+        Where {$_.Number -ne $cdisk.Number} |
+        Where {$_.OperationalStatus -ne "No Media"}
+    SelectDiskDialog $disks
+}
 
+Function SelectDiskDialog($disks){
     $form = New-Object System.Windows.Forms.Form
     $form.Text = 'Select a Disk to Write to'
     $form.Size = New-Object System.Drawing.Size(500,275)
@@ -108,7 +148,7 @@ Function Get-PhysDev()
     $label = New-Object System.Windows.Forms.Label
     $label.Location = New-Object System.Drawing.Point(10,20)
     $label.Size = New-Object System.Drawing.Size(480,20)
-    $label.Text = 'Please select a Dísk:'
+    $label.Text = 'Please select a Disk:'
     $form.Controls.Add($label)
 
     $listBox = New-Object System.Windows.Forms.ListBox
@@ -119,7 +159,7 @@ Function Get-PhysDev()
     $listBox.Height = 150
 
     $i = 0
-    foreach ($d in $disks_noc){
+    foreach ($d in $disks){
         if ($d.Size){
             $size = [math]::Round($d.Size/1Gb, 1)
         } else {
@@ -127,7 +167,8 @@ Function Get-PhysDev()
         }
         $number = $d.Number.toString()
         $name = $d.FriendlyName
-        $label = "{0,3}   {1,-35}    {2,8} GB" -f $number,$name,$size
+        $serial = $d.SerialNumber
+        $label = "{0,-3} {1,-25} {2,-20} {3,8} GB" -f $number,$name,$serial,$size
         [void] $listBox.Items.Add($label)
     }
 
@@ -140,29 +181,39 @@ Function Get-PhysDev()
     if ($result -eq [System.Windows.Forms.DialogResult]::OK)
     {
         $x = $listBox.SelectedIndex
-        $disks_noc[$x]
+        $disks[$x]
     }
 } #end function Get-PhysDev
 
 Function WinDD($inFileName, $outFileName, $blocksize = 5Mb) {
 
-    Write-Output "Copy $inFileName to $outFileName with blocksize: $blocksize ...."
+    Write-Output ""
+    Write-Output "" "Copy $inFileName to $outFileName with blocksize: $blocksize ...."
     $block = [System.Byte[]]::CreateInstance([System.Byte], $blocksize)
 
     try{
         $inFile = [System.IO.File]::Open($inFileName, [System.IO.FileMode]::Open)
         $outFile = [System.IO.File]::Open($outFileName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Write)
-        $outFile.Seek(0,0)
-        $inFile.Seek(0,0)
+        $outFile.Seek(0,0) | Out-Null
+        $inFile.Seek(0,0)  | Out-Null
 
         $max =      [math]::Round($inFile.Length/1Mb)
         while ($outFile.Position -lt $inFile.Length){
-            $percent = [math]::Round(100 * $outFile.Position / $inFile.Length, 1)
+
+            $remains = ($inFile.Length - $outFile.Position)
+
+            if($remains -lt $blocksize){
+                $blocksize = $remains
+                $block = [System.Byte[]]::CreateInstance([System.Byte], $blocksize)
+            }
+
+            $inFile.Read( $block, 0, $blocksize)    | Out-Null
+            $outFile.Write( $block , 0, $blocksize) | Out-Null
+
+            $percent = [math]::Min(100,[math]::Round(100 * $outFile.Position / $inFile.Length, 1))
             $done    = [math]::Round($outFile.Position/1Mb)
-            $status  = "{0,5}% {1,6}/{2,-6} Mb" -f ($percent,$done,$max)
+            $status  = "{0,5}% {1,6}/{2} Mb" -f ($percent,$done,$max)
             Write-Progress -Id 1 -Activity "Writing in Progress" -Status $status -PercentComplete $percent;
-            $ipos = $inFile.Read( $block, 0, $blocksize)
-            $opos = $outFile.Write( $block , 0, $blocksize)
         }
         Write-Output "Flushing...."
         $outFile.Flush()