16
16
package ghidra .plugins .fsbrowser ;
17
17
18
18
import java .util .*;
19
-
19
+ import java . util . stream . Collectors ;
20
20
import java .awt .Component ;
21
21
import java .awt .event .InputEvent ;
22
22
import java .awt .event .KeyEvent ;
35
35
import ghidra .app .events .ProgramActivatedPluginEvent ;
36
36
import ghidra .app .plugin .PluginCategoryNames ;
37
37
import ghidra .app .services .*;
38
+ import ghidra .app .util .bin .ByteProvider ;
38
39
import ghidra .app .util .opinion .LoaderService ;
39
40
import ghidra .formats .gfilesystem .*;
41
+ import ghidra .formats .gfilesystem .factory .FileSystemFactoryMgr ;
42
+ import ghidra .formats .gfilesystem .factory .FileSystemInfoRec ;
43
+ import ghidra .formats .gfilesystem .factory .GFileSystemProbeByteProvider ;
44
+ import ghidra .formats .gfilesystem .factory .GFileSystemProbeBytesOnly ;
45
+ import ghidra .formats .gfilesystem .factory .GFileSystemProbeManual ;
40
46
import ghidra .framework .main .FrontEndService ;
41
47
import ghidra .framework .main .ApplicationLevelPlugin ;
42
48
import ghidra .framework .model .Project ;
@@ -244,9 +250,12 @@ private void doOpenFilesystem(FSRL containerFSRL, Component parent, TaskMonitor
244
250
FileSystemRef ref = fsService ().probeFileForFilesystem (containerFSRL , monitor ,
245
251
FileSystemProbeConflictResolver .GUI_PICKER );
246
252
if (ref == null ) {
247
- Msg .showWarn (this , parent , "Open Filesystem" ,
248
- "No filesystem provider for " + containerFSRL .getName ());
249
- return ;
253
+ ref = showFallbackFileSystemChooser (containerFSRL , parent , monitor );
254
+ if (ref == null ) {
255
+ Msg .showWarn (this , parent , "Open Filesystem" ,
256
+ "No filesystem provider for " + containerFSRL .getName ());
257
+ return ;
258
+ }
250
259
}
251
260
252
261
createNewFileSystemBrowser (ref , true );
@@ -257,6 +266,42 @@ private void doOpenFilesystem(FSRL containerFSRL, Component parent, TaskMonitor
257
266
}
258
267
}
259
268
269
+ private FileSystemRef showFallbackFileSystemChooser (FSRL containerFSRL , Component parent , TaskMonitor monitor ) throws CancelledException , IOException {
270
+ FileSystemFactoryMgr fsFactoryMgr = FileSystemFactoryMgr .getInstance ();
271
+
272
+ //@formatter:off
273
+ List <FileSystemInfoRec > fsList = fsFactoryMgr .getFileSystemInfoRecs ().values ()
274
+ .stream ()
275
+ .filter (fs -> fs .getFactory () instanceof GFileSystemProbeManual )
276
+ .sorted ((filesystem1 , filesystem2 ) -> filesystem1 .getDescription ().compareToIgnoreCase (filesystem2 .getDescription ()))
277
+ .collect (Collectors .toList ());
278
+ //@formatter:on
279
+
280
+ if (fsList .isEmpty ()) {
281
+ return null ;
282
+ }
283
+
284
+ FileSystemInfoRec chosenFilesystem = SelectFromListDialog .selectFromList (fsList , "Select filesystem" ,
285
+ "Select a filesystem from list" , FileSystemInfoRec ::getDescription );
286
+ if (chosenFilesystem == null ) {
287
+ return null ;
288
+ }
289
+
290
+ ByteProvider byteProvider = fsService ().getByteProvider (containerFSRL , true , monitor );
291
+ GFileSystem fs = fsFactoryMgr .mountFileSystem (chosenFilesystem .getType (), byteProvider , fsService , monitor );
292
+ if (fs != null ) {
293
+ FileSystemRef fsRef = fsService ().getMountedFilesystem (containerFSRL .makeNested (chosenFilesystem .getType ()));
294
+ if (fsRef != null ) {
295
+ fs .close ();
296
+ return fsRef ;
297
+ }
298
+ fsService ().addFileSystem (fs );
299
+ return fs .getRefManager ().create ();
300
+ }
301
+
302
+ return null ;
303
+ }
304
+
260
305
/**
261
306
* Prompts the user to pick a file system container file to open using a local
262
307
* filesystem browser and then displays that filesystem in a new fsb browser.
0 commit comments