]> localhost Git - scsi2sd-util.git/commitdiff
Added code to flash a disk image
authorMichael McMaster <michael@codesrc.com>
Sat, 30 Jan 2021 10:25:11 +0000 (20:25 +1000)
committerMichael McMaster <michael@codesrc.com>
Sat, 30 Jan 2021 10:25:11 +0000 (20:25 +1000)
scsi2sd.io/scsi2sd.io.iml
scsi2sd.io/src/main/java/com/codesrc/scsi2sd/io/UsbDevice.java
scsi2sd.io/src/main/java/com/codesrc/scsi2sd/io/V3FirmwareUsbDevice.java
scsi2sd.io/src/main/java/com/codesrc/scsi2sd/io/V6FirmwareUsbDevice.java
scsi2sd.ui/src/main/java/com/codesrc/scsi2sd/presentation/MainController.java
scsi2sd.ui/src/main/resources/fx/main.fxml

index d415012fa202b0ec06e9131a702527a2e52fcc14..3e40fe60b1343c5c3aa591f24253587e075d4263 100644 (file)
@@ -6,7 +6,6 @@
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
       <excludeFolder url="file://$MODULE_DIR$/target" />
     </content>
     <orderEntry type="inheritedJdk" />
index 34d2118f5ebf518fe44578f4ed9d24e0a1195270..662b75622dde2f0285e63026a59df5295606666a 100644 (file)
@@ -17,6 +17,9 @@
 
 package com.codesrc.scsi2sd.io;
 
+import java.io.File;
+import java.io.IOException;
+
 /**
  * Created by michael on 27/08/18.
  */
@@ -36,6 +39,8 @@ public interface UsbDevice {
     void saveDiskConfig(int index, byte[] data);
     void saveCommit();
 
+    void writeImage(File file, int sectorStart) throws IOException;
+
     boolean supportsTerminator();
     boolean supportsSynchronous();
 }
index 2910b5fc48d56671c807a8dbc761f00fc40641ff..8b1b269bd3325d671515e8430966e33e68be8de3 100644 (file)
@@ -21,6 +21,7 @@ import org.hid4java.HidDevice;
 import org.hid4java.HidServices;
 import org.slf4j.LoggerFactory;
 
+import java.io.*;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
@@ -193,11 +194,7 @@ public class V3FirmwareUsbDevice implements UsbDevice {
             System.out.print("Found storage device with capacity: ");
             System.out.println(capacity * 512L);
         }
-
-       // System.out.println("Erasing 1 sectors");
-       // byte[] eraseCmd = {(byte)Commands.DEV_ERASE.ordinal(), (byte)1, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1};
-       // response = protocolDevice.sendHIDPacket(eraseCmd, 1);
-
+        /*
         System.out.println("Writing a sector");
         byte[] writeCmd = new byte[519];
         writeCmd[0] = (byte)Commands.DEV_WRITE.ordinal();
@@ -219,6 +216,8 @@ public class V3FirmwareUsbDevice implements UsbDevice {
         }
 
         System.out.println("FLASH test complete");
+        */
+
     }
 
 
@@ -281,6 +280,57 @@ public class V3FirmwareUsbDevice implements UsbDevice {
         }
     }
 
+    @Override
+    public void writeImage(File file, int sectorStart) throws IOException
+    {
+        // Only supported on the flash device
+        // Erase the flash device
+
+        var sectors = ((int) file.length() + 511) / 512;
+        byte[] eraseCmd = {
+                (byte)Commands.DEV_ERASE.ordinal(),
+                (byte)1, // Hardcoded flash device for now
+                (byte)0,
+                (byte)0,
+                (byte)0,
+                (byte)0,
+                HidPacketProtocol.intToUint8(sectors >> 24),
+                HidPacketProtocol.intToUint8(sectors >> 16),
+                HidPacketProtocol.intToUint8(sectors >> 8),
+                HidPacketProtocol.intToUint8(sectors)};
+
+        System.out.println("Erasing flash");
+
+        protocolDevice.sendHIDPacket(eraseCmd, 1);
+
+        System.out.println("Writing flash");
+
+        var is = new BufferedInputStream(new FileInputStream(file));
+
+        for (int sector = 0; sector < sectors; ++sector) {
+            if (sector % 100 == 0)
+            {
+                var percentComplete = 100.0 * sector / sectors;
+                System.out.print(percentComplete);
+                System.out.println("% complete");
+            }
+            byte[] writeCmd = new byte[519];
+            writeCmd[0] = (byte) Commands.DEV_WRITE.ordinal();
+            writeCmd[1] = 1; // flash
+            writeCmd[2] = HidPacketProtocol.intToUint8(sector >> 24); // Sector number
+            writeCmd[3] = HidPacketProtocol.intToUint8(sector >> 16); // Sector number
+            writeCmd[4] = HidPacketProtocol.intToUint8(sector >> 8); // Sector number
+            writeCmd[5] = HidPacketProtocol.intToUint8(sector); // Sector number
+
+            var buf = new byte[512];
+            is.readNBytes(writeCmd, 6, 512);
+
+            protocolDevice.sendHIDPacket(writeCmd, 1);
+        }
+
+        System.out.println("Write complete");
+    }
+
     private byte[] readFlash(int flashArray, int flashRow)
     {
         byte[] cmd = {
index 657cf0834891a33153dc95a51041c8c868f5c4d0..33e474fe3c61f268dd33f51776aea1d1d8ef0bb2 100644 (file)
@@ -20,6 +20,8 @@ package com.codesrc.scsi2sd.io;
 import org.hid4java.HidDevice;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -166,6 +168,12 @@ public class V6FirmwareUsbDevice implements UsbDevice {
         }
     }
 
+    @Override
+    public void writeImage(File file, int sectorStart) throws IOException
+    {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
     @Override
     public byte[] readDiskConfig(int index)
     {
index a83bf966f089986ba12c98fea5798bc6838dfe25..efb1505f1f026c5d82564be680d5e5b90a9cf0e1 100644 (file)
@@ -79,6 +79,8 @@ public class MainController implements FXController, DocumentObserver {
     @FXML private MenuItem menuRevert;
     @FXML private Button buttonRevert;
 
+    @FXML private MenuItem menuWriteImage;
+
     @FXML private TabPane mainTabPane;
 
     @FXML private AnchorPane debugLog;
@@ -121,9 +123,11 @@ public class MainController implements FXController, DocumentObserver {
         toolbarSaveFile.setOnAction(h -> saveConfigToFile());
         menuRevert.setOnAction(h -> revert());
         buttonRevert.setOnAction(h -> revert());
+        menuWriteImage.setOnAction(h -> writeImageToDevice());
 
         menuOpenDevice.setDisable(true);
         menuSaveDevice.setDisable(true);
+        menuWriteImage.setDisable(true);
 
         this.prefs = Preferences.userNodeForPackage(MainController.class);
         this.populateRecentFromPrefs();
@@ -157,6 +161,7 @@ public class MainController implements FXController, DocumentObserver {
     {
         this.menuOpenDevice.setDisable(true);
         this.menuSaveDevice.setDisable(true);
+        this.menuWriteImage.setDisable(true);
     }
 
     private void handleDeviceConnectedEvent(UsbDevice device)
@@ -164,6 +169,7 @@ public class MainController implements FXController, DocumentObserver {
         this.menuOpenDevice.setDisable(false);
         this.loadConfigFromDevice(device);
         this.menuSaveDevice.setDisable(false);
+        this.menuWriteImage.setDisable(false);
     }
 
     private void loadConfigFromDevice(UsbDevice device) {
@@ -452,4 +458,26 @@ public class MainController implements FXController, DocumentObserver {
             this.menuRecent.getItems().add(menuItem);
         }
     }
+
+    private void writeImageToDevice()
+    {
+        FileChooser fileChooser = new FileChooser();
+        fileChooser.setTitle("Open disk image");
+
+        File theFile = fileChooser.showOpenDialog(this.window);
+        if (theFile == null)
+        {
+            return; // User cancelled.
+        }
+
+        try {
+            this.getDevice().writeImage(theFile, 0);
+
+        } catch (Exception e) {
+            Alert alert = new Alert(Alert.AlertType.ERROR);
+            alert.setTitle("Imaging failed");
+            alert.setContentText(e.getLocalizedMessage());
+            alert.show();
+        }
+    }
 }
index 1d5f878534bfb2f36d3be9a36d044b490523e2bf..cc3aac44b18bd6a610c1ea6346e601e31bd928b5 100644 (file)
                 <Button fx:id="buttonRevert" mnemonicParsing="false" text="Revert" />
                 <Separator></Separator>
                 <Button>Update Firmware...</Button>
+                <Separator></Separator>
+                <MenuButton mnemonicParsing="false" text="Disk Image">
+                    <items>
+                        <MenuItem fx:id="menuWriteImage" mnemonicParsing="false" text="Write image" />
+                    </items>
+                </MenuButton>
             </items>
         </ToolBar>
         <AnchorPane VBox.vgrow="ALWAYS">