@@ -7,6 +7,7 @@ namespace FastbootCLI
77 class Program
88 {
99 private static string ? serial = null ;
10+ private static string ? slot = null ;
1011
1112 static void Main ( string [ ] args )
1213 {
@@ -20,9 +21,10 @@ static void Main(string[] args)
2021 {
2122 string arg = args [ i ++ ] ;
2223 if ( arg == "-s" && i < args . Length ) serial = args [ i ++ ] ;
24+ else if ( arg == "--slot" && i < args . Length ) slot = args [ i ++ ] ;
2325 else if ( arg == "--debug" ) FastbootDebug . IsEnabled = true ;
24- else if ( arg == "--version" ) { Console . WriteLine ( "fastboot version 1.0.1 " ) ; return ; }
25- else if ( arg == "-h" || arg == "--help" ) { ShowHelp ( ) ; return ; }
26+ else if ( arg == "--version" || arg == "version" ) { Console . WriteLine ( "fastboot version 1.1.0 " ) ; return ; }
27+ else if ( arg == "-h" || arg == "--help" || arg == "help" ) { ShowHelp ( ) ; return ; }
2628 else if ( ! arg . StartsWith ( "-" ) )
2729 {
2830 string command = arg ;
@@ -44,18 +46,42 @@ static void ExecuteCommand(string command, List<string> args)
4446 {
4547 if ( command == "devices" )
4648 {
47- foreach ( var dev in WinUSBFinder . FindDevice ( ) )
48- Console . WriteLine ( $ "{ dev . SerialNumber } \t fastboot") ;
49+ bool verbose = args . Contains ( "-l" ) ;
50+ foreach ( var dev in UsbManager . GetAllDevices ( ) )
51+ {
52+ if ( verbose ) Console . WriteLine ( $ "{ dev . SerialNumber } \t fastboot { dev . GetType ( ) . Name } ") ;
53+ else Console . WriteLine ( $ "{ dev . SerialNumber } \t fastboot") ;
54+ }
4955 return ;
5056 }
5157
52- var devices = WinUSBFinder . FindDevice ( ) ;
58+ var devices = UsbManager . GetAllDevices ( ) ;
5359 UsbDevice ? target = serial != null ? devices . FirstOrDefault ( d => d . SerialNumber == serial ) : ( devices . Count > 0 ? devices [ 0 ] : null ) ;
5460
5561 if ( target == null ) throw new Exception ( "no devices/found" ) ;
5662
5763 using FastbootUtil util = new FastbootUtil ( target ) ;
58- util . ReceivedFromDevice += ( s , e ) => { if ( e . NewInfo != null ) Console . Error . WriteLine ( "(bootloader) " + e . NewInfo ) ; } ;
64+ util . ReceivedFromDevice += ( s , e ) =>
65+ {
66+ if ( e . NewInfo != null ) Console . Error . WriteLine ( "(bootloader) " + e . NewInfo ) ;
67+ } ;
68+ util . DataTransferProgressChanged += ( s , e ) =>
69+ {
70+ int percent = ( int ) ( e . Item1 * 100 / e . Item2 ) ;
71+ Console . Write ( $ "\r { command } ({ e . Item1 } /{ e . Item2 } ) { percent } % ") ;
72+ if ( e . Item1 == e . Item2 ) Console . WriteLine ( ) ;
73+ } ;
74+
75+ // Process --slot if provided
76+ string cmdSuffix = "" ;
77+ if ( ! string . IsNullOrEmpty ( slot ) )
78+ {
79+ if ( slot == "all" || slot == "other" || slot == "a" || slot == "b" )
80+ {
81+ // For specific commands, Google fastboot appends slot suffix
82+ // We handle it in individual cases if needed or via a global rule
83+ }
84+ }
5985
6086 switch ( command )
6187 {
@@ -64,16 +90,173 @@ static void ExecuteCommand(string command, List<string> args)
6490 if ( args [ 0 ] == "all" ) util . GetVarAll ( ) ;
6591 else Console . WriteLine ( args [ 0 ] + ": " + util . GetVar ( args [ 0 ] ) ) ;
6692 break ;
93+
6794 case "reboot" :
6895 string targetStr = args . Count > 0 ? args [ 0 ] : "" ;
6996 util . Reboot ( targetStr ) . ThrowIfError ( ) ;
7097 break ;
98+
99+ case "fetch" :
100+ if ( args . Count < 2 ) throw new Exception ( "usage: fastboot fetch <partition> <outfile>" ) ;
101+ util . Fetch ( args [ 0 ] , args [ 1 ] ) . ThrowIfError ( ) ;
102+ break ;
103+
104+ case "flash" :
105+ if ( args . Count < 1 ) throw new Exception ( "usage: fastboot flash <partition> [filename]" ) ;
106+ string part = args [ 0 ] ;
107+ string ? file = args . Count > 1 ? args [ 1 ] : null ;
108+ if ( file == null ) throw new Exception ( "Automatic image discovery from $ANDROID_PRODUCT_OUT not implemented yet. Please specify filename." ) ;
109+ if ( ! File . Exists ( file ) ) throw new Exception ( $ "File not found: { file } ") ;
110+ using ( var fs = File . OpenRead ( file ) )
111+ {
112+ util . FlashUnsparseImage ( part , fs , fs . Length ) . ThrowIfError ( ) ;
113+ }
114+ break ;
115+
116+ case "flash:raw" :
117+ if ( args . Count < 2 ) throw new Exception ( "usage: fastboot flash:raw <partition> <kernel> [ramdisk [second]]" ) ;
118+ string rawPart = args [ 0 ] ;
119+ string rawKernel = args [ 1 ] ;
120+ string ? rawRamdisk = args . Count > 2 ? args [ 2 ] : null ;
121+ string ? rawSecond = args . Count > 3 ? args [ 3 ] : null ;
122+ util . FlashRaw ( rawPart , rawKernel , rawRamdisk , rawSecond ) . ThrowIfError ( ) ;
123+ break ;
124+
125+ case "erase" :
126+ if ( args . Count == 0 ) throw new Exception ( "usage: fastboot erase <partition>" ) ;
127+ util . ErasePartition ( args [ 0 ] ) . ThrowIfError ( ) ;
128+ break ;
129+
130+ case "format" :
131+ if ( args . Count == 0 ) throw new Exception ( "usage: fastboot format <partition>" ) ;
132+ util . FormatPartition ( args [ 0 ] ) . ThrowIfError ( ) ;
133+ break ;
134+
135+ case "set_active" :
136+ if ( args . Count == 0 ) throw new Exception ( "usage: fastboot set_active <slot>" ) ;
137+ util . SetActiveSlot ( args [ 0 ] ) . ThrowIfError ( ) ;
138+ break ;
139+
140+ case "oem" :
141+ if ( args . Count == 0 ) throw new Exception ( "usage: fastboot oem <command>" ) ;
142+ util . OemCommand ( string . Join ( " " , args ) ) . ThrowIfError ( ) ;
143+ break ;
144+
145+ case "flashing" :
146+ if ( args . Count == 0 ) throw new Exception ( "usage: fastboot flashing lock|unlock|lock_critical|unlock_critical|get_unlock_ability" ) ;
147+ util . FlashingCommand ( string . Join ( " " , args ) ) . ThrowIfError ( ) ;
148+ break ;
149+
150+ case "create-logical-partition" :
151+ if ( args . Count < 2 ) throw new Exception ( "usage: fastboot create-logical-partition <partition> <size>" ) ;
152+ if ( ! long . TryParse ( args [ 1 ] , out long size ) ) throw new Exception ( "Invalid size" ) ;
153+ util . CreateLogicalPartition ( args [ 0 ] , size ) . ThrowIfError ( ) ;
154+ break ;
155+
156+ case "delete-logical-partition" :
157+ if ( args . Count == 0 ) throw new Exception ( "usage: fastboot delete-logical-partition <partition>" ) ;
158+ util . RawCommand ( "delete-logical-partition:" + args [ 0 ] ) . ThrowIfError ( ) ;
159+ break ;
160+
161+ case "resize-logical-partition" :
162+ if ( args . Count < 2 ) throw new Exception ( "usage: fastboot resize-logical-partition <partition> <size>" ) ;
163+ if ( ! long . TryParse ( args [ 1 ] , out long rsize ) ) throw new Exception ( "Invalid size" ) ;
164+ util . RawCommand ( $ "resize-logical-partition:{ args [ 0 ] } :{ rsize } ") . ThrowIfError ( ) ;
165+ break ;
166+
167+ case "snapshot-update" :
168+ string sub = args . Count > 0 ? args [ 0 ] : "cancel" ;
169+ util . SnapshotUpdate ( sub ) . ThrowIfError ( ) ;
170+ break ;
171+
172+ case "continue" :
173+ util . Continue ( ) . ThrowIfError ( ) ;
174+ break ;
175+
176+ case "stage" :
177+ if ( args . Count == 0 ) throw new Exception ( "usage: fastboot stage <filename>" ) ;
178+ byte [ ] stageData = File . ReadAllBytes ( args [ 0 ] ) ;
179+ util . Stage ( stageData ) . ThrowIfError ( ) ;
180+ break ;
181+
182+ case "get_staged" :
183+ if ( args . Count == 0 ) throw new Exception ( "usage: fastboot get_staged <outfile>" ) ;
184+ using ( var ofs = File . Create ( args [ 0 ] ) )
185+ {
186+ util . UploadData ( "get_staged" , ofs ) . ThrowIfError ( ) ;
187+ }
188+ break ;
189+
190+ case "upload" :
191+ if ( args . Count < 2 ) throw new Exception ( "usage: fastboot upload <name> <outfile>" ) ;
192+ util . Upload ( args [ 0 ] , args [ 1 ] ) . ThrowIfError ( ) ;
193+ break ;
194+
195+ case "gsi" :
196+ if ( args . Count == 0 ) throw new Exception ( "usage: fastboot gsi wipe|disable|status" ) ;
197+ util . GsiCommand ( args [ 0 ] ) . ThrowIfError ( ) ;
198+ break ;
199+
200+ case "wipe-super" :
201+ string ? emptyImg = args . Count > 0 ? args [ 0 ] : null ;
202+ if ( emptyImg != null ) util . UpdateSuper ( "super" , emptyImg , true ) . ThrowIfError ( ) ;
203+ else util . RawCommand ( "wipe-super" ) . ThrowIfError ( ) ;
204+ break ;
205+
206+ case "boot" :
207+ if ( args . Count == 0 ) throw new Exception ( "usage: fastboot boot <kernel> [ramdisk [second]]" ) ;
208+ string kernel = args [ 0 ] ;
209+ string ? ramdisk = args . Count > 1 ? args [ 1 ] : null ;
210+ string ? second = args . Count > 2 ? args [ 2 ] : null ;
211+ util . BootFile ( kernel , ramdisk , second ) . ThrowIfError ( ) ;
212+ break ;
213+
71214 default :
72215 Console . WriteLine ( "Command not implemented: " + command ) ;
73216 break ;
74217 }
75218 }
76219
77- static void ShowHelp ( ) { Console . WriteLine ( "Usage: fastboot [-s <serial>] [--debug] <command> [args]" ) ; }
220+ static void ShowHelp ( )
221+ {
222+ Console . WriteLine ( "Usage: fastboot [-s <serial>] [--slot <slot>] [--debug] <command> [args]" ) ;
223+ Console . WriteLine ( "\n basics:" ) ;
224+ Console . WriteLine ( " devices [-l] List connected devices." ) ;
225+ Console . WriteLine ( " getvar <name> | all Display bootloader variable." ) ;
226+ Console . WriteLine ( " reboot [bootloader|fastboot] Reboot device." ) ;
227+ Console . WriteLine ( " continue Continue with autoboot." ) ;
228+
229+ Console . WriteLine ( "\n flashing:" ) ;
230+ Console . WriteLine ( " flash <partition> [filename] Write file to partition." ) ;
231+ Console . WriteLine ( " flash:raw <p> <k> [r [s]] Create boot image and flash it." ) ;
232+ Console . WriteLine ( " erase <partition> Erase a flash partition." ) ;
233+ Console . WriteLine ( " format <partition> Format a flash partition." ) ;
234+ Console . WriteLine ( " set_active <slot> Set the active slot." ) ;
235+
236+ Console . WriteLine ( "\n locking/unlocking:" ) ;
237+ Console . WriteLine ( " flashing lock|unlock Lock/unlock partitions." ) ;
238+ Console . WriteLine ( " flashing lock_critical|... Lock/unlock critical partitions." ) ;
239+ Console . WriteLine ( " flashing get_unlock_ability Check if unlocking is allowed." ) ;
240+
241+ Console . WriteLine ( "\n advanced:" ) ;
242+ Console . WriteLine ( " fetch <p> <outfile> Fetch a partition from device." ) ;
243+ Console . WriteLine ( " oem <command> Execute OEM-specific command." ) ;
244+ Console . WriteLine ( " gsi wipe|disable|status Manage GSI installation." ) ;
245+ Console . WriteLine ( " wipe-super [super_empty] Wipe the super partition." ) ;
246+ Console . WriteLine ( " snapshot-update cancel|merge Manage snapshot updates." ) ;
247+
248+ Console . WriteLine ( "\n logical partitions:" ) ;
249+ Console . WriteLine ( " create-logical-partition <p> <s>" ) ;
250+ Console . WriteLine ( " delete-logical-partition <p>" ) ;
251+ Console . WriteLine ( " resize-logical-partition <p> <s>" ) ;
252+
253+ Console . WriteLine ( "\n boot image:" ) ;
254+ Console . WriteLine ( " boot <kernel> [ramdisk [s]] Download and boot kernel from RAM." ) ;
255+
256+ Console . WriteLine ( "\n Android Things / Miscellaneous:" ) ;
257+ Console . WriteLine ( " stage <filename> Send file to device for next command." ) ;
258+ Console . WriteLine ( " get_staged <outfile> Write data staged by last command to file." ) ;
259+ Console . WriteLine ( " upload <name> <outfile> Legacy upload (e.g. last_kmsg)." ) ;
260+ }
78261 }
79262}
0 commit comments