Skip to content

Commit 4cea480

Browse files
committed
Add Windows drivers installer function
1 parent f2cd0c5 commit 4cea480

21 files changed

+317
-20
lines changed

src/main/java/nsusbloader/Controllers/SettingsController.java

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import nsusbloader.AppPreferences;
3131
import nsusbloader.ServiceWindow;
3232
import nsusbloader.ModelControllers.UpdatesChecker;
33+
import nsusbloader.Utilities.WindowsDrivers.DriversInstall;
3334

3435
import java.io.File;
3536
import java.io.IOException;
@@ -42,22 +43,16 @@
4243

4344
public class SettingsController implements Initializable {
4445
@FXML
45-
private CheckBox nspFilesFilterForGLCB;
46-
@FXML
47-
private CheckBox validateNSHostNameCb;
48-
@FXML
49-
private CheckBox expertModeCb;
50-
@FXML
51-
private CheckBox autoDetectIpCb;
52-
@FXML
53-
private CheckBox randPortCb;
46+
private CheckBox nspFilesFilterForGLCB,
47+
validateNSHostNameCb,
48+
expertModeCb,
49+
autoDetectIpCb,
50+
randPortCb;
5451

5552
@FXML
56-
private TextField pcIpTextField;
57-
@FXML
58-
private TextField pcPortTextField;
59-
@FXML
60-
private TextField pcExtraTextField;
53+
private TextField pcIpTextField,
54+
pcPortTextField,
55+
pcExtraTextField;
6156

6257
@FXML
6358
private CheckBox dontServeCb;
@@ -69,13 +64,14 @@ public class SettingsController implements Initializable {
6964
private CheckBox autoCheckUpdCb;
7065
@FXML
7166
private Hyperlink newVersionLink;
72-
@FXML
73-
private Button checkForUpdBtn;
67+
7468
@FXML
7569
private CheckBox tfXciSpprtCb;
7670

7771
@FXML
78-
private Button langBtn;
72+
private Button langBtn,
73+
checkForUpdBtn,
74+
drvInstBtn;
7975
@FXML
8076
private ChoiceBox<String> langCB;
8177

@@ -215,6 +211,15 @@ public void initialize(URL url, ResourceBundle resourceBundle) {
215211
updates.setDaemon(true);
216212
updates.start();
217213
});
214+
215+
if (isWindows()){
216+
Region btnDrvImage = new Region();
217+
btnDrvImage.getStyleClass().add("regionWindows");
218+
drvInstBtn.setGraphic(btnDrvImage);
219+
drvInstBtn.setVisible(true);
220+
drvInstBtn.setOnAction(actionEvent -> new DriversInstall(resourceBundle));
221+
}
222+
218223
tfXciSpprtCb.setSelected(AppPreferences.getInstance().getTfXCI());
219224

220225
// Language settings area
@@ -282,6 +287,11 @@ public void initialize(URL url, ResourceBundle resourceBundle) {
282287
}
283288
glOldVerCheck.setOnAction(e-> glOldVerChoice.setDisable(! glOldVerCheck.isSelected()) );
284289
}
290+
291+
private boolean isWindows(){
292+
return System.getProperty("os.name").toLowerCase().replace(" ", "").contains("windows");
293+
}
294+
285295
public boolean getNSPFileFilterForGL(){return nspFilesFilterForGLCB.isSelected(); }
286296
public boolean getExpertModeSelected(){ return expertModeCb.isSelected(); }
287297
public boolean getAutoIpSelected(){ return autoDetectIpCb.isSelected(); }

src/main/java/nsusbloader/ServiceWindow.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ private static void getNotification(String title, String body, Alert.AlertType t
5454
new Image("/res/warn_ico64x64.png"),
5555
new Image("/res/warn_ico128x128.png")
5656
);
57-
dialogStage.toFront();
58-
5957
alertBox.show();
58+
dialogStage.toFront();
6059
}
6160
/**
6261
* Create notification window with confirm/deny
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
Copyright 2019-2020 Dmitry Isaenko
3+
4+
This file is part of NS-USBloader.
5+
6+
NS-USBloader is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
NS-USBloader is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
package nsusbloader.Utilities.WindowsDrivers;
20+
21+
import javafx.concurrent.Task;
22+
23+
import java.io.*;
24+
import java.net.URL;
25+
26+
public class DownloadDriversTask extends Task<String> {
27+
28+
private static final String driverFileLocationURL = "https://github.com/developersu/NS-Drivers/releases/download/v1.0/Drivers_set.exe";
29+
private static final long driversFileSize = 3857375;
30+
31+
private static File driversInstallerFile;
32+
33+
@Override
34+
protected String call() {
35+
if (isDriversDownloaded())
36+
return driversInstallerFile.getAbsolutePath();
37+
if (downloadDrivers())
38+
return driversInstallerFile.getAbsolutePath();
39+
return null;
40+
}
41+
42+
private boolean isDriversDownloaded(){
43+
return driversInstallerFile != null && driversInstallerFile.length() == driversFileSize;
44+
}
45+
46+
private boolean downloadDrivers(){
47+
try {
48+
File tmpDirectory = File.createTempFile("nsul", null);
49+
if (! tmpDirectory.delete())
50+
return false;
51+
if (! tmpDirectory.mkdirs())
52+
return false;
53+
54+
tmpDirectory.deleteOnExit();
55+
56+
URL url = new URL(driverFileLocationURL);
57+
BufferedInputStream bis = new BufferedInputStream(url.openStream());
58+
59+
driversInstallerFile = new File(tmpDirectory, "drivers.exe");
60+
FileOutputStream fos = new FileOutputStream(driversInstallerFile);
61+
62+
byte[] dataBuffer = new byte[1024];
63+
int bytesRead;
64+
double totalRead = 0;
65+
66+
while ((bytesRead = bis.read(dataBuffer, 0, 1024)) != -1) {
67+
fos.write(dataBuffer, 0, bytesRead);
68+
totalRead += bytesRead;
69+
updateProgress(totalRead, driversFileSize);
70+
if (this.isCancelled()) {
71+
bis.close();
72+
fos.close();
73+
updateProgress(0, 0);
74+
return false;
75+
}
76+
}
77+
bis.close();
78+
fos.close();
79+
80+
return true;
81+
}
82+
catch (IOException | SecurityException e){
83+
updateMessage("Error: "+e.toString().replaceAll(":.*$", ""));
84+
e.printStackTrace();
85+
return false;
86+
}
87+
}
88+
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
Copyright 2019-2020 Dmitry Isaenko
3+
4+
This file is part of NS-USBloader.
5+
6+
NS-USBloader is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
NS-USBloader is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
package nsusbloader.Utilities.WindowsDrivers;
20+
21+
import javafx.geometry.Insets;
22+
import javafx.geometry.Pos;
23+
import javafx.scene.Scene;
24+
import javafx.scene.control.Button;
25+
import javafx.scene.control.Label;
26+
import javafx.scene.control.ProgressBar;
27+
import javafx.scene.image.Image;
28+
import javafx.scene.layout.HBox;
29+
import javafx.scene.layout.Pane;
30+
import javafx.scene.layout.Priority;
31+
import javafx.scene.layout.VBox;
32+
import javafx.stage.Stage;
33+
import nsusbloader.AppPreferences;
34+
35+
import java.io.BufferedReader;
36+
import java.io.IOException;
37+
import java.io.InputStreamReader;
38+
import java.util.ResourceBundle;
39+
40+
public class DriversInstall {
41+
42+
private static volatile boolean isRunning;
43+
44+
private Label runInstallerStatusLabel;
45+
46+
public DriversInstall(ResourceBundle rb){
47+
48+
if (DriversInstall.isRunning)
49+
return;
50+
51+
DriversInstall.isRunning = true;
52+
53+
DownloadDriversTask downloadTask = new DownloadDriversTask();
54+
55+
Button cancelButton = new Button(rb.getString("btn_Cancel"));
56+
57+
HBox hBoxInformation = new HBox();
58+
hBoxInformation.setAlignment(Pos.TOP_LEFT);
59+
hBoxInformation.getChildren().add(new Label(rb.getString("windowBodyDownloadDrivers")));
60+
61+
ProgressBar progressBar = new ProgressBar();
62+
progressBar.setPrefWidth(Double.MAX_VALUE);
63+
progressBar.progressProperty().bind(downloadTask.progressProperty());
64+
65+
Label downloadStatusLabel = new Label();
66+
downloadStatusLabel.setWrapText(true);
67+
downloadStatusLabel.textProperty().bind(downloadTask.messageProperty());
68+
69+
runInstallerStatusLabel = new Label();
70+
runInstallerStatusLabel.setWrapText(true);
71+
72+
Pane fillerPane1 = new Pane();
73+
Pane fillerPane2 = new Pane();
74+
75+
VBox parentVBox = new VBox();
76+
parentVBox.setAlignment(Pos.TOP_CENTER);
77+
parentVBox.setFillWidth(true);
78+
parentVBox.setSpacing(5.0);
79+
parentVBox.setPadding(new Insets(5.0));
80+
parentVBox.setFillWidth(true);
81+
parentVBox.getChildren().addAll(
82+
hBoxInformation,
83+
fillerPane1,
84+
downloadStatusLabel,
85+
runInstallerStatusLabel,
86+
fillerPane2,
87+
progressBar,
88+
cancelButton
89+
); // TODO:FIX
90+
91+
VBox.setVgrow(fillerPane1, Priority.ALWAYS);
92+
VBox.setVgrow(fillerPane2, Priority.ALWAYS);
93+
94+
Stage stage = new Stage();
95+
96+
stage.setTitle(rb.getString("windowTitleDownloadDrivers"));
97+
stage.getIcons().addAll(
98+
new Image("/res/dwnload_ico32x32.png"), //TODO: REDRAW
99+
new Image("/res/dwnload_ico48x48.png"),
100+
new Image("/res/dwnload_ico64x64.png"),
101+
new Image("/res/dwnload_ico128x128.png")
102+
);
103+
stage.setMinWidth(400);
104+
stage.setMinHeight(150);
105+
106+
Scene mainScene = new Scene(parentVBox, 405, 155);
107+
108+
mainScene.getStylesheets().add(AppPreferences.getInstance().getTheme());
109+
110+
stage.setOnHidden(windowEvent -> {
111+
downloadTask.cancel(true );
112+
DriversInstall.isRunning = false;
113+
});
114+
115+
stage.setScene(mainScene);
116+
stage.show();
117+
stage.toFront();
118+
119+
downloadTask.setOnSucceeded(event -> {
120+
cancelButton.setText(rb.getString("btn_Close"));
121+
122+
String returnedValue = downloadTask.getValue();
123+
124+
if (returnedValue == null)
125+
return;
126+
127+
if (runInstaller(returnedValue))
128+
stage.close();
129+
});
130+
131+
Thread downloadThread = new Thread(downloadTask);
132+
downloadThread.start();
133+
134+
cancelButton.setOnAction(actionEvent -> {
135+
downloadTask.cancel(true );
136+
stage.close();
137+
});
138+
}
139+
140+
private boolean runInstaller(String pathToFile) {
141+
try {
142+
Runtime.getRuntime().exec("cmd /c "+pathToFile);
143+
return true;
144+
}
145+
catch (Exception e){
146+
runInstallerStatusLabel.setText("Error: "+e.toString());
147+
e.printStackTrace();
148+
return false;
149+
}
150+
}
151+
}

src/main/resources/SettingsTab.fxml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
<Label text="%tab2_Lbl_Language" />
2323
<ChoiceBox fx:id="langCB" prefWidth="100.0" />
2424
<Button fx:id="langBtn" mnemonicParsing="false" text="OK" />
25+
<VBox alignment="CENTER_RIGHT" HBox.hgrow="ALWAYS">
26+
<children>
27+
<Button fx:id="drvInstBtn" mnemonicParsing="false" text="%tab2_Btn_InstallDrivers" visible="false" />
28+
</children>
29+
</VBox>
2530
</children>
2631
<VBox.margin>
2732
<Insets left="5.0" />

src/main/resources/locale.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,8 @@ failure_txt=Failed
6363
btn_Select=Select
6464
btn_InjectPayloader=Inject payload
6565
tabNXDT_Btn_Start=Start!
66+
tab2_Btn_InstallDrivers=Download and install drivers
67+
windowTitleDownloadDrivers=Download and install drivers
68+
windowBodyDownloadDrivers=Downloading drivers (libusbK v3.0.7.0)...
69+
btn_Cancel=Cancel
70+
btn_Close=Close

src/main/resources/locale_deu.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,5 @@ tab2_Lbl_AllowXciNszXczDesc=Von einigen Drittanbietern verwendet, welche XCI/NSZ
4343
tab2_Lbl_Language=Sprache
4444
windowBodyRestartToApplyLang=Bitte die Applikation neustarten um die Einstellungen zu \u00FCbernehmen.
4545
tab2_Cb_GLshowNspOnly=Nur *.nsp in GoldLeaf zeigen.
46+
btn_Cancel=Abbrechen
47+

src/main/resources/locale_fra.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,6 @@ windowBodyNewVersionUnknown=Une erreur s'est produite\nPeut-\u00EAtre des probl\
4141
tab2_Cb_AllowXciNszXcz=Autoriser la s\u00E9lection de fichiers XCI / NSZ / XCZ pour TinFoil
4242
tab2_Lbl_AllowXciNszXczDesc=Utilis\u00E9 par certaines applications tierces prenant en charge XCI/NSZ/XCZ et utilisant le protocole de transfert TinFoil. Ne changez pas en cas de doute.
4343
tab2_Lbl_Language=La langue
44+
btn_Cancel=Annuler
45+
4446

src/main/resources/locale_ita.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,5 @@ done_txt=Fatto!
6262
failure_txt=Fallito
6363
btn_Select=Seleziona
6464
btn_InjectPayloader=Inietta payload
65+
btn_Cancel=Annulla
66+

src/main/resources/locale_por.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,5 @@ done_txt=Feito!
6262
failure_txt=Falhou
6363
btn_Select=Selecionar
6464
btn_InjectPayloader=Injetar payload
65+
btn_Cancel=Cancelar
66+

0 commit comments

Comments
 (0)