├── .gitattributes
├── .gitignore
├── AdbWinApi.dll
├── AdbWinUsbApi.dll
├── App.config
├── App.xaml
├── App.xaml.cs
├── Fastboot.cs
├── FastbootActionWindow.xaml
├── FastbootActionWindow.xaml.cs
├── FastbootData.cs
├── FastbootEnhance.csproj
├── FastbootEnhance.sln
├── FastbootUI.cs
├── Helper.cs
├── LICENSE
├── Logger.xaml
├── Logger.xaml.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Payload.cs
├── PayloadUI.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.ja-JP.Designer.cs
├── Resources.ja-JP.resx
├── Resources.ko-KR.Designer.cs
├── Resources.ko-KR.resx
├── Resources.resx
├── Resources.zh-CN.Designer.cs
├── Resources.zh-CN.resx
├── Settings.Designer.cs
└── Settings.settings
├── README.md
├── UpdateMetadata.cs
├── big_icon.png
├── fastboot.exe
├── icon.ico
├── liblzma.dll
├── liblzma64.dll
├── packages.config
└── screenshots
├── Banner.png
├── ss1.png
├── ss2.png
├── ss3.png
└── ss4.png
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Oo]ut/
33 | [Ll]og/
34 | [Ll]ogs/
35 |
36 | # Visual Studio 2015/2017 cache/options directory
37 | .vs/
38 | # Uncomment if you have tasks that create the project's static files in wwwroot
39 | #wwwroot/
40 |
41 | # Visual Studio 2017 auto generated files
42 | Generated\ Files/
43 |
44 | # MSTest test Results
45 | [Tt]est[Rr]esult*/
46 | [Bb]uild[Ll]og.*
47 |
48 | # NUnit
49 | *.VisualState.xml
50 | TestResult.xml
51 | nunit-*.xml
52 |
53 | # Build Results of an ATL Project
54 | [Dd]ebugPS/
55 | [Rr]eleasePS/
56 | dlldata.c
57 |
58 | # Benchmark Results
59 | BenchmarkDotNet.Artifacts/
60 |
61 | # .NET Core
62 | project.lock.json
63 | project.fragment.lock.json
64 | artifacts/
65 |
66 | # ASP.NET Scaffolding
67 | ScaffoldingReadMe.txt
68 |
69 | # StyleCop
70 | StyleCopReport.xml
71 |
72 | # Files built by Visual Studio
73 | *_i.c
74 | *_p.c
75 | *_h.h
76 | *.ilk
77 | *.meta
78 | *.obj
79 | *.iobj
80 | *.pch
81 | *.pdb
82 | *.ipdb
83 | *.pgc
84 | *.pgd
85 | *.rsp
86 | *.sbr
87 | *.tlb
88 | *.tli
89 | *.tlh
90 | *.tmp
91 | *.tmp_proj
92 | *_wpftmp.csproj
93 | *.log
94 | *.vspscc
95 | *.vssscc
96 | .builds
97 | *.pidb
98 | *.svclog
99 | *.scc
100 |
101 | # Chutzpah Test files
102 | _Chutzpah*
103 |
104 | # Visual C++ cache files
105 | ipch/
106 | *.aps
107 | *.ncb
108 | *.opendb
109 | *.opensdf
110 | *.sdf
111 | *.cachefile
112 | *.VC.db
113 | *.VC.VC.opendb
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 | *.vspx
119 | *.sap
120 |
121 | # Visual Studio Trace Files
122 | *.e2e
123 |
124 | # TFS 2012 Local Workspace
125 | $tf/
126 |
127 | # Guidance Automation Toolkit
128 | *.gpState
129 |
130 | # ReSharper is a .NET coding add-in
131 | _ReSharper*/
132 | *.[Rr]e[Ss]harper
133 | *.DotSettings.user
134 |
135 | # TeamCity is a build add-in
136 | _TeamCity*
137 |
138 | # DotCover is a Code Coverage Tool
139 | *.dotCover
140 |
141 | # AxoCover is a Code Coverage Tool
142 | .axoCover/*
143 | !.axoCover/settings.json
144 |
145 | # Coverlet is a free, cross platform Code Coverage Tool
146 | coverage*.json
147 | coverage*.xml
148 | coverage*.info
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio LightSwitch build output
298 | **/*.HTMLClient/GeneratedArtifacts
299 | **/*.DesktopClient/GeneratedArtifacts
300 | **/*.DesktopClient/ModelManifest.xml
301 | **/*.Server/GeneratedArtifacts
302 | **/*.Server/ModelManifest.xml
303 | _Pvt_Extensions
304 |
305 | # Paket dependency manager
306 | .paket/paket.exe
307 | paket-files/
308 |
309 | # FAKE - F# Make
310 | .fake/
311 |
312 | # CodeRush personal settings
313 | .cr/personal
314 |
315 | # Python Tools for Visual Studio (PTVS)
316 | __pycache__/
317 | *.pyc
318 |
319 | # Cake - Uncomment if you are using it
320 | # tools/**
321 | # !tools/packages.config
322 |
323 | # Tabs Studio
324 | *.tss
325 |
326 | # Telerik's JustMock configuration file
327 | *.jmconfig
328 |
329 | # BizTalk build output
330 | *.btp.cs
331 | *.btm.cs
332 | *.odx.cs
333 | *.xsd.cs
334 |
335 | # OpenCover UI analysis results
336 | OpenCover/
337 |
338 | # Azure Stream Analytics local run output
339 | ASALocalRun/
340 |
341 | # MSBuild Binary and Structured Log
342 | *.binlog
343 |
344 | # NVidia Nsight GPU debugger configuration file
345 | *.nvuser
346 |
347 | # MFractors (Xamarin productivity tool) working folder
348 | .mfractor/
349 |
350 | # Local History for Visual Studio
351 | .localhistory/
352 |
353 | # BeatPulse healthcheck temp database
354 | healthchecksdb
355 |
356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
357 | MigrationBackup/
358 |
359 | # Ionide (cross platform F# VS Code tools) working folder
360 | .ionide/
361 |
362 | # Fody - auto-generated XML schema
363 | FodyWeavers.xsd
--------------------------------------------------------------------------------
/AdbWinApi.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/AdbWinApi.dll
--------------------------------------------------------------------------------
/AdbWinUsbApi.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/AdbWinUsbApi.dll
--------------------------------------------------------------------------------
/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace FastbootEnhance
10 | {
11 | ///
12 | /// App.xaml 的交互逻辑
13 | ///
14 | public partial class App : Application
15 | {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Fastboot.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 |
5 | namespace FastbootEnhance
6 | {
7 | class Fastboot : IDisposable
8 | {
9 | Process process;
10 | public StreamReader stdout;
11 | public StreamReader stderr;
12 |
13 | public Fastboot(string serial, string action)
14 | {
15 | process = new Process();
16 | process.StartInfo.FileName = ".\\fastboot.exe";
17 | process.StartInfo.Arguments = serial == null ? action :
18 | "\"-s\" \"" + serial + "\" " + action;
19 | process.StartInfo.CreateNoWindow = true;
20 | process.StartInfo.RedirectStandardError = true;
21 | process.StartInfo.RedirectStandardOutput = true;
22 | process.StartInfo.RedirectStandardInput = true;
23 | process.StartInfo.UseShellExecute = false;
24 | process.Start();
25 |
26 | stdout = process.StandardOutput;
27 | stderr = process.StandardError;
28 | }
29 |
30 | public void Dispose()
31 | {
32 | process.Close();
33 | process = null;
34 | }
35 |
36 | ~Fastboot()
37 | {
38 | if (process != null)
39 | Dispose();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/FastbootActionWindow.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/FastbootActionWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 |
4 | namespace FastbootEnhance
5 | {
6 | ///
7 | /// Fastboot_create_resize.xaml 的交互逻辑
8 | ///
9 | public partial class FastbootActionWindow : Window
10 | {
11 | public enum StartType
12 | {
13 | CREATE,
14 | RESIZE
15 | }
16 |
17 | public delegate void FastbootLogicalCallback(string name, ulong size);
18 |
19 | public FastbootActionWindow(StartType type,
20 | string partition_name, long size, FastbootLogicalCallback callback)
21 | {
22 | InitializeComponent();
23 |
24 | this.name.Text = partition_name;
25 | this.size.Text = size.ToString();
26 |
27 | this.ok.Click += delegate
28 | {
29 | if (this.name.Text == "")
30 | {
31 | MessageBox.Show(Properties.Resources.fastboot_partition_name_empty);
32 | return;
33 | }
34 |
35 | if (this.size.Text == "")
36 | {
37 | MessageBox.Show(Properties.Resources.fastboot_partition_size_empty);
38 | return;
39 | }
40 |
41 | ulong new_size = 0;
42 | try
43 | {
44 | new_size = Convert.ToUInt64(this.size.Text);
45 | }
46 | catch (Exception)
47 | {
48 | MessageBox.Show(Properties.Resources.fastboot_partition_size_invalid);
49 | return;
50 | }
51 |
52 | if (type == StartType.RESIZE && new_size == (ulong)size)
53 | {
54 | Close();
55 | return;
56 | }
57 |
58 | if (type == StartType.RESIZE && new_size < (ulong)size)
59 | {
60 | MessageBox.Show(Properties.Resources.fastboot_partition_size_unable_shrink);
61 | return;
62 | }
63 |
64 | callback(this.name.Text, new_size);
65 | Close();
66 | };
67 |
68 | switch (type)
69 | {
70 | case StartType.CREATE:
71 | this.Title = Properties.Resources.fastboot_create_dynamic_partition;
72 | break;
73 | case StartType.RESIZE:
74 | this.Title = Properties.Resources.fastboot_expand_dynamic_partition;
75 | this.name.IsReadOnly = true;
76 | break;
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/FastbootData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FastbootEnhance
5 | {
6 | class FastbootData
7 | {
8 | List> raw_data;
9 |
10 | public Dictionary partition_size;
11 | public Dictionary partition_is_logical;
12 | public string product;
13 | public bool secure;
14 | public string current_slot;
15 | public bool fastbootd;
16 | public long max_download_size;
17 | public string snapshot_update_status;
18 |
19 | public FastbootData(string real_raw_data)
20 | {
21 | raw_data = new List>();
22 | partition_size = new Dictionary();
23 | partition_is_logical = new Dictionary();
24 | product = null;
25 | secure = false;
26 | current_slot = null;
27 | fastbootd = false;
28 | max_download_size = -1;
29 | snapshot_update_status = null;
30 |
31 | foreach (string line in real_raw_data.Split(new char[] { '\n' },
32 | StringSplitOptions.RemoveEmptyEntries))
33 | {
34 | List tmp = new List(line.Split(new char[] { ' ', ':', '\n', '\r', '\t' },
35 | StringSplitOptions.RemoveEmptyEntries));
36 |
37 | if (tmp[0].Contains("bootloader"))
38 | raw_data.Add(tmp);
39 | }
40 |
41 | foreach (List line in raw_data)
42 | {
43 | if (line[1] == "partition-size")
44 | {
45 | string raw_size = line[3];
46 | raw_size = raw_size.Replace("0x", "");
47 | try
48 | {
49 | partition_size.Add(line[2], Convert.ToInt64(raw_size, 16));
50 | }
51 | catch (Exception)
52 | {
53 | partition_size[line[2]] = -1;
54 | }
55 | continue;
56 | }
57 |
58 | if (line[1] == "is-logical")
59 | {
60 | try
61 | {
62 | partition_is_logical.Add(line[2], line[3] == "yes");
63 | }
64 | catch (Exception)
65 | {
66 | partition_is_logical[line[2]] = null;
67 | }
68 | continue;
69 | }
70 |
71 | if (line[1] == "product")
72 | {
73 | product = line[2];
74 | continue;
75 | }
76 |
77 | if (line[1] == "secure")
78 | {
79 | secure = line[2] == "yes";
80 | continue;
81 | }
82 |
83 | if (line[1] == "current-slot")
84 | {
85 | current_slot = line[2];
86 | continue;
87 | }
88 |
89 | if (line[1] == "is-userspace")
90 | {
91 | fastbootd = line[2] == "yes";
92 | continue;
93 | }
94 |
95 | if (line[1] == "max-download-size")
96 | {
97 | max_download_size = Convert.ToInt64(line[2], 16);
98 | continue;
99 | }
100 |
101 | if (line[1] == "snapshot-update-status")
102 | {
103 | snapshot_update_status = line[2];
104 | continue;
105 | }
106 | }
107 |
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/FastbootEnhance.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {7CB79897-F766-40AA-AEC8-F8A5C7B9E26E}
8 | WinExe
9 | FastbootEnhance
10 | FastbootEnhance
11 | v4.5.2
12 | 512
13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 4
15 | true
16 | true
17 |
18 |
19 |
20 |
21 |
22 | AnyCPU
23 | true
24 | full
25 | false
26 | bin\Debug\
27 | DEBUG;TRACE
28 | prompt
29 | 4
30 | true
31 |
32 |
33 | AnyCPU
34 | pdbonly
35 | true
36 | bin\Release\
37 |
38 |
39 | prompt
40 | 4
41 | true
42 |
43 |
44 | true
45 | bin\x86\Debug\
46 | DEBUG;TRACE
47 | full
48 | x86
49 | 7.3
50 | prompt
51 | true
52 |
53 |
54 | bin\x86\Release\
55 | TRACE
56 | true
57 | pdbonly
58 | x86
59 | 7.3
60 | prompt
61 | true
62 |
63 |
64 | true
65 | bin\x64\Debug\
66 | DEBUG;TRACE
67 | full
68 | x64
69 | 7.3
70 | prompt
71 | true
72 |
73 |
74 | bin\x64\Release\
75 | TRACE
76 | true
77 | pdbonly
78 | x64
79 | 7.3
80 | prompt
81 | true
82 |
83 |
84 | icon.ico
85 |
86 |
87 |
88 | packages\DotNetZip.1.15.0\lib\net40\DotNetZip.dll
89 |
90 |
91 | packages\Google.Protobuf.3.17.3\lib\net45\Google.Protobuf.dll
92 |
93 |
94 |
95 | packages\System.Buffers.4.5.1\lib\netstandard1.1\System.Buffers.dll
96 |
97 |
98 |
99 | packages\System.Memory.4.5.4\lib\netstandard1.1\System.Memory.dll
100 |
101 |
102 |
103 | packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | 4.0
114 |
115 |
116 |
117 |
118 |
119 | packages\XZ.NET.2.0.0\lib\net20\XZ.NET.dll
120 |
121 |
122 |
123 |
124 | MSBuild:Compile
125 | Designer
126 |
127 |
128 |
129 |
130 |
131 | FastbootActionWindow.xaml
132 |
133 |
134 | Logger.xaml
135 |
136 |
137 | True
138 | True
139 | Resources.ja-JP.resx
140 |
141 |
142 | True
143 | True
144 | Resources.ko-KR.resx
145 |
146 |
147 | Resources.zh-CN.resx
148 | True
149 | True
150 |
151 |
152 |
153 | Designer
154 | MSBuild:Compile
155 |
156 |
157 | Designer
158 | MSBuild:Compile
159 |
160 |
161 | MSBuild:Compile
162 | Designer
163 |
164 |
165 | App.xaml
166 | Code
167 |
168 |
169 |
170 | MainWindow.xaml
171 | Code
172 |
173 |
174 |
175 |
176 |
177 |
178 | Code
179 |
180 |
181 | True
182 | True
183 | Resources.resx
184 |
185 |
186 | True
187 | Settings.settings
188 | True
189 |
190 |
191 | PublicResXFileCodeGenerator
192 | Resources.ja-JP.Designer.cs
193 |
194 |
195 | PublicResXFileCodeGenerator
196 | Resources.ko-KR.Designer.cs
197 |
198 |
199 | PublicResXFileCodeGenerator
200 | Resources.zh-CN.Designer.cs
201 |
202 |
203 | PublicResXFileCodeGenerator
204 | Resources.Designer.cs
205 |
206 |
207 |
208 | SettingsSingleFileGenerator
209 | Settings.Designer.cs
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 | Always
219 |
220 |
221 | Always
222 |
223 |
224 |
225 | Always
226 |
227 |
228 | Always
229 |
230 |
231 | Always
232 |
233 |
234 |
235 |
236 |
--------------------------------------------------------------------------------
/FastbootEnhance.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31321.278
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastbootEnhance", "FastbootEnhance.csproj", "{7CB79897-F766-40AA-AEC8-F8A5C7B9E26E}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {7CB79897-F766-40AA-AEC8-F8A5C7B9E26E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {7CB79897-F766-40AA-AEC8-F8A5C7B9E26E}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {7CB79897-F766-40AA-AEC8-F8A5C7B9E26E}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {7CB79897-F766-40AA-AEC8-F8A5C7B9E26E}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {499BD847-56D1-471A-86CB-B4AC51082D20}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/FastbootUI.cs:
--------------------------------------------------------------------------------
1 | using ChromeosUpdateEngine;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Threading;
6 | using System.Windows;
7 |
8 | namespace FastbootEnhance
9 | {
10 | class FastbootUI
11 | {
12 | public const string PAYLOAD_TMP = ".\\payload.tmp.fastboot";
13 | static List devices;
14 | static string cur_serial;
15 | static FastbootData fastbootData;
16 |
17 | static Logger logger;
18 | static void appendLog(string logs)
19 | {
20 | if (logger == null)
21 | return;
22 |
23 | logger.appendLog(logs);
24 | }
25 |
26 | enum FastbootStatus
27 | {
28 | show_devices,
29 | show_actions
30 | }
31 |
32 | static FastbootStatus cur_status;
33 | static void refreshDeviceList()
34 | {
35 | MainWindow.THIS.Dispatcher.Invoke(new Action(delegate
36 | {
37 | MainWindow.THIS.fastboot_devices_list.Items.Clear();
38 | foreach (fastboot_devices_row row in devices)
39 | {
40 | MainWindow.THIS.fastboot_devices_list.Items.Add(row);
41 | }
42 | }));
43 | }
44 |
45 | static bool checkCurDevExist()
46 | {
47 | using (Fastboot fastboot = new Fastboot(null, "devices"))
48 | {
49 | while (true)
50 | {
51 | string line = fastboot.stdout.ReadLine();
52 | if (line == null)
53 | break;
54 |
55 | string[] param = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
56 | if (cur_serial == param[0])
57 | return true;
58 | }
59 | MessageBox.Show(Properties.Resources.fastboot_device_not_exist);
60 | cur_status = FastbootStatus.show_devices;
61 | change_page();
62 | return false;
63 | }
64 | }
65 |
66 | static void devicesListRefresher()
67 | {
68 | while (true)
69 | {
70 | Thread.Sleep(1000);
71 |
72 | if (cur_status == FastbootStatus.show_actions)
73 | continue;
74 |
75 | List tmp = new List();
76 |
77 | using (Fastboot fastboot = new Fastboot(null, "devices"))
78 | {
79 | while (true)
80 | {
81 | string line = fastboot.stdout.ReadLine();
82 | if (line == null)
83 | break;
84 |
85 | string[] param = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
86 | tmp.Add(new fastboot_devices_row(param[0], param[1]));
87 | }
88 | }
89 |
90 | if (tmp.Count != devices.Count)
91 | {
92 | devices = tmp;
93 | refreshDeviceList();
94 | }
95 | else
96 | {
97 | int i;
98 | for (i = 0; i < tmp.Count; i++)
99 | {
100 | if (devices[i].name != tmp[i].name || devices[i].serial != tmp[i].serial)
101 | break;
102 | }
103 | if (i != tmp.Count)
104 | {
105 | devices = tmp;
106 | refreshDeviceList();
107 | }
108 | }
109 | }
110 | }
111 |
112 | class fastboot_devices_row
113 | {
114 | public string serial { get; }
115 | public string name { get; }
116 | public fastboot_devices_row(string serial, string name)
117 | {
118 | this.serial = serial;
119 | this.name = name;
120 | }
121 | }
122 |
123 | class fastboot_info_row
124 | {
125 | public string name { get; }
126 | public string value { get; }
127 | public fastboot_info_row(string name, string value)
128 | {
129 | this.name = name;
130 | this.value = value;
131 | }
132 | }
133 |
134 | class fastboot_partition_row
135 | {
136 | public string name { get; }
137 | public string size { get; }
138 | public string is_logical { get; }
139 | public fastboot_partition_row(string name, string size, string is_logical)
140 | {
141 | this.name = name;
142 | this.size = size;
143 | this.is_logical = is_logical;
144 | }
145 | }
146 |
147 | static void action_lock()
148 | {
149 | MainWindow.THIS.fastboot_progress_bar.Value = 0;
150 | MainWindow.THIS.fastboot_action_bar.Visibility = Visibility.Hidden;
151 | MainWindow.THIS.fastboot_progress_bar.Visibility = Visibility.Visible;
152 | MainWindow.THIS.fastboot_progress_bar.IsIndeterminate = false;
153 | Helper.TaskbarItemHelper.start();
154 | MainWindow.THIS.fastboot_single_part_op.IsEnabled = false;
155 | MainWindow.THIS.fastboot_flash_payload.IsEnabled = false;
156 | }
157 |
158 | static void action_unlock()
159 | {
160 | MainWindow.THIS.fastboot_progress_bar.Visibility = Visibility.Hidden;
161 | MainWindow.THIS.fastboot_action_bar.Visibility = Visibility.Visible;
162 | Helper.TaskbarItemHelper.stop();
163 | MainWindow.THIS.fastboot_single_part_op.IsEnabled = true;
164 | MainWindow.THIS.fastboot_flash_payload.IsEnabled = true;
165 | }
166 |
167 | static Helper.ListHelper listHelper;
168 |
169 | static void load_fastboot_vars()
170 | {
171 | //reset
172 | fastbootData = null;
173 | listHelper.clear();
174 | MainWindow.THIS.fastboot_partition_name_textbox.Text = "";
175 | MainWindow.THIS.fastboot_info_list.Items.Clear();
176 | action_lock();
177 | MainWindow.THIS.fastboot_progress_bar.IsIndeterminate = true;
178 |
179 | new Thread(new ThreadStart(delegate
180 | {
181 | using (Fastboot fastboot = new Fastboot(cur_serial, "getvar all"))
182 | {
183 | // fastboot bug: Must read stderr first or stdout would be blocked
184 | fastbootData = new FastbootData(fastboot.stderr.ReadToEnd());
185 | }
186 |
187 | MainWindow.THIS.Dispatcher.Invoke(delegate
188 | {
189 | //Partition list init
190 |
191 | foreach (string key in fastbootData.partition_size.Keys)
192 | {
193 | long raw_size = fastbootData.partition_size[key];
194 | string size_str = raw_size >= 0 ? Helper.byte2AUnit((ulong)raw_size) : Properties.Resources.fastboot_0_size;
195 | bool? raw_logical = null;
196 | fastbootData.partition_is_logical.TryGetValue(key, out raw_logical);
197 | string logical_str = raw_logical != null && raw_logical == true ? Properties.Resources.yes : Properties.Resources.no;
198 | listHelper.addItem(new fastboot_partition_row(key, size_str, logical_str));
199 | }
200 | listHelper.render();
201 |
202 | //info list init
203 |
204 | MainWindow.THIS.fastboot_info_list.Items.Add(new fastboot_info_row(Properties.Resources.fastboot_device, fastbootData.product));
205 |
206 | MainWindow.THIS.fastboot_info_list.Items.Add(new fastboot_info_row(Properties.Resources.fastboot_secure_boot,
207 | fastbootData.secure ? Properties.Resources.enabled : Properties.Resources.disabled));
208 |
209 | MainWindow.THIS.fastboot_info_list.Items.Add(new fastboot_info_row(Properties.Resources.fastboot_seamless_update,
210 | fastbootData.current_slot != null ? Properties.Resources.yes : Properties.Resources.no));
211 |
212 | if (fastbootData.current_slot != null)
213 | MainWindow.THIS.fastboot_info_list.Items.Add(new fastboot_info_row(Properties.Resources.fastboot_current_slot,
214 | fastbootData.current_slot));
215 |
216 | MainWindow.THIS.fastboot_info_list.Items.Add(new fastboot_info_row(Properties.Resources.fastboot_is_userspace,
217 | fastbootData.fastbootd ? Properties.Resources.yes : Properties.Resources.no));
218 |
219 | string vab_status_str = null;
220 | switch (fastbootData.snapshot_update_status)
221 | {
222 | case "none":
223 | vab_status_str = Properties.Resources.fastboot_update_status_none;
224 | break;
225 | case "snapshotted":
226 | vab_status_str = Properties.Resources.fastboot_update_status_snapshotted;
227 | break;
228 | case "merging":
229 | vab_status_str = Properties.Resources.fastboot_update_status_merging;
230 | break;
231 | default:
232 | vab_status_str = fastbootData.snapshot_update_status;
233 | break;
234 | }
235 |
236 | if (vab_status_str != null)
237 | MainWindow.THIS.fastboot_info_list.Items.Add(new fastboot_info_row(Properties.Resources.fastboot_update_status,
238 | vab_status_str));
239 |
240 | //buttons init
241 |
242 | MainWindow.THIS.fastboot_logical_create.IsEnabled = fastbootData.fastbootd;
243 | MainWindow.THIS.fastboot_reboot_d.Content = fastbootData.fastbootd ?
244 | Properties.Resources.fastboot_reboot_bootloader : Properties.Resources.fastboot_reboot_fastbootd;
245 | if (fastbootData.current_slot != null)
246 | {
247 | MainWindow.THIS.fastboot_ab_switch.Visibility = Visibility.Visible;
248 | if (fastbootData.current_slot == "a")
249 | {
250 | MainWindow.THIS.fastboot_ab_switch.Content = Properties.Resources.fastboot_setactive_b;
251 | }
252 | else if (fastbootData.current_slot == "b")
253 | {
254 | MainWindow.THIS.fastboot_ab_switch.Content = Properties.Resources.fastboot_setactive_a;
255 | }
256 | }
257 | else
258 | {
259 | MainWindow.THIS.fastboot_ab_switch.Visibility = Visibility.Hidden;
260 | }
261 |
262 | //检测是否应出现"去除更新状态"按钮
263 | if (fastbootData.snapshot_update_status == "none")
264 | {
265 | MainWindow.THIS.fastboot_cancel_update.Visibility = Visibility.Hidden;
266 | }
267 |
268 | MainWindow.THIS.fastboot_progress_bar.IsIndeterminate = false;
269 | action_unlock();
270 | });
271 | })).Start();
272 | }
273 |
274 | static void change_page()
275 | {
276 | switch (cur_status)
277 | {
278 | case FastbootStatus.show_devices:
279 | MainWindow.THIS.fastboot_actions_page.Visibility = Visibility.Hidden;
280 | MainWindow.THIS.fastboot_devices_page.Visibility = Visibility.Visible;
281 | break;
282 | case FastbootStatus.show_actions:
283 | load_fastboot_vars();
284 | MainWindow.THIS.fastboot_devices_page.Visibility = Visibility.Hidden;
285 | MainWindow.THIS.fastboot_actions_page.Visibility = Visibility.Visible;
286 | break;
287 | }
288 | }
289 |
290 | class StepCmdRunnerParam
291 | {
292 | public string cmd;
293 | public int step_count;
294 | public bool show_dialog_on_done;
295 | public bool skip_var_refresh;
296 | public StepCmdRunnerParam(string cmd, int step_count, bool hint_on_done, bool skip_var_refresh = false)
297 | {
298 | this.cmd = cmd;
299 | this.step_count = step_count;
300 | this.show_dialog_on_done = hint_on_done;
301 | this.skip_var_refresh = skip_var_refresh;
302 | }
303 | }
304 |
305 | static void step_cmd_runner_err(object raw_param)
306 | {
307 | StepCmdRunnerParam param = (StepCmdRunnerParam)raw_param;
308 |
309 | MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
310 | {
311 | action_lock();
312 | if (param.step_count <= 0)
313 | MainWindow.THIS.fastboot_progress_bar.IsIndeterminate = true;
314 | }));
315 |
316 | using (Fastboot fastboot = new Fastboot(cur_serial, param.cmd))
317 | {
318 | int count = 0;
319 | while (true)
320 | {
321 | string err = fastboot.stderr.ReadLine();
322 |
323 | if (err == null)
324 | break;
325 |
326 | appendLog(err);
327 |
328 | if (param.step_count > 0)
329 | MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
330 | {
331 | MainWindow.THIS.fastboot_progress_bar.Value = ++count * 100 / param.step_count;
332 | Helper.TaskbarItemHelper.update(count * 100 / param.step_count);
333 | }));
334 | }
335 | }
336 |
337 | MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
338 | {
339 | if (!param.skip_var_refresh)
340 | load_fastboot_vars();
341 | if (param.show_dialog_on_done)
342 | MessageBox.Show(Properties.Resources.operation_completed);
343 | }));
344 | }
345 |
346 | static bool singlePartitionCheck()
347 | {
348 | if (MainWindow.THIS.fastboot_partition_list.SelectedItems.Count == 0)
349 | {
350 | MessageBox.Show(Properties.Resources.fastboot_target_partition_not_selected);
351 | return true;
352 | }
353 |
354 | if (MainWindow.THIS.fastboot_partition_list.SelectedItems.Count > 1)
355 | {
356 | MessageBox.Show(Properties.Resources.fastboot_not_support_multiselect);
357 | return true;
358 | }
359 |
360 | return false;
361 | }
362 |
363 | static bool logicalCheck()
364 | {
365 | bool? ret = null;
366 | fastbootData.partition_is_logical.TryGetValue(
367 | ((fastboot_partition_row)
368 | MainWindow.THIS.fastboot_partition_list.SelectedItem).name, out ret);
369 | if (ret == null || ret == false)
370 | {
371 | MessageBox.Show(Properties.Resources.fastboot_only_logical);
372 | return true;
373 | }
374 |
375 | return false;
376 | }
377 |
378 | static bool vabStagingCheck()
379 | {
380 | if (fastbootData.snapshot_update_status != null
381 | && fastbootData.snapshot_update_status != "none")
382 | {
383 | System.Windows.Forms.DialogResult result =
384 | System.Windows.Forms.MessageBox.Show(
385 | Properties.Resources.fastboot_vab_staging_str1 + "\n" +
386 | Properties.Resources.fastboot_vab_staging_str2 + "\n" +
387 | Properties.Resources.fastboot_vab_staging_str3
388 | , Properties.Resources.fastboot_vab_staging_str0,
389 | System.Windows.Forms.MessageBoxButtons.YesNo,
390 | System.Windows.Forms.MessageBoxIcon.Question);
391 |
392 | if (result != System.Windows.Forms.DialogResult.Yes)
393 | {
394 | return true;
395 | }
396 | }
397 |
398 | bool cow_exist = false;
399 | foreach (string key in fastbootData.partition_size.Keys)
400 | {
401 | if (key.EndsWith("cow"))
402 | {
403 | cow_exist = true;
404 | break;
405 | }
406 | }
407 |
408 | if (cow_exist)
409 | {
410 | System.Windows.Forms.DialogResult result =
411 | System.Windows.Forms.MessageBox.Show(
412 | Properties.Resources.fastboot_cow_exist_str1 + "\n" +
413 | Properties.Resources.fastboot_cow_exist_str2 + "\n" +
414 | Properties.Resources.fastboot_cow_exist_str3
415 | , Properties.Resources.fastboot_cow_exist_str0,
416 | System.Windows.Forms.MessageBoxButtons.YesNo,
417 | System.Windows.Forms.MessageBoxIcon.Question);
418 |
419 | if (result != System.Windows.Forms.DialogResult.Yes)
420 | {
421 | return true;
422 | }
423 | }
424 |
425 | return false;
426 | }
427 |
428 | public static void init()
429 | {
430 | devices = new List();
431 | cur_status = FastbootStatus.show_devices;
432 | change_page();
433 |
434 | new Thread(new ThreadStart(devicesListRefresher)).Start();
435 | MainWindow.THIS.fastboot_devices_list.MouseDoubleClick += delegate
436 | {
437 | if (MainWindow.THIS.fastboot_devices_list.SelectedItems.Count == 0)
438 | return;
439 |
440 | if (MainWindow.THIS.fastboot_devices_list.SelectedItems.Count > 1)
441 | {
442 | MainWindow.THIS.fastboot_devices_list.SelectedItems.Clear();
443 | return;
444 | }
445 |
446 | fastboot_devices_row cur = (fastboot_devices_row)MainWindow.THIS.fastboot_devices_list.SelectedItem;
447 | cur_serial = cur.serial;
448 | if (!checkCurDevExist())
449 | return;
450 | cur_status = FastbootStatus.show_actions;
451 | MainWindow.THIS.fastboot_cur_device.Content = Properties.Resources.fastboot_current_device + cur.serial;
452 | change_page();
453 | };
454 |
455 | MainWindow.THIS.fastboot_remove.Click += delegate
456 | {
457 | cur_serial = null;
458 | cur_status = FastbootStatus.show_devices;
459 | change_page();
460 | };
461 |
462 | MainWindow.THIS.fastboot_reboot_d.Click += delegate
463 | {
464 | if (!checkCurDevExist())
465 | return;
466 |
467 | if (fastbootData.fastbootd)
468 | {
469 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
470 | .Start(new StepCmdRunnerParam("reboot bootloader", 2, false));
471 | }
472 | else
473 | {
474 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
475 | .Start(new StepCmdRunnerParam("reboot fastboot", 3, false));
476 | }
477 | };
478 |
479 | MainWindow.THIS.fastboot_reboot_system.Click += delegate
480 | {
481 | if (!checkCurDevExist())
482 | return;
483 |
484 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
485 | .Start(new StepCmdRunnerParam("reboot", 0, false, true));
486 |
487 | cur_serial = null;
488 | cur_status = FastbootStatus.show_devices;
489 | change_page();
490 | };
491 |
492 | MainWindow.THIS.fastboot_reboot_recovery.Click += delegate
493 | {
494 | if (!checkCurDevExist())
495 | return;
496 |
497 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
498 | .Start(new StepCmdRunnerParam("reboot recovery", 0, false, true));
499 |
500 | cur_serial = null;
501 | cur_status = FastbootStatus.show_devices;
502 | change_page();
503 | };
504 |
505 | MainWindow.THIS.fastboot_ab_switch.Click += delegate
506 | {
507 | if (!checkCurDevExist())
508 | return;
509 |
510 | if (fastbootData.current_slot == "a")
511 | {
512 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
513 | .Start(new StepCmdRunnerParam("set_active b", 2, false));
514 | }
515 | else if (fastbootData.current_slot == "b")
516 | {
517 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
518 | .Start(new StepCmdRunnerParam("set_active a", 2, false));
519 | }
520 | else
521 | {
522 | MessageBox.Show(Properties.Resources.operation_not_supported);
523 | }
524 | };
525 |
526 | //监听"去除更新状态"按钮
527 | MainWindow.THIS.fastboot_cancel_update.Click += delegate
528 | {
529 | if (!checkCurDevExist())
530 | return;
531 |
532 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
533 | .Start(new StepCmdRunnerParam("snapshot-update cancel", 2, true));
534 | };
535 |
536 | MainWindow.THIS.fastboot_flash.Click += delegate
537 | {
538 | if (!checkCurDevExist())
539 | return;
540 |
541 | if (singlePartitionCheck())
542 | return;
543 |
544 | if (vabStagingCheck())
545 | return;
546 |
547 | string target = ((fastboot_partition_row)MainWindow.THIS.fastboot_partition_list.SelectedItem).name;
548 |
549 | Helper.fileSelect(new Helper.PathSelectCallback(delegate (string path)
550 | {
551 | string ext_arg = "";
552 |
553 | if (target == "vbmeta" || target == "vbmeta_" + fastbootData.current_slot
554 | || target == "vbmeta_a" || target == "vbmeta_b")
555 | {
556 | System.Windows.Forms.DialogResult result =
557 | System.Windows.Forms.MessageBox.Show(Properties.Resources.fastboot_vbmeta_disable_verify,
558 | Properties.Resources.fastboot_vbmeta_disable_verify_title,
559 | System.Windows.Forms.MessageBoxButtons.YesNo,
560 | System.Windows.Forms.MessageBoxIcon.Question);
561 |
562 | if (result == System.Windows.Forms.DialogResult.Yes)
563 | {
564 | ext_arg += "--disable-verity --disable-verification";
565 | }
566 | }
567 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
568 | .Start(new StepCmdRunnerParam("flash " + ext_arg + " \"" + target + "\" \"" + path + "\"", -1, true));
569 | }), "Image File|*.img;*.image");
570 | };
571 |
572 | MainWindow.THIS.fastboot_erase.Click += delegate
573 | {
574 | if (singlePartitionCheck())
575 | return;
576 |
577 | string target = ((fastboot_partition_row)MainWindow.THIS.fastboot_partition_list.SelectedItem).name;
578 |
579 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
580 | .Start(new StepCmdRunnerParam("erase \"" + target + "\"", 2, false));
581 | };
582 |
583 | MainWindow.THIS.fastboot_partition_list.SelectionChanged += delegate
584 | {
585 | MainWindow.THIS.fastboot_flash.IsEnabled = true;
586 | MainWindow.THIS.fastboot_erase.IsEnabled = true;
587 | MainWindow.THIS.fastboot_logical_delete.IsEnabled = true;
588 | MainWindow.THIS.fastboot_logical_resize.IsEnabled = true;
589 |
590 | if (MainWindow.THIS.fastboot_partition_list.SelectedItems.Count > 1)
591 | {
592 | MainWindow.THIS.fastboot_flash.IsEnabled = false;
593 | MainWindow.THIS.fastboot_erase.IsEnabled = false;
594 | MainWindow.THIS.fastboot_logical_delete.IsEnabled = false;
595 | MainWindow.THIS.fastboot_logical_resize.IsEnabled = false;
596 | return;
597 | }
598 |
599 | if (fastbootData == null)
600 | return;
601 |
602 | if (!fastbootData.fastbootd)
603 | {
604 | MainWindow.THIS.fastboot_logical_delete.IsEnabled = false;
605 | MainWindow.THIS.fastboot_logical_resize.IsEnabled = false;
606 | return;
607 | }
608 |
609 | bool? ret = null;
610 |
611 | if (MainWindow.THIS.fastboot_partition_list.SelectedItem == null)
612 | {
613 | MainWindow.THIS.fastboot_logical_delete.IsEnabled = true;
614 | MainWindow.THIS.fastboot_logical_resize.IsEnabled = true;
615 | return;
616 | }
617 | fastbootData.partition_is_logical.TryGetValue(
618 | ((fastboot_partition_row)
619 | MainWindow.THIS.fastboot_partition_list.SelectedItem).name, out ret);
620 | if (ret == null || ret == false)
621 | {
622 | MainWindow.THIS.fastboot_logical_delete.IsEnabled = false;
623 | MainWindow.THIS.fastboot_logical_resize.IsEnabled = false;
624 | }
625 | };
626 |
627 | MainWindow.THIS.fastboot_logical_delete.Click += delegate
628 | {
629 | if (!checkCurDevExist())
630 | return;
631 |
632 | if (singlePartitionCheck() || logicalCheck())
633 | return;
634 |
635 | string target = ((fastboot_partition_row)MainWindow.THIS.fastboot_partition_list.SelectedItem).name;
636 |
637 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
638 | .Start(new StepCmdRunnerParam("delete-logical-partition \"" + target + "\"", 2, false));
639 | };
640 |
641 | MainWindow.THIS.fastboot_logical_create.Click += delegate
642 | {
643 | if (!checkCurDevExist())
644 | return;
645 |
646 | new FastbootActionWindow(FastbootActionWindow.StartType.CREATE, "", 0,
647 | delegate (string name, ulong size)
648 | {
649 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
650 | .Start(new StepCmdRunnerParam(
651 | "create-logical-partition \"" + name + "\" \"" + size.ToString() + "\"", 2, false));
652 | }).ShowDialog();
653 | };
654 |
655 | MainWindow.THIS.fastboot_logical_resize.Click += delegate
656 | {
657 | if (!checkCurDevExist())
658 | return;
659 |
660 | if (singlePartitionCheck() || logicalCheck())
661 | return;
662 |
663 | string target = ((fastboot_partition_row)MainWindow.THIS.fastboot_partition_list.SelectedItem).name;
664 |
665 | new FastbootActionWindow(FastbootActionWindow.StartType.RESIZE, target,
666 | fastbootData.partition_size[target],
667 | delegate (string name, ulong size)
668 | {
669 | new Thread(new ParameterizedThreadStart(step_cmd_runner_err))
670 | .Start(new StepCmdRunnerParam(
671 | "resize-logical-partition \"" + name + "\" \"" + size.ToString() + "\"", 2, false));
672 | }).ShowDialog();
673 | };
674 |
675 | MainWindow.THIS.fastboot_flash_payload.Click += delegate
676 | {
677 | if (!checkCurDevExist())
678 | return;
679 |
680 | if (vabStagingCheck())
681 | return;
682 |
683 | Helper.fileSelect(new Helper.PathSelectCallback(delegate (string path)
684 | {
685 | Payload payload = null;
686 | Exception exception = null;
687 |
688 | Action beforeLoad = new Action(delegate
689 | {
690 | try
691 | {
692 | payload = new Payload(path, PAYLOAD_TMP);
693 | }
694 | catch (Exception e)
695 | {
696 | exception = e;
697 | }
698 | });
699 |
700 | Action afterLoad = new Action(delegate
701 | {
702 | action_unlock();
703 | MainWindow.THIS.fastboot_progress_bar.IsIndeterminate = false;
704 |
705 | if (exception != null)
706 | {
707 | MessageBox.Show(exception.Message);
708 | return;
709 | }
710 | Payload.PayloadInitException exc = payload.init();
711 | if (exc != null)
712 | {
713 | payload.Dispose();
714 | payload = null;
715 | MessageBox.Show(Properties.Resources.payload_unsupported_format + "\n" + exc.Message);
716 | return;
717 | }
718 |
719 | //Ensure that all partitions are there
720 | string unknown_partition_list = "";
721 | foreach (PartitionUpdate partitionUpdate in payload.manifest.Partitions)
722 | {
723 | long size;
724 | if (MainWindow.THIS.ignore_unknown_part.IsChecked == false
725 | && !fastbootData.partition_size.TryGetValue(partitionUpdate.PartitionName, out size)
726 | && !fastbootData.partition_size.TryGetValue(partitionUpdate.PartitionName + "_" + fastbootData.current_slot, out size))
727 | {
728 | unknown_partition_list += partitionUpdate.PartitionName + " ";
729 | }
730 | }
731 |
732 | if (unknown_partition_list != "")
733 | {
734 | string message_append = fastbootData.fastbootd ?
735 | "\n" + Properties.Resources.fastboot_unknown_partition_str1 : "\n" + Properties.Resources.fastboot_unknown_partition_str2;
736 | MessageBox.Show(Properties.Resources.fastboot_unknown_partition_str0 + "\n" + unknown_partition_list + message_append);
737 | payload.Dispose();
738 | return;
739 | }
740 |
741 | Directory.CreateDirectory(PAYLOAD_TMP);
742 |
743 | action_lock();
744 | new Thread(new ThreadStart(delegate
745 | {
746 | int count_full = payload.manifest.Partitions.Count * 2;
747 | int count = 0;
748 | foreach (PartitionUpdate partitionUpdate in payload.manifest.Partitions)
749 | {
750 | appendLog("Extracting " + partitionUpdate.PartitionName);
751 | Payload.PayloadExtractionException e = payload.extract(partitionUpdate.PartitionName,
752 | PAYLOAD_TMP, false, false);
753 |
754 | if (e != null)
755 | {
756 | MessageBox.Show(e.Message);
757 | MainWindow.THIS.Dispatcher.Invoke(new Action(delegate
758 | {
759 | action_unlock();
760 | }));
761 | payload.Dispose();
762 | return;
763 | }
764 |
765 | appendLog("Extracted " + partitionUpdate.PartitionName);
766 |
767 | MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
768 | {
769 | MainWindow.THIS.fastboot_progress_bar.Value = 100 * ++count / count_full;
770 | Helper.TaskbarItemHelper.update(100 * count / count_full);
771 | }));
772 | }
773 |
774 | foreach (PartitionUpdate partitionUpdate in payload.manifest.Partitions)
775 | {
776 | using (Fastboot fastboot = new Fastboot
777 | (cur_serial, "flash \"" + partitionUpdate.PartitionName + "\" \"" + PAYLOAD_TMP + "\\" + partitionUpdate.PartitionName + ".img\""))
778 | {
779 | while (true)
780 | {
781 | string err = fastboot.stderr.ReadLine();
782 |
783 | if (err == null)
784 | break;
785 |
786 | appendLog(err);
787 | }
788 |
789 | MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
790 | {
791 | MainWindow.THIS.fastboot_progress_bar.Value = 100 * ++count / count_full;
792 | Helper.TaskbarItemHelper.update(100 * count / count_full);
793 | }));
794 | }
795 | }
796 |
797 | MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
798 | {
799 | load_fastboot_vars();
800 | MessageBox.Show(Properties.Resources.operation_completed);
801 | }));
802 |
803 | payload.Dispose();
804 | })).Start();
805 | });
806 | action_lock();
807 | MainWindow.THIS.fastboot_progress_bar.IsIndeterminate = true;
808 | Helper.offloadAndRun(beforeLoad, afterLoad);
809 | }), "Payload|*.bin;*.zip");
810 | };
811 |
812 | listHelper = new Helper.ListHelper(MainWindow.THIS.fastboot_partition_list,
813 | new Helper.ListHelper.Filter(delegate (fastboot_partition_row row)
814 | {
815 | if (MainWindow.THIS.fastboot_partition_name_textbox.Text == "")
816 | return true;
817 |
818 | if (row.name.Contains(MainWindow.THIS.fastboot_partition_name_textbox.Text))
819 | return true;
820 | return false;
821 | }));
822 |
823 | MainWindow.THIS.fastboot_partition_name_textbox.TextChanged += delegate
824 | {
825 | listHelper.doFilter();
826 | };
827 |
828 | MainWindow.THIS.fastboot_show_logs.Click += delegate
829 | {
830 | if ((bool)MainWindow.THIS.fastboot_show_logs.IsChecked)
831 | {
832 | logger = new Logger(new Action(delegate
833 | {
834 | logger = null;
835 | MainWindow.THIS.fastboot_show_logs.IsChecked = false;
836 | }));
837 | logger.Show();
838 | }
839 | else
840 | {
841 | logger.Close();
842 | }
843 | };
844 | }
845 | }
846 | }
847 |
--------------------------------------------------------------------------------
/Helper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 | using System.Windows.Controls;
5 |
6 | namespace FastbootEnhance
7 | {
8 | class Helper
9 | {
10 |
11 | public class TaskbarItemHelper
12 | {
13 | public static void start()
14 | {
15 | MainWindow.THIS.taskbariteminfo.ProgressValue = 0;
16 | MainWindow.THIS.taskbariteminfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;
17 | }
18 |
19 | public static void stop()
20 | {
21 | MainWindow.THIS.taskbariteminfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
22 | }
23 |
24 | public static void update(int percent)
25 | {
26 | MainWindow.THIS.taskbariteminfo.ProgressValue = percent / 100.0;
27 | }
28 | }
29 |
30 | public static void offloadAndRun(Action bigtask, Action callbackOnUIThread)
31 | {
32 | new Thread(new ThreadStart(delegate
33 | {
34 | bigtask();
35 | MainWindow.THIS.Dispatcher.Invoke(callbackOnUIThread);
36 | })).Start();
37 | }
38 | public class ListHelper
39 | {
40 | public delegate bool Filter(T t);
41 |
42 | ListView listView;
43 | List items;
44 | Filter filter;
45 |
46 | public ListHelper(ListView listView, Filter filter)
47 | {
48 | this.listView = listView;
49 | items = new List();
50 | this.filter = filter;
51 | }
52 |
53 | public void clear()
54 | {
55 | listView.SelectedItems.Clear();
56 | listView.Items.Clear();
57 | items = new List();
58 | }
59 |
60 | public void addItem(T item)
61 | {
62 | items.Add(item);
63 | }
64 |
65 | public void render()
66 | {
67 | listView.Items.Clear();
68 | foreach (T t in items)
69 | {
70 | listView.Items.Add(t);
71 | }
72 | }
73 |
74 | public void doFilter()
75 | {
76 | listView.Items.Clear();
77 | foreach (T t in items)
78 | {
79 | if (filter(t))
80 | listView.Items.Add(t);
81 | }
82 | }
83 | }
84 |
85 | public delegate void PathSelectCallback(string path);
86 | public static void fileSelect(PathSelectCallback callback, string filter = "All Files|*.*")
87 | {
88 | System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog();
89 | openFileDialog.Filter = filter;
90 | if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
91 | {
92 | callback(openFileDialog.FileName);
93 | }
94 | }
95 |
96 | public static void pathSelect(PathSelectCallback callback)
97 | {
98 | System.Windows.Forms.FolderBrowserDialog folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
99 | folderBrowserDialog.Description = Properties.Resources.select_save_path;
100 |
101 | if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
102 | {
103 | callback(folderBrowserDialog.SelectedPath);
104 | }
105 | }
106 |
107 | public static DateTime timeStamp2DataTime(Int64 timestamp)
108 | {
109 | Int64 begtime = timestamp * 10000000;
110 | DateTime dt_1970 = new DateTime(1970, 1, 1, 8, 0, 0);
111 | long tricks_1970 = dt_1970.Ticks;
112 | long time_tricks = tricks_1970 + begtime;
113 | DateTime dt = new DateTime(time_tricks);
114 | return dt;
115 | }
116 |
117 | public static string byte2AUnit(ulong size)
118 | {
119 | if (size > 1024 * 1024 * 1024)
120 | return (int)((double)size / 1024 / 1024 / 1024 * 100) / 100.0 + " GB";
121 |
122 | if (size > 1024 * 1024)
123 | return (int)((double)size / 1024 / 1024 * 100) / 100.0 + " MB";
124 |
125 | if (size > 1024)
126 | return (int)((double)size / 1024 * 100) / 100.0 + " KB";
127 |
128 | return size + " B";
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 LibXZR
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Logger.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Logger.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 |
4 | namespace FastbootEnhance
5 | {
6 | ///
7 | /// Logger.xaml 的交互逻辑
8 | ///
9 | public partial class Logger : Window
10 | {
11 | public Logger()
12 | {
13 | InitializeComponent();
14 | }
15 |
16 | public Logger(Action onClose)
17 | {
18 | InitializeComponent();
19 | Closed += (a, b) => onClose();
20 | }
21 |
22 | public void appendLog(string logs)
23 | {
24 | Dispatcher.Invoke(new Action(delegate
25 | {
26 | log.Text += logs + "\n";
27 | scroller.ScrollToEnd();
28 | }));
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
283 |
284 |
285 |
286 |
287 |
288 |
--------------------------------------------------------------------------------
/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.IO;
3 | using System.Threading;
4 | using System.Windows;
5 |
6 | namespace FastbootEnhance
7 | {
8 | ///
9 | /// MainWindow.xaml 的交互逻辑
10 | ///
11 | public partial class MainWindow : Window
12 | {
13 | public static MainWindow THIS;
14 | const string version = "1.4.0";
15 | public MainWindow()
16 | {
17 | InitializeComponent();
18 | THIS = this;
19 |
20 | string mutexName = "FastbootEnhance";
21 | bool createdNew;
22 | Mutex singleInstanceWatcher = new Mutex(false, mutexName, out createdNew);
23 | if (!createdNew)
24 | {
25 | MessageBox.Show(Properties.Resources.program_already_running, Properties.Resources.error, MessageBoxButton.OK, MessageBoxImage.Error);
26 | Process.GetCurrentProcess().Kill();
27 | }
28 |
29 | try
30 | {
31 | new DirectoryInfo(PayloadUI.PAYLOAD_TMP).Delete(true);
32 | }
33 | catch (DirectoryNotFoundException) { }
34 |
35 | try
36 | {
37 | new DirectoryInfo(FastbootUI.PAYLOAD_TMP).Delete(true);
38 | }
39 | catch (DirectoryNotFoundException) { }
40 |
41 | PayloadUI.init();
42 | FastbootUI.init();
43 |
44 | Title += " v" + version;
45 |
46 | Closed += delegate
47 | {
48 | if (PayloadUI.payload != null)
49 | PayloadUI.payload.Dispose();
50 |
51 | try
52 | {
53 | new DirectoryInfo(PayloadUI.PAYLOAD_TMP).Delete(true);
54 | }
55 | catch (DirectoryNotFoundException) { }
56 | catch (IOException) { }
57 |
58 | try
59 | {
60 | new DirectoryInfo(FastbootUI.PAYLOAD_TMP).Delete(true);
61 | }
62 | catch (DirectoryNotFoundException) { }
63 | catch (IOException) { }
64 |
65 | Process.GetCurrentProcess().Kill();
66 | };
67 | }
68 |
69 | private void Thread_Click(object sender, RoutedEventArgs e)
70 | {
71 | Process.Start("https://www.akr-developers.com/d/506");
72 | }
73 |
74 | private void OSS_Click(object sender, RoutedEventArgs e)
75 | {
76 | Process.Start("https://github.com/libxzr/FastbootEnhance");
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Payload.cs:
--------------------------------------------------------------------------------
1 | using ChromeosUpdateEngine;
2 | using Google.Protobuf;
3 | using Ionic.Zip;
4 | using System;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Security.Cryptography;
8 | using System.Text;
9 |
10 | namespace FastbootEnhance
11 | {
12 | public class Payload : IDisposable
13 | {
14 | string payload_tmp;
15 | BinaryReader binaryReader;
16 | public class PayloadInitException : Exception
17 | {
18 | public PayloadInitException(string message) : base(message) { }
19 | };
20 | public class PayloadExtractionException : Exception
21 | {
22 | public PayloadExtractionException(string message) : base(message) { }
23 | };
24 |
25 | const string magic = "CrAU";
26 | public UInt64 file_format_version;
27 | public UInt64 manifest_size;
28 | public UInt32 metadata_signature_size;
29 | public DeltaArchiveManifest manifest;
30 | public Signatures metadata_signature_message;
31 | //{data blocks}
32 | public UInt64 payload_signatures_message_size;
33 | public Signatures payload_signatures_message;
34 |
35 | long data_start;
36 | public ulong data_size;
37 |
38 | public PayloadExtractionException extract(string which, string path,
39 | bool ignore_unknown_op, bool ignore_checks)
40 | {
41 | SHA256Managed Sha256 = new SHA256Managed();
42 |
43 | foreach (PartitionUpdate partitionUpdate in manifest.Partitions)
44 | {
45 | if (partitionUpdate.PartitionName != which)
46 | continue;
47 |
48 | using (FileStream fileStream = new FileStream(path + "\\" + which + ".img", FileMode.Create))
49 | {
50 | foreach (InstallOperation installOperation in partitionUpdate.Operations)
51 | {
52 | binaryReader.BaseStream.Seek(data_start + (long)installOperation.DataOffset, SeekOrigin.Begin);
53 | byte[] raw_data = binaryReader.ReadBytes((int)installOperation.DataLength);
54 | if (!ignore_checks && installOperation.HasDataSha256Hash &&
55 | installOperation.DataSha256Hash.ToBase64() != Convert.ToBase64String(Sha256.ComputeHash(raw_data)))
56 | return new PayloadExtractionException("Block hash check failed");
57 |
58 | if (installOperation.DstExtents == null)
59 | return new PayloadExtractionException("No dst");
60 |
61 | if (installOperation.DstExtents.Count > 1)
62 | return new PayloadExtractionException("Multiple dst in one operation");
63 |
64 | long dst_start = (long)installOperation.DstExtents[0].StartBlock * manifest.BlockSize;
65 | long dst_length = (long)installOperation.DstExtents[0].NumBlocks * manifest.BlockSize;
66 |
67 | fileStream.Seek(dst_start, SeekOrigin.Begin);
68 |
69 | using (MemoryStream raw_data_stream = new MemoryStream(raw_data))
70 | {
71 | switch (installOperation.Type)
72 | {
73 | case InstallOperation.Types.Type.Replace:
74 | if (ignore_checks || (long)installOperation.DataLength == dst_length)
75 | raw_data_stream.CopyTo(fileStream);
76 | else
77 | return new PayloadExtractionException("REPLACE: Block size mismatch");
78 | break;
79 | case InstallOperation.Types.Type.ReplaceBz:
80 | using (MemoryStream buf = new MemoryStream())
81 | {
82 | using (Ionic.BZip2.BZip2InputStream bZip = new Ionic.BZip2.BZip2InputStream(raw_data_stream))
83 | {
84 | bZip.CopyTo(buf);
85 | }
86 |
87 | if (ignore_checks || buf.Length == dst_length)
88 | {
89 | buf.Seek(0, SeekOrigin.Begin);
90 | buf.CopyTo(fileStream);
91 | }
92 | else
93 | return new PayloadExtractionException("BZ: Block size mismatch");
94 | }
95 | break;
96 | case InstallOperation.Types.Type.ReplaceXz:
97 | using (MemoryStream buf = new MemoryStream())
98 | {
99 | using (XZ.NET.XZInputStream xZ = new XZ.NET.XZInputStream(raw_data_stream))
100 | {
101 | xZ.CopyTo(buf);
102 | }
103 |
104 | if (ignore_checks || buf.Length == dst_length)
105 | {
106 | buf.Seek(0, SeekOrigin.Begin);
107 | buf.CopyTo(fileStream);
108 | }
109 | else
110 | return new PayloadExtractionException("XZ: Block size mismatch");
111 | }
112 | break;
113 | case InstallOperation.Types.Type.Zero:
114 | long i = dst_length;
115 | while (i-- != 0)
116 | fileStream.WriteByte(0);
117 | break;
118 | default:
119 | if (!ignore_unknown_op)
120 | return new PayloadExtractionException("Unknown action type " + installOperation.Type.ToString());
121 | break;
122 | }
123 | }
124 | }
125 |
126 | fileStream.Seek(0, SeekOrigin.Begin);
127 | if (!ignore_checks && partitionUpdate.NewPartitionInfo != null &&
128 | (fileStream.Length != (long)partitionUpdate.NewPartitionInfo.Size
129 | || (partitionUpdate.NewPartitionInfo.HasHash &&
130 | Convert.ToBase64String(Sha256.ComputeHash(fileStream)) != partitionUpdate.NewPartitionInfo.Hash.ToBase64())))
131 | return new PayloadExtractionException("Final image check failed");
132 | }
133 |
134 | return null;
135 | }
136 |
137 | return new PayloadExtractionException("Unable to find target");
138 | }
139 | public PayloadInitException init()
140 | {
141 | try
142 | {
143 | if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != magic)
144 | return new PayloadInitException("Magic mismatch");
145 |
146 | file_format_version = BitConverter.ToUInt64(binaryReader.ReadBytes(8).Reverse().ToArray(), 0);
147 |
148 | if (file_format_version < 2)
149 | return new PayloadInitException("format version 1 is not supported");
150 |
151 | manifest_size = BitConverter.ToUInt64(binaryReader.ReadBytes(8).Reverse().ToArray(), 0);
152 | metadata_signature_size = BitConverter.ToUInt32(binaryReader.ReadBytes(4).Reverse().ToArray(), 0);
153 |
154 | if (manifest_size > Int32.MaxValue)
155 | return new PayloadInitException("manifest_size overflowed");
156 |
157 | manifest = new MessageParser(delegate { return new DeltaArchiveManifest(); })
158 | .ParseFrom(binaryReader.ReadBytes((int)manifest_size));
159 |
160 | if (metadata_signature_size > Int32.MaxValue)
161 | return new PayloadInitException("metadata_signature_size overflowed");
162 |
163 | metadata_signature_message = new MessageParser(delegate { return new Signatures(); })
164 | .ParseFrom(binaryReader.ReadBytes((int)metadata_signature_size));
165 |
166 | data_start = binaryReader.BaseStream.Position;
167 | data_size = manifest.SignaturesOffset;
168 |
169 | binaryReader.BaseStream.Seek((long)manifest.SignaturesOffset, SeekOrigin.Current);
170 | payload_signatures_message_size = manifest.SignaturesSize;
171 | if (payload_signatures_message_size > Int32.MaxValue)
172 | return new PayloadInitException("payload_signatures_message_size overflowed");
173 | payload_signatures_message = new MessageParser(delegate { return new Signatures(); })
174 | .ParseFrom(binaryReader.ReadBytes((int)payload_signatures_message_size));
175 |
176 | }
177 | catch (Exception e)
178 | {
179 | return new PayloadInitException(e.Message);
180 | }
181 |
182 | return null;
183 | }
184 |
185 | public void Dispose()
186 | {
187 | if (binaryReader != null)
188 | {
189 | binaryReader.Close();
190 | binaryReader = null;
191 | }
192 | try
193 | {
194 | new DirectoryInfo(payload_tmp).Delete(true);
195 | }
196 | catch (DirectoryNotFoundException) { }
197 | catch (IOException) { }
198 | }
199 |
200 | public Payload(string path, String tmpdir)
201 | {
202 | payload_tmp = tmpdir;
203 |
204 | if (path.EndsWith(".zip"))
205 | {
206 | ZipFile zip = new ZipFile(path);
207 | foreach (ZipEntry entry in zip.Entries)
208 | {
209 | if (entry.FileName == "payload.bin")
210 | {
211 | entry.Extract(payload_tmp);
212 | binaryReader = new BinaryReader(
213 | new FileStream(payload_tmp + "\\payload.bin", FileMode.Open));
214 | return;
215 | }
216 | }
217 | throw new Exception("Unable to find entry for payload.bin");
218 | }
219 | binaryReader = new BinaryReader(new FileStream(path, FileMode.Open));
220 | }
221 |
222 | ~Payload()
223 | {
224 | Dispose();
225 | }
226 | }
227 | }
228 |
--------------------------------------------------------------------------------
/PayloadUI.cs:
--------------------------------------------------------------------------------
1 | using ChromeosUpdateEngine;
2 | using System;
3 | using System.Threading;
4 | using System.Windows;
5 |
6 | namespace FastbootEnhance
7 | {
8 | class PayloadUI
9 | {
10 | public const string PAYLOAD_TMP = ".\\payload.tmp.dumper";
11 |
12 | enum page_status
13 | {
14 | empty,
15 | loaded
16 | }
17 |
18 | static page_status cur_status;
19 | public static Payload payload;
20 |
21 | static void switchMainView()
22 | {
23 | switch (cur_status)
24 | {
25 | case page_status.empty:
26 | MainWindow.THIS.payload_before_load.Visibility = Visibility.Visible;
27 | MainWindow.THIS.payload_after_load.Visibility = Visibility.Hidden;
28 | break;
29 | case page_status.loaded:
30 | MainWindow.THIS.payload_before_load.Visibility = Visibility.Hidden;
31 | MainWindow.THIS.payload_after_load.Visibility = Visibility.Visible;
32 | break;
33 | }
34 | }
35 |
36 | static void onLoad(string filename)
37 | {
38 | Exception exception = null;
39 |
40 | MainWindow.THIS.payload_load_btn.Visibility = Visibility.Hidden;
41 | MainWindow.THIS.payload_opening.Visibility = Visibility.Visible;
42 |
43 | Action load = new Action(delegate
44 | {
45 | try
46 | {
47 | payload = new Payload(filename, PAYLOAD_TMP);
48 | }
49 | catch (Exception e)
50 | {
51 | exception = e;
52 | }
53 | });
54 |
55 | Action afterLoad = new Action(delegate
56 | {
57 | MainWindow.THIS.payload_load_btn.Visibility = Visibility.Visible;
58 | MainWindow.THIS.payload_opening.Visibility = Visibility.Hidden;
59 |
60 | if (exception != null)
61 | {
62 | MessageBox.Show(exception.Message);
63 | return;
64 | }
65 |
66 | Payload.PayloadInitException exc = payload.init();
67 | if (exc != null)
68 | {
69 | payload.Dispose();
70 | payload = null;
71 | MessageBox.Show(Properties.Resources.payload_unsupported_format + "\n" + exc.Message);
72 | return;
73 | }
74 |
75 | cur_status = page_status.loaded;
76 | MainWindow.THIS.payload_cur_open.Content = Properties.Resources.payload_current_file + filename;
77 | refreshData();
78 | switchMainView();
79 | });
80 |
81 | Helper.offloadAndRun(load, afterLoad);
82 | }
83 |
84 | static void actionInit()
85 | {
86 | listHelper = new Helper.ListHelper(MainWindow.THIS.payload_partition_info,
87 | new Helper.ListHelper.Filter(
88 | delegate (payload_partition_info_row row)
89 | {
90 | if (MainWindow.THIS.payload_partition_name_textbox.Text == "")
91 | return true;
92 |
93 | if (row.name.Contains(MainWindow.THIS.payload_partition_name_textbox.Text))
94 | return true;
95 | return false;
96 | }
97 | ));
98 |
99 | MainWindow.THIS.payload_partition_name_textbox.TextChanged += delegate
100 | {
101 | listHelper.doFilter();
102 | };
103 |
104 | MainWindow.THIS.payload_load_btn.Click += delegate
105 | {
106 | Helper.fileSelect(new Helper.PathSelectCallback(delegate (string ret)
107 | {
108 | onLoad(ret);
109 | }), "Payload|*.bin;*.zip");
110 | };
111 |
112 | MainWindow.THIS.payload_remove.Click += delegate
113 | {
114 | payload.Dispose();
115 | payload = null;
116 | cur_status = page_status.empty;
117 | switchMainView();
118 | };
119 |
120 | MainWindow.THIS.payload_extract.Click += delegate
121 | {
122 | if (MainWindow.THIS.payload_partition_info.SelectedItems.Count == 0)
123 | {
124 | MessageBox.Show(Properties.Resources.payload_target_partition_not_selected);
125 | return;
126 | }
127 |
128 | if (payload.manifest.MinorVersion != 0 && !(bool)MainWindow.THIS.payload_ignore_delta.IsChecked)
129 | {
130 | MessageBox.Show(Properties.Resources.payload_incremental_warning);
131 | return;
132 | }
133 |
134 | bool ignore_unknown_op = (bool)MainWindow.THIS.payload_ignore_unknown_op.IsChecked;
135 | bool ignore_checks = (bool)MainWindow.THIS.payload_ignore_check.IsChecked;
136 |
137 | Helper.pathSelect(new Helper.PathSelectCallback(delegate (string path)
138 | {
139 | MainWindow.THIS.payload_progress.Visibility = Visibility.Visible;
140 | MainWindow.THIS.payload_action_bar.Visibility = Visibility.Hidden;
141 | Helper.TaskbarItemHelper.start();
142 | System.Collections.IList selected = MainWindow.THIS.payload_partition_info.SelectedItems;
143 | MainWindow.THIS.payload_extract.IsEnabled = false;
144 | MainWindow.THIS.payload_extract_options.IsEnabled = false;
145 |
146 | new Thread(new ThreadStart(delegate
147 | {
148 | int full = selected.Count * 2;
149 | int now = 0;
150 | Payload.PayloadExtractionException exc = null;
151 |
152 | foreach (payload_partition_info_row row in selected)
153 | {
154 | MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
155 | {
156 | MainWindow.THIS.payload_progress.Value = ++now * 100 / full;
157 | Helper.TaskbarItemHelper.update(now * 100 / full);
158 | }));
159 | exc = payload.extract(row.name, path, ignore_unknown_op, ignore_checks);
160 | if (exc != null)
161 | break;
162 | MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
163 | {
164 | MainWindow.THIS.payload_progress.Value = ++now * 100 / full;
165 | Helper.TaskbarItemHelper.update(now * 100 / full);
166 | }));
167 | }
168 |
169 | if (exc == null)
170 | MessageBox.Show(Properties.Resources.operation_completed);
171 | else
172 | MessageBox.Show(Properties.Resources.payload_error_occur + "\n" + exc.Message);
173 |
174 | MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
175 | {
176 | MainWindow.THIS.payload_progress.Visibility = Visibility.Hidden;
177 | MainWindow.THIS.payload_action_bar.Visibility = Visibility.Visible;
178 | Helper.TaskbarItemHelper.stop();
179 | MainWindow.THIS.payload_extract.IsEnabled = true;
180 | MainWindow.THIS.payload_extract_options.IsEnabled = true;
181 | }));
182 |
183 | })).Start();
184 | }));
185 | };
186 |
187 | MainWindow.THIS.payload_before_load.DragEnter += delegate (object sender, DragEventArgs e)
188 | {
189 | if (e.Data.GetDataPresent(DataFormats.FileDrop))
190 | e.Effects = DragDropEffects.All;
191 | else
192 | e.Effects = DragDropEffects.None;
193 | };
194 |
195 | MainWindow.THIS.payload_before_load.Drop += delegate (object sender, DragEventArgs e)
196 | {
197 | Array files = (Array)e.Data.GetData(DataFormats.FileDrop);
198 | if (files.Length > 1)
199 | {
200 | MessageBox.Show(Properties.Resources.payload_unable_drop_multifile);
201 | return;
202 | }
203 | string filename = files.GetValue(0).ToString();
204 | if (!filename.EndsWith(".bin") && !filename.EndsWith(".zip"))
205 | {
206 | MessageBox.Show(Properties.Resources.payload_unsupported_format);
207 | return;
208 | }
209 | onLoad(files.GetValue(0).ToString());
210 | };
211 | }
212 |
213 | static void refreshData()
214 | {
215 | MainWindow.THIS.payload_progress.Visibility = Visibility.Hidden;
216 | MainWindow.THIS.payload_action_bar.Visibility = Visibility.Visible;
217 | MainWindow.THIS.payload_info.Items.Clear();
218 | listHelper.clear();
219 | MainWindow.THIS.payload_partition_name_textbox.Text = "";
220 | MainWindow.THIS.payload_dynamic_partition_meta.Items.Clear();
221 |
222 | payloadInfoListAppend(Properties.Resources.payload_version, payload.file_format_version.ToString());
223 | payloadInfoListAppend(Properties.Resources.payload_manifest_size, Helper.byte2AUnit(payload.manifest_size));
224 | payloadInfoListAppend(Properties.Resources.payload_metadata_signature_size, Helper.byte2AUnit(payload.metadata_signature_size));
225 | payloadInfoListAppend(Properties.Resources.payload_metadata_signature, payload.metadata_signature_message.Signatures_[0].Data.ToBase64());
226 | payloadInfoListAppend(Properties.Resources.payload_data_size, Helper.byte2AUnit(payload.data_size));
227 | payloadInfoListAppend(Properties.Resources.payload_signature_size, Helper.byte2AUnit(payload.payload_signatures_message_size));
228 | payloadInfoListAppend(Properties.Resources.payload_signature, payload.payload_signatures_message.Signatures_[0].Data.ToBase64());
229 |
230 | payloadInfoListAppend(Properties.Resources.payload_full_package, payload.manifest.MinorVersion == 0 ?
231 | Properties.Resources.yes : Properties.Resources.no + " (" + payload.manifest.MinorVersion + ")");
232 | if (payload.manifest.HasMaxTimestamp)
233 | payloadInfoListAppend(Properties.Resources.payload_timestamp, Helper.timeStamp2DataTime(payload.manifest.MaxTimestamp).ToString());
234 | payloadInfoListAppend(Properties.Resources.payload_blocksize, Helper.byte2AUnit(payload.manifest.BlockSize));
235 |
236 | if (payload.manifest.NewImageInfo != null)
237 | {
238 | if (payload.manifest.NewImageInfo.HasBoard)
239 | payloadInfoListAppend("board", payload.manifest.NewImageInfo.Board);
240 |
241 | if (payload.manifest.NewImageInfo.HasKey)
242 | payloadInfoListAppend("key", payload.manifest.NewImageInfo.Key);
243 |
244 | if (payload.manifest.NewImageInfo.HasChannel)
245 | payloadInfoListAppend("channel", payload.manifest.NewImageInfo.Channel);
246 |
247 | if (payload.manifest.NewImageInfo.HasVersion)
248 | payloadInfoListAppend("version", payload.manifest.NewImageInfo.Version);
249 |
250 | if (payload.manifest.NewImageInfo.HasBuildVersion)
251 | payloadInfoListAppend("build_version", payload.manifest.NewImageInfo.BuildVersion);
252 |
253 | if (payload.manifest.NewImageInfo.HasBuildChannel)
254 | payloadInfoListAppend("build_channel", payload.manifest.NewImageInfo.BuildChannel);
255 | }
256 |
257 |
258 | foreach (PartitionUpdate partitionUpdate in payload.manifest.Partitions)
259 | {
260 | payloadPartitionInfoListAppend(partitionUpdate.PartitionName,
261 | partitionUpdate.NewPartitionInfo != null && partitionUpdate.NewPartitionInfo.HasSize ?
262 | Helper.byte2AUnit(partitionUpdate.NewPartitionInfo.Size) : Properties.Resources.unknown,
263 | partitionUpdate.NewPartitionInfo != null && partitionUpdate.NewPartitionInfo.HasHash ?
264 | partitionUpdate.NewPartitionInfo.Hash.ToBase64() : Properties.Resources.unknown);
265 | }
266 | listHelper.render();
267 |
268 | if (payload.manifest.DynamicPartitionMetadata != null)
269 | {
270 | if (payload.manifest.DynamicPartitionMetadata.HasSnapshotEnabled)
271 | dynamicPartitionMetaAppend(Properties.Resources.payload_snapshot_enabled +
272 | (payload.manifest.DynamicPartitionMetadata.SnapshotEnabled ? Properties.Resources.yes :
273 | Properties.Resources.no));
274 |
275 | if (payload.manifest.DynamicPartitionMetadata.Groups != null)
276 | foreach (DynamicPartitionGroup dynamicPartitionGroup in payload.manifest.DynamicPartitionMetadata.Groups)
277 | {
278 | dynamicPartitionMetaAppend(Properties.Resources.payload_partition_group_name + dynamicPartitionGroup.Name);
279 | dynamicPartitionMetaAppend(Properties.Resources.payload_partition_group_size + Helper.byte2AUnit(dynamicPartitionGroup.Size));
280 | dynamicPartitionMetaAppend(Properties.Resources.payload_partition_group_include);
281 | if (dynamicPartitionGroup.PartitionNames != null)
282 | foreach (string parition in dynamicPartitionGroup.PartitionNames)
283 | dynamicPartitionMetaAppend(parition);
284 | }
285 | }
286 | else
287 | {
288 | dynamicPartitionMetaAppend(Properties.Resources.payload_no_dynamic_metadata);
289 | }
290 |
291 | }
292 |
293 | class payload_info_row
294 | {
295 | public string title { get; }
296 | public string value { get; }
297 | public payload_info_row(string title, string value)
298 | {
299 | this.title = title;
300 | this.value = value;
301 | }
302 | }
303 |
304 | static Helper.ListHelper listHelper;
305 | static void payloadInfoListAppend(string title, string value)
306 | {
307 | MainWindow.THIS.payload_info.Items.Add(new payload_info_row(title, value));
308 | }
309 |
310 | class payload_partition_info_row
311 | {
312 | public string name { get; }
313 | public string size { get; }
314 | public string hash { get; }
315 | public payload_partition_info_row(string name, string size, string hash)
316 | {
317 | this.name = name;
318 | this.size = size;
319 | this.hash = hash;
320 | }
321 | }
322 |
323 | static void dynamicPartitionMetaAppend(string line)
324 | {
325 | MainWindow.THIS.payload_dynamic_partition_meta.Items.Add(new payload_dynamic_partition_meta_row(line));
326 | }
327 |
328 | class payload_dynamic_partition_meta_row
329 | {
330 | public string line { get; }
331 | public payload_dynamic_partition_meta_row(string line)
332 | {
333 | this.line = line;
334 | }
335 | }
336 |
337 | static void payloadPartitionInfoListAppend(string name, string size, string hash)
338 | {
339 | listHelper.addItem(new payload_partition_info_row(name, size, hash));
340 | }
341 |
342 | public static void init()
343 | {
344 | cur_status = page_status.empty;
345 | actionInit();
346 | switchMainView();
347 | }
348 | }
349 | }
350 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // 有关程序集的一般信息由以下
8 | // 控制。更改这些特性值可修改
9 | // 与程序集关联的信息。
10 | [assembly: AssemblyTitle("FastbootEnhance")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("FastbootEnhance")]
15 | [assembly: AssemblyCopyright("Copyright © 2021 LibXZR. All rights reserved.")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // 将 ComVisible 设置为 false 会使此程序集中的类型
20 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
21 | //请将此类型的 ComVisible 特性设置为 true。
22 | [assembly: ComVisible(false)]
23 |
24 | //若要开始生成可本地化的应用程序,请设置
25 | //.csproj 文件中的 CultureYouAreCodingWith
26 | //例如,如果您在源文件中使用的是美国英语,
27 | //使用的是美国英语,请将 设置为 en-US。 然后取消
28 | //对以下 NeutralResourceLanguage 特性的注释。 更新
29 | //以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //主题特定资源词典所处位置
36 | //(未在页面中找到资源时使用,
37 | //或应用程序资源字典中找到时使用)
38 | ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
39 | //(未在页面中找到资源时使用,
40 | //、应用程序或任何主题专用资源字典中找到时使用)
41 | )]
42 |
43 |
44 | // 程序集的版本信息由下列四个值组成:
45 | //
46 | // 主版本
47 | // 次版本
48 | // 生成号
49 | // 修订号
50 | //
51 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
52 | //通过使用 "*",如下所示:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.4.0")]
55 | [assembly: AssemblyFileVersion("1.4.0")]
56 |
--------------------------------------------------------------------------------
/Properties/Resources.ja-JP.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/Properties/Resources.ja-JP.Designer.cs
--------------------------------------------------------------------------------
/Properties/Resources.ja-JP.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | バージョン情報
122 |
123 |
124 | Fastboot Enhance
125 |
126 |
127 | 開発者: LibXZR @ akr-developers.com
128 |
129 |
130 | 無効
131 |
132 |
133 | 有効
134 |
135 |
136 | エラー
137 |
138 |
139 | 不明
140 |
141 |
142 | プロパティ
143 |
144 |
145 | 更新を中断する
146 |
147 |
148 | ダブルクリックで対象のデバイスを選択:
149 |
150 |
151 | 仮想A/B一時パーティションが存在します
152 |
153 |
154 | 仮想A/Bパーティションのアップデート時に作成された一時パーティションがデバイス内に存在する為、無理に続行をするとsuperパーティションの容量不足によりデバイスが文鎮化する可能性があります。
155 |
156 |
157 | (仮想A/Bのアップデート中でなければ「COW」で終わる一時パーティションを手動で削除すればこの警告を解消することが可能です)
158 |
159 |
160 | 続行をしますか?
161 |
162 |
163 | 新しい論理パーティションの作成
164 |
165 |
166 | 現在のデバイス:
167 |
168 |
169 | 現在のスロット
170 |
171 |
172 | デバイス名
173 |
174 |
175 | デバイス
176 |
177 |
178 | 対象デバイスがありません
179 |
180 |
181 | Fastboot
182 |
183 |
184 | 論理パーティションの拡張
185 |
186 |
187 | 名前で絞り込む:
188 |
189 |
190 | Payload.binを書き込む
191 |
192 |
193 | 不明なパーティションを無視
194 |
195 |
196 | Fastbootdで実行中
197 |
198 |
199 | この操作では複数のパーティションを選択することはできません。
200 |
201 |
202 | この操作は論理パーティションでのみ可能です。
203 |
204 |
205 | アクション
206 |
207 |
208 | 作成
209 |
210 |
211 | 削除
212 |
213 |
214 | 消去
215 |
216 |
217 | 書き込み
218 |
219 |
220 | リサイズ
221 |
222 |
223 | 論理パーティション
224 |
225 |
226 | 名前
227 |
228 |
229 | パーティション名が空欄です。
230 |
231 |
232 | サイズ
233 |
234 |
235 | サイズ (B)
236 |
237 |
238 | パーティションサイズが空欄です。
239 |
240 |
241 | パーティションサイズが無効です。
242 |
243 |
244 | パーティションの縮小ができません。パーティションの削除をしてから再作成であれば可能です。
245 |
246 |
247 | パーティション
248 |
249 |
250 | 名前
251 |
252 |
253 | 値
254 |
255 |
256 | Bootloaderで再起動
257 |
258 |
259 | Fastbootdで再起動
260 |
261 |
262 | Recoveryで再起動
263 |
264 |
265 | Systemで再起動
266 |
267 |
268 | 切断
269 |
270 |
271 | シームレスアップデートに対応
272 |
273 |
274 | セキュアブート
275 |
276 |
277 | シリアルナンバー
278 |
279 |
280 | スロットAに変更
281 |
282 |
283 | スロットBに変更
284 |
285 |
286 | ログを表示
287 |
288 |
289 | 対象のパーティションが未選択です。
290 |
291 |
292 | 以下の書き込むパーティションが不明な場合があります:
293 |
294 |
295 | 不明なパーティションを無視にチェックを入れるとこの警告を無効にすることができます。未知のパーティションですがデバイスの書き込みに失敗したり、文鎮化する訳ではありません。
296 |
297 |
298 | fastbootdモードの再起動が必要な可能性があります。
299 |
300 |
301 | システムアップデートの状態
302 |
303 |
304 | マージ
305 |
306 |
307 | なし
308 |
309 |
310 | スナップショット済み
311 |
312 |
313 | システムアップデート中
314 |
315 |
316 | デバイスのシステムアップデート中です。操作を強制するとデバイスが文鎮化する可能性があります。
317 |
318 |
319 | (デバイスのシステムアップデートが完了するまでしばらくお待ちください)
320 |
321 |
322 | 続行をしますか?
323 |
324 |
325 | vbmetaのVerificationを無効化しますか?
326 |
327 |
328 | Verificationを無効化
329 |
330 |
331 | ログを記録
332 |
333 |
334 | いいえ
335 |
336 |
337 | OK
338 |
339 |
340 | GitHub
341 |
342 |
343 | 操作が完了しました
344 |
345 |
346 | 操作はサポートされていません。
347 |
348 |
349 | プロパティ
350 |
351 |
352 | ブロックサイズ
353 |
354 |
355 | 参照
356 |
357 |
358 | 現在のファイル:
359 |
360 |
361 | Data Blobのサイズ
362 |
363 |
364 | Payload Dumper
365 |
366 |
367 | 動的パーティションのメタデータ
368 |
369 |
370 | エラーが発生しました。
371 |
372 |
373 | 不明な操作を無視
374 |
375 |
376 | チェックサムを無視
377 |
378 |
379 | イメージを抽出する
380 |
381 |
382 | インクリメンタルを許可
383 |
384 |
385 | 抽出のオプション
386 |
387 |
388 | フルパッケージ
389 |
390 |
391 | インクリメンタルパッケージからイメージを抽出できません。
392 |
393 |
394 | マニフェストのサイズ
395 |
396 |
397 | メタデータの署名 (Base64)
398 |
399 |
400 | メタデータの署名のサイズ
401 |
402 |
403 | 動的パーティションのメタデータがありません
404 |
405 |
406 | Payloadを指定していない場合は、「参照」をクリックまたは「ファイルをドラッグ&ドロップ」してください。
407 |
408 |
409 | パーティション
410 |
411 |
412 | 名前で絞り込む:
413 |
414 |
415 | チェックサム (Base64)
416 |
417 |
418 | 名前
419 |
420 |
421 | サイズ
422 |
423 |
424 | Payloadに含まれるパーティション:
425 |
426 |
427 | パーティションのグループ名:
428 |
429 |
430 | パーティションのグループサイズ:
431 |
432 |
433 | 名前
434 |
435 |
436 | 値
437 |
438 |
439 | 削除
440 |
441 |
442 | 署名 (Base64)
443 |
444 |
445 | 署名のサイズ
446 |
447 |
448 | スナップショットが有効:
449 |
450 |
451 | 抽出する対象パーティションが未選択です。
452 |
453 |
454 | タイムスタンプ
455 |
456 |
457 | 複数ファイルのドロップはできません。
458 |
459 |
460 | ファイル形式の互換性がありません。
461 |
462 |
463 | Payloadのバージョン
464 |
465 |
466 | プログラムは既に実行中です。
467 |
468 |
469 | リリース先: www.akr-developers.com
470 |
471 |
472 | 保存するパスを選択
473 |
474 |
475 | 不明
476 |
477 |
478 | スレッド
479 |
480 |
481 | はい
482 |
483 |
--------------------------------------------------------------------------------
/Properties/Resources.ko-KR.Designer.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Properties/Resources.ko-KR.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 버전 정보
122 |
123 |
124 | 고급 Fastboot
125 |
126 |
127 | 제작자: LibXZR @ akr-developers.com
128 |
129 |
130 | 꺼짐
131 |
132 |
133 | 켜짐
134 |
135 |
136 | 오류
137 |
138 |
139 | 알 수 없음
140 |
141 |
142 | 기본 정보
143 |
144 |
145 | 업데이트 중지
146 |
147 |
148 | 두 번 눌러 기기를 선택하세요:
149 |
150 |
151 | 가상 A/B 임시 파티션이 있습니다
152 |
153 |
154 | 가상 A/B 시스템 업데이트 중에 생성된 임시 파티션이 기기에 존재하므로 강제로 계속 진행하면 슈퍼 파티션의 공간 부족으로 인해 플래싱이 실패하여 기기가 벽돌이 될 수 있습니다.
155 |
156 |
157 | (가상 A/B 업데이트가 진행 중이 아닌 경우 "cow"로 끝나는 임시 파티션을 수동으로 삭제하여 이 경고를 해결할 수 있습니다.)
158 |
159 |
160 | 계속 하시겠습니까?
161 |
162 |
163 | 새 동적 파티션 만들기
164 |
165 |
166 | 현재 기기:
167 |
168 |
169 | 현재 슬롯
170 |
171 |
172 | 기기
173 |
174 |
175 | 기기 이름
176 |
177 |
178 | 해당 기기가 없습니다
179 |
180 |
181 | Fastboot 가상화
182 |
183 |
184 | 동적 파티션 확장하기
185 |
186 |
187 | 이름으로 검색:
188 |
189 |
190 | Payload.bin 플래시
191 |
192 |
193 | 알 수 없는 파티션 무시하기
194 |
195 |
196 | Fastbootd 모드
197 |
198 |
199 | 이 동작은 여러개의 파티션을 선택하면 할 수 없습니다.
200 |
201 |
202 | 이 작업은 동적 파티션에서만 할 수 있습니다.
203 |
204 |
205 | 동작
206 |
207 |
208 | 추가
209 |
210 |
211 | 제거
212 |
213 |
214 | 지우기
215 |
216 |
217 | 플래시
218 |
219 |
220 | 크기 조정
221 |
222 |
223 | 동적
224 |
225 |
226 | 이름
227 |
228 |
229 | 파티션 이름이 비었습니다.
230 |
231 |
232 | 크기
233 |
234 |
235 | 크기 (B)
236 |
237 |
238 | 파티션 크기가 비었습니다.
239 |
240 |
241 | 입력할수 없는 파티션크기입니다.
242 |
243 |
244 | 파티션을 축소할 수 없습니다. 지우고 재생성 할 수 있습니다.
245 |
246 |
247 | 파티션
248 |
249 |
250 | 이름
251 |
252 |
253 | 값
254 |
255 |
256 | 부트로더로 재부팅
257 |
258 |
259 | Fastbootd로 재부팅
260 |
261 |
262 | 복구모드로 재부팅
263 |
264 |
265 | 재부팅
266 |
267 |
268 | 연결 끊기
269 |
270 |
271 | 심리스 업데이트
272 |
273 |
274 | 보안 부팅
275 |
276 |
277 | 일련 번호
278 |
279 |
280 | 슬롯 A 활성화
281 |
282 |
283 | 슬롯 B 활성화
284 |
285 |
286 | 로그 보기
287 |
288 |
289 | 파티션이 선택되지 않았습니다.
290 |
291 |
292 | 다음 파티션이 플래싱 됐는지 알 수 없습니다:
293 |
294 |
295 | "알 수 없는 파티션 무시하기" 확인란을 선택하여 이 경고를 비활성화할 수 있습니다. 알 수 없는 파티션이 있다고 해서 플래싱이 실패하거나 기기가 벽돌이 되는 것은 아닙니다.
296 |
297 |
298 | fastbootd 모드로 재부팅 해야할수도 있습니다.
299 |
300 |
301 | 시스템 업데이트 상태
302 |
303 |
304 | 병합중
305 |
306 |
307 | 없음
308 |
309 |
310 | 스냅샷
311 |
312 |
313 | 시스템 업데이트가 진행중입니다
314 |
315 |
316 | 기기가 시스템 업데이트 중이므로 강제로 작업하면 기기가 벽돌이될 수 있습니다.
317 |
318 |
319 | ( 기기를 시스템으로 재부팅하고 업데이트가 완료될 때까지 잠시 기다려주세요 )
320 |
321 |
322 | 계속 할까요?
323 |
324 |
325 | vbmeta 검증을 비활성화 할까요?
326 |
327 |
328 | 검증 비활성화
329 |
330 |
331 | 기록기
332 |
333 |
334 | 아니요
335 |
336 |
337 | 확인
338 |
339 |
340 | 오픈소스
341 |
342 |
343 | 작업 완료
344 |
345 |
346 | 명령이 지원되지 않습니다.
347 |
348 |
349 | 기본 정보
350 |
351 |
352 | 블록 크기
353 |
354 |
355 | 탐색
356 |
357 |
358 | 현재 파일:
359 |
360 |
361 | Data Blob 크기
362 |
363 |
364 | Payload 추출기
365 |
366 |
367 | 동적 파티션 부가정보
368 |
369 |
370 | 오류가 발생했습니다.
371 |
372 |
373 | 알 수 없는 작업 무시하기
374 |
375 |
376 | 체크섬 무시하기
377 |
378 |
379 | 이미지 추출하기
380 |
381 |
382 | 패치형 업데이트 허용
383 |
384 |
385 | 추출 옵션
386 |
387 |
388 | 풀 패키지
389 |
390 |
391 | 패치형 업데이트 패키지에서는 이미지를 추출할 수 없습니다.
392 |
393 |
394 | 매니페스트 크기
395 |
396 |
397 | 매니페스트 서명 (Base64)
398 |
399 |
400 | 매니페스트 서명 크기
401 |
402 |
403 | 동적 파티션 부가정보가 없습니다.
404 |
405 |
406 | Payload 파일이 선택되지 않았습니다, 탐색 버튼을 눌러 열거나, 끌어다 놓아주세요.
407 |
408 |
409 | 파티션
410 |
411 |
412 | 이름으로 검색:
413 |
414 |
415 | 체크섬 (Base64)
416 |
417 |
418 | 이름
419 |
420 |
421 | 크기
422 |
423 |
424 | 포함된 파티션:
425 |
426 |
427 | 파티션 그룹 이름:
428 |
429 |
430 | 파티션 그룹 크기:
431 |
432 |
433 | 이름
434 |
435 |
436 | 값
437 |
438 |
439 | 제거
440 |
441 |
442 | 서명 (Base64)
443 |
444 |
445 | 서명 크기
446 |
447 |
448 | 스냅샷 켜짐:
449 |
450 |
451 | 추출할 파티션을 선택해주세요.
452 |
453 |
454 | 시간
455 |
456 |
457 | 여러파일을 동시에 놓을수 없습니다.
458 |
459 |
460 | 호환되지 않는 파일 형식입니다.
461 |
462 |
463 | Payload 버전
464 |
465 |
466 | 이미 실행중입니다.
467 |
468 |
469 | 새로운 정보를 보시려면 www.akr-developers.com 을 방문하세요.
470 |
471 |
472 | 저장할 위치를 선택하세요
473 |
474 |
475 | 알 수 없는
476 |
477 |
478 | 게시글 보기
479 |
480 |
481 | 예
482 |
483 |
--------------------------------------------------------------------------------
/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | About
122 |
123 |
124 | Fastboot Enhance
125 |
126 |
127 | Author: LibXZR @ akr-developers.com
128 |
129 |
130 | Disabled
131 |
132 |
133 | Enabled
134 |
135 |
136 | Error
137 |
138 |
139 | Unknown
140 |
141 |
142 | Basic Properties
143 |
144 |
145 | Cancel pending update
146 |
147 |
148 | Double click to choose the target device:
149 |
150 |
151 | Virtual A/B temporary partitions exist
152 |
153 |
154 | The temporary partitions created during the Virtual A/B system update exist in the device, forcing it to continue may cause the flashing to fail due to insufficient space in the super partition, and thus brick the device.
155 |
156 |
157 | ( You can manually delete the temporary partitions ending in "cow" to resolve this warning if the Virtual A/B update is not in progress )
158 |
159 |
160 | Would you like to continue?
161 |
162 |
163 | Create new logical partition
164 |
165 |
166 | Current Device:
167 |
168 |
169 | Current Slot
170 |
171 |
172 | Device
173 |
174 |
175 | Device Name
176 |
177 |
178 | Target device is not exist
179 |
180 |
181 | Fastboot Visualization
182 |
183 |
184 | Expand logical partition
185 |
186 |
187 | Filter by name:
188 |
189 |
190 | Flash Payload.bin
191 |
192 |
193 | Ignore Unknown Partitions
194 |
195 |
196 | In Fastbootd
197 |
198 |
199 | This operation does not allow multiple partitions to be selected.
200 |
201 |
202 | This operation is only supported for logical partitions.
203 |
204 |
205 | Actions
206 |
207 |
208 | Create
209 |
210 |
211 | Delete
212 |
213 |
214 | Erase
215 |
216 |
217 | Flash
218 |
219 |
220 | Resize
221 |
222 |
223 | is Logical
224 |
225 |
226 | Name
227 |
228 |
229 | Partition name is empty.
230 |
231 |
232 | Size
233 |
234 |
235 | Size (B)
236 |
237 |
238 | Partition size is empty.
239 |
240 |
241 | Invalid partition size.
242 |
243 |
244 | Unable to shrink a partition. You can delete and recreate it.
245 |
246 |
247 | Partitions
248 |
249 |
250 | Name
251 |
252 |
253 | Value
254 |
255 |
256 | Reboot to BootLoader
257 |
258 |
259 | Reboot to Fastbootd
260 |
261 |
262 | Reboot to Recovery
263 |
264 |
265 | Reboot to System
266 |
267 |
268 | Disconnect
269 |
270 |
271 | Seamless Update
272 |
273 |
274 | Secure Boot
275 |
276 |
277 | Serial Number
278 |
279 |
280 | Activate Slot A
281 |
282 |
283 | Activate Slot B
284 |
285 |
286 | Show logs
287 |
288 |
289 | Target partition not yet selected.
290 |
291 |
292 | The following partitions to flash may be unknown:
293 |
294 |
295 | You can check the "Ignore unknown partitions" checkbox to disable this warning, the presence of unknown partitions does not mean that the flashing will fail or the device will brick.
296 |
297 |
298 | You may need to reboot to fastbootd mode.
299 |
300 |
301 | System Update Status
302 |
303 |
304 | Merging
305 |
306 |
307 | None
308 |
309 |
310 | Snapshotted
311 |
312 |
313 | System update is in progress
314 |
315 |
316 | The device is in the process of system update, forcing the operation may brick the device.
317 |
318 |
319 | ( You can reboot the device to the system and wait a while until the update process is complete )
320 |
321 |
322 | Would you like to continue?
323 |
324 |
325 | Would you like to disable the verification in vbmeta?
326 |
327 |
328 | Disable verification
329 |
330 |
331 | Logger
332 |
333 |
334 | No
335 |
336 |
337 | OK
338 |
339 |
340 | Opensource
341 |
342 |
343 | Operation completed
344 |
345 |
346 | Operation is not supported.
347 |
348 |
349 | Basic Properties
350 |
351 |
352 | Blocksize
353 |
354 |
355 | Browse
356 |
357 |
358 | Current file:
359 |
360 |
361 | Data Blobs Size
362 |
363 |
364 | Payload Dumper
365 |
366 |
367 | Dynamic Partition Metadata
368 |
369 |
370 | An error has occurred.
371 |
372 |
373 | Ignore unknown operations
374 |
375 |
376 | Ignore checksum
377 |
378 |
379 | Extract Image
380 |
381 |
382 | Allow incremental
383 |
384 |
385 | Extracting options
386 |
387 |
388 | Full Package
389 |
390 |
391 | Unable to extract images from an incremental package.
392 |
393 |
394 | Manifest Size
395 |
396 |
397 | Metadata Signatures (Base64)
398 |
399 |
400 | Metadata Signatures Size
401 |
402 |
403 | No dynamic partition metadata
404 |
405 |
406 | No payload has been specified, click the button browse, or drag in a file.
407 |
408 |
409 | Partitions
410 |
411 |
412 | Filter by name:
413 |
414 |
415 | Checksum (Base64)
416 |
417 |
418 | Name
419 |
420 |
421 | Size
422 |
423 |
424 | Partitions Included:
425 |
426 |
427 | Partition Group Name:
428 |
429 |
430 | Partition Group Size:
431 |
432 |
433 | Name
434 |
435 |
436 | Value
437 |
438 |
439 | Remove
440 |
441 |
442 | Signatures (Base64)
443 |
444 |
445 | Signatures Size
446 |
447 |
448 | Snapshot enabled:
449 |
450 |
451 | Target partitions to extract not yet selected.
452 |
453 |
454 | Timestamp
455 |
456 |
457 | Unable to drop multiple files.
458 |
459 |
460 | Incompatible file format.
461 |
462 |
463 | Payload Version
464 |
465 |
466 | The program is already running
467 |
468 |
469 | Release at www.akr-developers.com
470 |
471 |
472 | Select the path to save
473 |
474 |
475 | Unknown
476 |
477 |
478 | Thread
479 |
480 |
481 | Yes
482 |
483 |
--------------------------------------------------------------------------------
/Properties/Resources.zh-CN.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/Properties/Resources.zh-CN.Designer.cs
--------------------------------------------------------------------------------
/Properties/Resources.zh-CN.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 关于
122 |
123 |
124 | 作者:LibXZR @ akr-developers.com
125 |
126 |
127 | 未启用
128 |
129 |
130 | 启用
131 |
132 |
133 | 错误
134 |
135 |
136 | 获取失败
137 |
138 |
139 | 基本属性
140 |
141 |
142 | 清除更新状态
143 |
144 |
145 | 选择操作的目标设备(双击):
146 |
147 |
148 | Virtual A/B 临时分区存在
149 |
150 |
151 | 当前设备中存在 Virtual A/B 更新中创建的临时分区,强行继续可能造成因 super 分区空间不足而导致的镜像刷入失败,从而无法启动。
152 |
153 |
154 | (在 Virtual A/B 更新未在进行的前提下,您可以手动删除动态分区中以 cow 结尾的临时分区以解决此警告)
155 |
156 |
157 | 要强行继续刷入吗?
158 |
159 |
160 | 创建新的动态分区
161 |
162 |
163 | 当前选择的设备:
164 |
165 |
166 | 当前分区
167 |
168 |
169 | 设备
170 |
171 |
172 | 设备名
173 |
174 |
175 | 目标设备不存在
176 |
177 |
178 | Fastboot 可视化
179 |
180 |
181 | 扩容动态分区
182 |
183 |
184 | 根据分区名过滤:
185 |
186 |
187 | 刷写 Payload.bin
188 |
189 |
190 | 忽略未知分区
191 |
192 |
193 | 当前处于 Fastbootd
194 |
195 |
196 | 单分区操作不允许选择多个分区
197 |
198 |
199 | 此操作仅限于逻辑分区
200 |
201 |
202 | 分区操作
203 |
204 |
205 | 创建
206 |
207 |
208 | 删除
209 |
210 |
211 | 擦除
212 |
213 |
214 | 刷写
215 |
216 |
217 | 扩容
218 |
219 |
220 | 动态分区
221 |
222 |
223 | 分区名
224 |
225 |
226 | 分区名未填写。
227 |
228 |
229 | 大小
230 |
231 |
232 | 大小 (B)
233 |
234 |
235 | 分区大小未填写。
236 |
237 |
238 | 无效的分区大小。
239 |
240 |
241 | 无法缩小分区。你可以选择先删除再重建。
242 |
243 |
244 | 分区表
245 |
246 |
247 | 属性名
248 |
249 |
250 | 属性值
251 |
252 |
253 | 重启到 BootLoader
254 |
255 |
256 | 重启到 Fastbootd
257 |
258 |
259 | 重启到恢复模式
260 |
261 |
262 | 重启到系统
263 |
264 |
265 | 移除设备
266 |
267 |
268 | 无缝更新 (A/B 分区)
269 |
270 |
271 | 安全启动
272 |
273 |
274 | 序列号
275 |
276 |
277 | 切换到 A 插槽
278 |
279 |
280 | 切换到 B 插槽
281 |
282 |
283 | 显示日志
284 |
285 |
286 | 尚未选择目标分区
287 |
288 |
289 | 以下分区可能未知:
290 |
291 |
292 | 您可以勾选“忽略未知分区” 来消除此警告,存在未知分区并不代表分区刷入会失败抑或设备会无法启动。
293 |
294 |
295 | 可能需要切换到 Fastbootd 模式
296 |
297 |
298 | 系统更新状态
299 |
300 |
301 | 正在合并
302 |
303 |
304 | 未在进行
305 |
306 |
307 | 已执行快照
308 |
309 |
310 | 系统更新正在进行中
311 |
312 |
313 | 设备正处于系统更新过程中,强行进行刷入可能导致设备无法启动。
314 |
315 |
316 | (您可以重启设备进系统等待一会儿,直到更新过程完成)
317 |
318 |
319 | 要强行继续刷入吗?
320 |
321 |
322 | 要禁用 vbmeta 校验吗?
323 |
324 |
325 | 禁用校验
326 |
327 |
328 | 日志
329 |
330 |
331 | 否
332 |
333 |
334 | 确认
335 |
336 |
337 | 开放源代码
338 |
339 |
340 | 操作已完成
341 |
342 |
343 | 操作不被支持。
344 |
345 |
346 | 基本属性
347 |
348 |
349 | 块大小
350 |
351 |
352 | 浏览
353 |
354 |
355 | 当前打开:
356 |
357 |
358 | 数据大小
359 |
360 |
361 | Payload.bin 解包
362 |
363 |
364 | 动态分区元数据
365 |
366 |
367 | 发生了一个错误。
368 |
369 |
370 | 忽略未知操作
371 |
372 |
373 | 忽略一切校验
374 |
375 |
376 | 导出镜像
377 |
378 |
379 | 允许非完整包
380 |
381 |
382 | 导出选项
383 |
384 |
385 | 完整包
386 |
387 |
388 | 这不是一个完整包,无法导出分区镜像。
389 |
390 |
391 | 清单大小
392 |
393 |
394 | 元数据签名 (Base64)
395 |
396 |
397 | 元数据签名大小
398 |
399 |
400 | 无动态分区元数据
401 |
402 |
403 | 尚未指定目标,请点击按钮浏览,或拖入一个文件
404 |
405 |
406 | 分区信息
407 |
408 |
409 | 根据分区名过滤:
410 |
411 |
412 | 校验值 (Base64)
413 |
414 |
415 | 分区名
416 |
417 |
418 | 分区大小
419 |
420 |
421 | 包含的分区:
422 |
423 |
424 | 分区组名:
425 |
426 |
427 | 分区组大小:
428 |
429 |
430 | 属性名
431 |
432 |
433 | 属性值
434 |
435 |
436 | 移除
437 |
438 |
439 | 签名 (Base64)
440 |
441 |
442 | 签名大小
443 |
444 |
445 | 启用分区快照:
446 |
447 |
448 | 未选择要导出的分区。
449 |
450 |
451 | 时间
452 |
453 |
454 | 不支持放入多个文件。
455 |
456 |
457 | 不兼容的文件格式。
458 |
459 |
460 | Payload 版本
461 |
462 |
463 | 程序已经在运行
464 |
465 |
466 | 发布于 www.akr-developers.com
467 |
468 |
469 | 选择保存路径
470 |
471 |
472 | 未知
473 |
474 |
475 | 访问主帖
476 |
477 |
478 | 是
479 |
480 |
--------------------------------------------------------------------------------
/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.42000
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace FastbootEnhance.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Fastboot Enhance
2 |
3 | 
4 |
5 |
6 |
7 |
8 | ## What can it do?
9 |
10 | - Show fastboot vars
11 | - Switch between fastbootd, bootloader, recovery & system
12 | - Switch between A & B slot
13 | - **Flash Payload.bin in fastbootd**
14 | - Flash images
15 | - Erase partitions
16 | - Delete logical partitions
17 | - Create logical partitions
18 | - Resize logical partitions
19 | - Unpack Payload.bin
20 | - **Extract specific image from Payload.bin**
21 | - Show Payload vars
22 | - Show dynamic partition metadata
23 |
24 | ## Usage
25 |
26 | - Make sure `.NET Framework 4.5+` is supported
27 |
28 | - Download `Release.zip` from [Github Releases](https://github.com/xzr467706992/FastbootEnhance/releases)
29 | - Unzip
30 | - Click `FastbootEnhance.exe`
31 |
32 | ## Note
33 |
34 | - Incremental packages are not supported
35 |
36 | ( I don't have a plan to support it in the future because it is quite useless )
37 |
38 | - Still you are able to extract correct image from incremental packages if the checksum passes
39 |
40 | ( The checksum will be automatically done if "ignore checksum" is not checked )
41 |
42 | ## Building
43 |
44 | - Clone and build it with Visual Studio
45 |
46 | ## Credits
47 |
48 | - [Android Platform Tools](https://developer.android.com/studio/releases/platform-tools)
49 | - [DotNetZip](https://github.com/haf/DotNetZip.Semverd)
50 | - [Protobuf](https://github.com/protocolbuffers/protobuf)
51 | - [XZ.NET](https://github.com/RomanBelkov/XZ.NET)
52 |
--------------------------------------------------------------------------------
/big_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/big_icon.png
--------------------------------------------------------------------------------
/fastboot.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/fastboot.exe
--------------------------------------------------------------------------------
/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/icon.ico
--------------------------------------------------------------------------------
/liblzma.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/liblzma.dll
--------------------------------------------------------------------------------
/liblzma64.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/liblzma64.dll
--------------------------------------------------------------------------------
/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/screenshots/Banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/screenshots/Banner.png
--------------------------------------------------------------------------------
/screenshots/ss1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/screenshots/ss1.png
--------------------------------------------------------------------------------
/screenshots/ss2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/screenshots/ss2.png
--------------------------------------------------------------------------------
/screenshots/ss3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/screenshots/ss3.png
--------------------------------------------------------------------------------
/screenshots/ss4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libxzr/FastbootEnhance/e0a1048a1f823516935cffe037ae2675741b8937/screenshots/ss4.png
--------------------------------------------------------------------------------