diff --git a/.github/scripts/screenshots.ps1 b/.github/scripts/screenshots.ps1
index f155039..2d82dea 100644
--- a/.github/scripts/screenshots.ps1
+++ b/.github/scripts/screenshots.ps1
@@ -347,27 +347,29 @@ if ($ExpectedFlashes -gt 0) {
# The file dialog takes a moment to go away; it must not be mistaken for the result.
Wait-For { $d = Find-Dialog; $null -eq $d -or $d.Current.NativeWindowHandle -ne $fileHwnd } 20 "the file dialog to close" | Out-Null
- # The stand-in phone has no odm: the app offers to create it in super first.
- $create = Wait-For { Find-Dialog } 30 "the missing partition question"
+ # One summary before the flash: the phone, the file, and every point to know. Here the
+ # stand-in has no odm (created in super first) and the six physical partitions also go to
+ # slot b. A point that could cost data adds an "I have read this" box; tick it if it is there.
+ $summary = Wait-For { Find-Dialog } 30 "the flash summary"
Start-Sleep -Milliseconds 600
- Save-Window ('{0:D2}-create-missing' -f $i); $i++
- Answer-Dialog $create 'Yes'
-
- $slots = Wait-For { Find-Dialog } 30 "the both-slots question"
- Start-Sleep -Milliseconds 600
- Save-Window ('{0:D2}-both-slots' -f $i); $i++
- Answer-Dialog $slots 'Yes'
-
- # The app shows "operation completed" (or an error) when it is done. With the file dialog
- # gone, the next window to appear is that box. A message box does not expose its text to
- # UI Automation, so the fastboot log below is what proves the flash.
- $done = Wait-For { Find-Dialog } 240 "flashing to finish"
+ Save-Window ('{0:D2}-flash-summary' -f $i); $i++
+ $i++ # the both-slots question used to be its own screen; the number is kept so later links hold
+ $ackCond = New-Object System.Windows.Automation.PropertyCondition($UIA::ControlTypeProperty, $Type::CheckBox)
+ $ack = @($summary.FindAll($Scope::Descendants, $ackCond)) | Select-Object -First 1
+ if ($null -ne $ack) { $ack.GetCurrentPattern([System.Windows.Automation.TogglePattern]::Pattern).Toggle() }
+ Answer-Dialog $summary 'Flash'
+
+ # The result is a strip on the Flash page (an error is still a box). The fastboot log below
+ # is what proves the flash.
+ $result = Wait-For { $d = Find-Dialog; if ($null -ne $d) { $d } else { Shown $root 'flash_result_title' } } 240 "flashing to finish"
+ if ($result.Current.ControlType -eq $Type::Window) {
+ $message = ($result.FindAll($Scope::Descendants, [System.Windows.Automation.Condition]::TrueCondition) |
+ ForEach-Object { $_.Current.Name } | Where-Object { $_ }) -join ' | '
+ Fail "flashing ended with a box: $message"
+ }
Start-Sleep -Milliseconds 800
- $message = ($done.FindAll($Scope::Descendants, [System.Windows.Automation.Condition]::TrueCondition) |
- ForEach-Object { $_.Current.Name } | Where-Object { $_ }) -join ' | '
- Write-Host "dialog after flashing: $message"
+ Write-Host "after flashing: $((By-Id $root 'flash_result_title').Current.Name)"
Save-Window ('{0:D2}-flash' -f $i); $i++
- Close-Dialog $done
Remove-Item $fastbootRefuse -ErrorAction SilentlyContinue
$flashes = @(Get-Content $fakeLog | Where-Object { $_ -match ' flash ' }).Count
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 525ceaf..3e505f5 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -15,9 +15,9 @@ jobs:
name: core library and tests (linux)
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- - uses: actions/setup-dotnet@v4
+ - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4
with:
dotnet-version: 8.0.x
@@ -42,9 +42,9 @@ jobs:
name: wpf app (windows)
runs-on: windows-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- - uses: actions/setup-dotnet@v4
+ - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4
with:
dotnet-version: 8.0.x
@@ -114,7 +114,7 @@ jobs:
Write-Host "Samsung's installer: $pos"
if (-not ($pos -match 'samsung=True')) { throw "Samsung's own installer did not pass the signature check" }
- - uses: actions/upload-artifact@v4
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: FastbootStudio-win-x64
path: publish/
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index a533c1e..f30df25 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -21,8 +21,9 @@ on:
type: boolean
default: false
+# Only the release job writes to the repository (the release, the tag); the rest read.
permissions:
- contents: write
+ contents: read
env:
DOTNET_NOLOGO: true
@@ -36,9 +37,9 @@ jobs:
name: core tests (linux)
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- - uses: actions/setup-dotnet@v4
+ - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4
with:
dotnet-version: 8.0.x
@@ -50,7 +51,7 @@ jobs:
needs: test
runs-on: windows-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- name: Check the version
shell: bash
@@ -75,7 +76,7 @@ jobs:
fi
done
- - uses: actions/setup-dotnet@v4
+ - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4
with:
dotnet-version: 8.0.x
@@ -104,7 +105,7 @@ jobs:
- name: Upload FastbootStudio.exe for signing
id: unsigned
if: steps.signpath.outputs.enabled == 'true'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: unsigned-exe
path: publish/FastbootStudio.exe
@@ -112,7 +113,7 @@ jobs:
- name: Sign FastbootStudio.exe
if: steps.signpath.outputs.enabled == 'true'
- uses: signpath/github-action-submit-signing-request@v3
+ uses: signpath/github-action-submit-signing-request@f6d04783b4569d051e0c80105fe66e82819d0092 # v3
with:
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
organization-id: ${{ vars.SIGNPATH_ORGANIZATION_ID }}
@@ -148,7 +149,7 @@ jobs:
[System.IO.File]::WriteAllText("$zip.sha256", "$hash $zip`n")
Get-Content "$zip.sha256"
- - uses: actions/upload-artifact@v4
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: release-zip
path: |
@@ -160,10 +161,12 @@ jobs:
name: publish and announce
needs: build
runs-on: ubuntu-latest
+ permissions:
+ contents: write
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- - uses: actions/download-artifact@v4
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: release-zip
path: out
@@ -217,7 +220,7 @@ jobs:
if: env.PRE != 'true'
run: bash .github/scripts/winget-manifests.sh "$RELEASE_VERSION" "$FILE" winget
- - uses: actions/upload-artifact@v4
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
if: env.PRE != 'true'
with:
name: winget-manifests
@@ -236,7 +239,7 @@ jobs:
- name: Submit to winget
if: steps.winget.outputs.enabled == 'true'
continue-on-error: true
- uses: vedantmgoyal9/winget-releaser@v2
+ uses: vedantmgoyal9/winget-releaser@b7370d4d152efdce803a26cc6ca9eee58cb2ad54 # v2
with:
identifier: IFOKNR.FastbootStudio
release-tag: ${{ env.RELEASE_VERSION }}
diff --git a/.github/workflows/screenshots.yml b/.github/workflows/screenshots.yml
index da45c3e..8f15520 100644
--- a/.github/workflows/screenshots.yml
+++ b/.github/workflows/screenshots.yml
@@ -27,11 +27,11 @@ jobs:
capture:
runs-on: windows-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
fetch-depth: 0 # full history so the commit step can rebase
- - uses: actions/setup-dotnet@v4
+ - uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4
with:
dotnet-version: 8.0.x
@@ -60,7 +60,7 @@ jobs:
shell: pwsh
run: ./.github/scripts/screenshots.ps1 -App publish/FastbootStudio.exe -Payload sample/sample-ota.zip -Out docs/screenshots -ExpectedFlashes 12 -ExpectedBackups 20 -Arabic
- - uses: actions/upload-artifact@v4
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
if: always()
with:
name: screenshots
@@ -71,14 +71,16 @@ jobs:
- name: Commit screenshots
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
shell: pwsh
+ env:
+ BRANCH: ${{ github.ref_name }}
run: |
- git config user.name "github-actions[bot]"
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git config user.name "IFOKNR"
+ git config user.email "253658289+ifoknr@users.noreply.github.com"
git add docs/screenshots
git diff --cached --quiet
if ($LASTEXITCODE -ne 0) {
git commit -m "Update app screenshots [skip ci]"
# The branch may have moved while the app was being captured.
- git pull --rebase origin ${{ github.ref_name }}
- git push origin HEAD:${{ github.ref_name }}
+ git pull --rebase origin $env:BRANCH
+ git push origin HEAD:$env:BRANCH
}
diff --git a/.github/workflows/telegram.yml b/.github/workflows/telegram.yml
index 17a6b28..bc14c6c 100644
--- a/.github/workflows/telegram.yml
+++ b/.github/workflows/telegram.yml
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v6
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- name: Get the release
env:
diff --git a/AdbFacts.cs b/AdbFacts.cs
index cbbc10f..77d5e35 100644
--- a/AdbFacts.cs
+++ b/AdbFacts.cs
@@ -56,6 +56,12 @@ public static void ReadConnected()
}
}
+ /// The Settings key: "on" when a connected phone may be asked for root on its own.
+ public const string RootProbeKey = "root_probe";
+
+ /// Whether a phone is asked for root when it connects; off until turned on in Settings.
+ public static bool RootProbe => Settings.Get(RootProbeKey) == "on";
+
///
/// Asks the phone and stores what it said. Blocks, so call it on a worker thread. A phone
/// that does not answer is simply not remembered.
@@ -72,10 +78,12 @@ public static DeviceFacts Read(string serial)
Settings.Set(FastbootUI.DeviceFactsKey, DeviceFacts.Remember(Settings.Get(FastbootUI.DeviceFactsKey), facts));
// The Companion lives under /data/adb, which only root can reach. Ask su only when
- // the phone has one; Magisk shows a prompt the first time, KernelSU and APatch
- // answer from their own allow list.
- Adb.Result su = Adb.Run(AdbCommand.Shell(serial, "command -v su"), Adb.ShortCommand);
- if (su.Succeeded && su.Output.Trim().Length > 0)
+ // the phone has one and the person turned the question on in Settings; Magisk
+ // shows a prompt the first time, KernelSU and APatch answer from their own allow list.
+ Adb.Result su = RootProbe
+ ? Adb.Run(AdbCommand.Shell(serial, "command -v su"), Adb.ShortCommand)
+ : null;
+ if (su != null && su.Succeeded && su.Output.Trim().Length > 0)
{
LogStore.Append("ADB device " + serial + ": asking for root to read Fastboot Studio Companion "
+ "(allow Shell in the root manager, or ignore this)");
diff --git a/Assets/icon-light.png b/Assets/icon-light.png
new file mode 100644
index 0000000..d6bb419
Binary files /dev/null and b/Assets/icon-light.png differ
diff --git a/Assets/icon-themed.png b/Assets/icon-themed.png
index 1cd446e..519262a 100644
Binary files a/Assets/icon-themed.png and b/Assets/icon-themed.png differ
diff --git a/BackupUI.cs b/BackupUI.cs
index 3cebb4c..f79d5a5 100644
--- a/BackupUI.cs
+++ b/BackupUI.cs
@@ -42,6 +42,9 @@ static class BackupUI
static string lastOutputFolder;
+ /// True while the poller sets the list's selection itself: the handler then stays out.
+ static bool choosing;
+
static volatile bool busy;
static volatile bool pageVisible;
static CancellationTokenSource cancel;
@@ -79,6 +82,8 @@ public static void init()
W.backup_devices.SelectionChanged += delegate
{
+ if (choosing)
+ return;
AdbDevice picked = W.backup_devices.SelectedItem as AdbDevice;
if (picked != null && (current == null || picked.Serial != current.Serial))
selectDevice(picked);
@@ -221,7 +226,9 @@ static void showDevices(List latest)
return;
}
+ choosing = true;
W.backup_devices.SelectedItem = keep;
+ choosing = false;
if (current == null || keep.Serial != current.Serial || keep.State != current.State)
selectDevice(keep);
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5a3feb7..8561061 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,22 @@
+## v3.0.0
+- شكل زجاجي جديد وأيقونة جديدة: رمادي زجاجي بالليلي، ثلجي بالنهاري
+- القائمة بمجموعات، وشريط فوق يبيّن الجوال ووضعه، وشريط حالة تحت
+- قبل الفلاش ملخص واحد فيه الجوال وكل النقاط، والنتيجة على الصفحة بدل نافذة
+- سجل لكل فلاش ينحفظ كملف، وزر إيقاف للأمر المعلّق
+- أودين: الحد من نوع الذاكرة، والترتيب BL ثم AP ثم CP ثم CSC
+- اختصارات كيبورد، والصيني والياباني والكوري كاملين
+
+**English**
+- A new glass look and icon: grey glass in dark, frosted in light
+- Pages in groups, a bar above with the phone and its mode, a status bar below
+- One summary before a flash with the phone and every point; the result on the page
+- A log file per flash, and a Stop for a hung command
+- Odin: limits from the storage type; BL, AP, CP, CSC order
+- Keyboard shortcuts; Chinese, Japanese and Korean complete
+
## v2.9.0
- جديد: فلاش سامسونج من التطبيق في وضع التحميل: صورة وحدة، tar من Magisk، أو الروم كامل
- قبل ما يكتب: يفحص MD5 والـ lz4، وجدول PIT والموديل، ويرفض EFS وروم موديل ثاني
diff --git a/DarkTitleBar.cs b/DarkTitleBar.cs
index 6a596ad..61928a0 100644
--- a/DarkTitleBar.cs
+++ b/DarkTitleBar.cs
@@ -18,6 +18,23 @@ static class DarkTitleBar
const int DWMWA_BORDER_COLOR = 34;
const int DWMWA_CAPTION_COLOR = 35;
const int DWMWA_TEXT_COLOR = 36;
+ const int DWMWA_SYSTEMBACKDROP_TYPE = 38;
+ const int DWMSBT_NONE = 1;
+ const int DWMSBT_MAINWINDOW = 2; // Mica
+
+ /// The Settings key of the glass backdrop: "off" to keep the window's own gradient.
+ public const string BackdropKey = "backdrop";
+
+ /// Windows 11 22H2 and later draw Mica; older systems have nothing to turn on.
+ public static bool BackdropAvailable => Environment.OSVersion.Version.Build >= 22621;
+
+ ///
+ /// Off unless turned on in Settings, and only with graphics-card drawing: under software
+ /// drawing (the app's default) Windows paints nothing behind a clear window, so the page
+ /// turned black.
+ ///
+ public static bool BackdropWanted => BackdropAvailable && Rendering.Chosen == Rendering.Mode.Gpu
+ && Settings.Get(BackdropKey) == "on";
/// COLORREF (0x00BBGGRR) of one of the theme's brushes: Bg, Line or Text.
static int ColorRef(string key)
@@ -49,6 +66,22 @@ public static void Apply(Window window)
DwmSetWindowAttribute(hwnd, DWMWA_CAPTION_COLOR, ref caption, sizeof(int));
DwmSetWindowAttribute(hwnd, DWMWA_BORDER_COLOR, ref border, sizeof(int));
DwmSetWindowAttribute(hwnd, DWMWA_TEXT_COLOR, ref text, sizeof(int));
+
+ // Mica: the desktop shows through the window, blurred. The window's own
+ // background has to be clear for it to show, so the sky brush goes when it is on.
+ if (BackdropAvailable)
+ {
+ bool mica = BackdropWanted;
+ int backdrop = mica ? DWMSBT_MAINWINDOW : DWMSBT_NONE;
+ if (DwmSetWindowAttribute(hwnd, DWMWA_SYSTEMBACKDROP_TYPE, ref backdrop, sizeof(int)) == 0)
+ {
+ HwndSource source = HwndSource.FromHwnd(hwnd);
+ if (source?.CompositionTarget != null)
+ source.CompositionTarget.BackgroundColor = mica ? System.Windows.Media.Colors.Transparent
+ : ((System.Windows.Media.SolidColorBrush)Palette.Get("Bg")).Color;
+ window.Background = mica ? System.Windows.Media.Brushes.Transparent : Palette.Get("SkyBrush");
+ }
+ }
}
catch (DllNotFoundException)
{
diff --git a/DriverWindow.xaml b/DriverWindow.xaml
index 0034608..ec984da 100644
--- a/DriverWindow.xaml
+++ b/DriverWindow.xaml
@@ -6,8 +6,8 @@
SizeToContent="Height" Width="596" ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
Foreground="{StaticResource Text}" FontFamily="{StaticResource UiFont}" FontSize="13" UseLayoutRounding="True">
-
+
@@ -18,7 +18,7 @@
-
+
+ BorderBrush="{StaticResource Line}" BorderThickness="0,1,0,0" CornerRadius="0,0,15,15">
diff --git a/Fastboot.cs b/Fastboot.cs
index c62b932..bfae7c2 100644
--- a/Fastboot.cs
+++ b/Fastboot.cs
@@ -53,7 +53,7 @@ public Fastboot(string serial, string action, TimeSpan timeout)
process.StartInfo.FileName = ExecutablePath;
process.StartInfo.Arguments = serial == null
? action
- : "-s \"" + serial + "\" " + action;
+ : "-s " + FastbootEnhance.Core.Adb.AdbCommand.WindowsArgument(serial) + " " + action;
process.StartInfo.WorkingDirectory = AppContext.BaseDirectory;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardError = true;
@@ -108,6 +108,9 @@ public static System.Collections.Generic.List ListSerials()
/// True when the deadline passed and the process was killed.
public bool TimedOut => timedOut;
+ /// True once stopped the process on purpose.
+ public bool Aborted { get; private set; }
+
///
/// Waits for fastboot to exit after its output has been read, and returns the exit code,
/// or null when the deadline killed it. The deadline guarantees this returns.
@@ -133,6 +136,7 @@ public void Abort()
Process current = process;
if (current == null)
return;
+ Aborted = true;
try
{
KillQuietly(current);
diff --git a/FastbootEnhance.csproj b/FastbootEnhance.csproj
index 9d4e822..895234e 100644
--- a/FastbootEnhance.csproj
+++ b/FastbootEnhance.csproj
@@ -15,7 +15,7 @@
- 2.9.0
+ 3.0.0
Fastboot Studio
Fastboot Studio
IFOKNR; LibXZR
@@ -70,6 +70,7 @@
+
diff --git a/FastbootUI.cs b/FastbootUI.cs
index e4d559a..1afd576 100644
--- a/FastbootUI.cs
+++ b/FastbootUI.cs
@@ -29,6 +29,42 @@ class FastbootUI
/// True while a payload is being extracted or written; the window asks before closing.
public static volatile bool flashing;
+ /// The fastboot started by and still running; null otherwise.
+ static volatile Fastboot activeStep;
+
+ ///
+ /// Which phone a question is about: "Phone: serial · product · slot a · fastbootd". Every
+ /// flash or erase confirmation ends with it, so a phone swapped mid-way is noticed.
+ ///
+ internal static string deviceLine()
+ {
+ FastbootData data = fastbootData;
+ string slot = data == null || string.IsNullOrEmpty(data.current_slot) ? "-" : data.current_slot.TrimStart('_');
+ return string.Format(Properties.Resources.confirm_device_line, cur_serial ?? "?",
+ data == null || string.IsNullOrEmpty(data.product) ? "?" : data.product, slot,
+ data != null && data.fastbootd ? "fastbootd" : "bootloader");
+ }
+
+ ///
+ /// Stops whatever fastboot command is running: a step command (flash, erase, boot…) or
+ /// the payload flash. The command's own error path reports what was stopped.
+ ///
+ public static void cancelCurrent()
+ {
+ Fastboot step = activeStep;
+ if (step != null)
+ {
+ appendLog("stopped by the user");
+ step.Abort();
+ return;
+ }
+ if (flashWorker != null)
+ {
+ appendLog("flash stopped by the user");
+ abortFlash();
+ }
+ }
+
static void appendLog(string logs)
{
LogStore.Append(logs);
@@ -52,7 +88,7 @@ static void refreshDeviceList()
}
MainWindow.THIS.fastboot_devices_empty.Visibility =
devices.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
- MainWindow.THIS.main_tabs.Tag = string.Format(Properties.Resources.rail_devices, devices.Count);
+ setStatus(string.Format(Properties.Resources.rail_devices, devices.Count));
}));
}
@@ -60,6 +96,8 @@ static bool checkCurDevExist()
{
using (Fastboot fastboot = new Fastboot(null, "devices"))
{
+ // stderr is drained alongside: a full pipe would otherwise stall fastboot.
+ System.Threading.Tasks.Task errors = fastboot.stderr.ReadToEndAsync();
while (true)
{
string line = fastboot.stdout.ReadLine();
@@ -111,7 +149,7 @@ static void devicesListRefresher()
// rather than letting the exception take the whole app down.
MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
{
- MainWindow.THIS.main_tabs.Tag = Properties.Resources.rail_no_fastboot;
+ setStatus(Properties.Resources.rail_no_fastboot);
ThemedDialog.Show(e.Message + "\n" + e.FileName, Properties.Resources.error,
MessageBoxButton.OK, MessageBoxImage.Error);
}));
@@ -480,10 +518,10 @@ static void showFastbootVars()
fastbootData.HasPendingUpdate ? Visibility.Visible : Visibility.Collapsed;
MainWindow.THIS.fastboot_mode_text.Text = fastbootData.fastbootd ? "fastbootd" : "bootloader";
- MainWindow.THIS.fastboot_mode_badge.Visibility = Visibility.Visible;
MainWindow.THIS.fastboot_checks.ItemsSource = buildChecks();
showSuperSpace();
+ updateDeviceBar();
}
/// What to look at before writing anything to this device.
@@ -566,16 +604,27 @@ static void showSuperSpace()
/// True to go ahead.
///
static bool superSpaceAllowed(IEnumerable> writes, IEnumerable created = null)
+ {
+ string problem = superSpaceProblem(writes, created);
+ return problem == null || Helper.confirm(problem + "\n\n" + Properties.Resources.super_full_ask + "\n\n" + deviceLine(),
+ Properties.Resources.super_full_title, true);
+ }
+
+ ///
+ /// When super is known to be too small for the images: by how much, and what could make
+ /// room. Null when they fit (or the phone is not in fastbootd, where nothing is resized).
+ ///
+ static string superSpaceProblem(IEnumerable> writes, IEnumerable created = null)
{
if (fastbootData == null || !fastbootData.fastbootd)
- return true;
+ return null;
SuperSpace space = SuperSpace.From(fastbootData);
SuperFit fit = space.Check(writes, created);
appendLog("super space: " + (space.Known ? Helper.byte2AUnit(space.Free) + " free" : "size unknown")
+ ", writes need " + Helper.byte2AUnit(fit.Needed) + (fit.Fits ? "" : " (does not fit)"));
if (fit.Fits)
- return true;
+ return null;
List ways = new List();
if (space.OtherSlotPartitions.Count > 0)
@@ -587,11 +636,9 @@ static bool superSpaceAllowed(IEnumerable> writes, IE
if (ways.Count == 0)
ways.Add(Properties.Resources.super_full_nothing);
- string text = string.Format(Properties.Resources.super_full,
+ return string.Format(Properties.Resources.super_full,
Helper.byte2AUnit(fit.Needed), string.Join(", ", fit.Growing), Helper.byte2AUnit(fit.Free))
- + "\n\n" + string.Join("\n\n", ways.Select(w => "• " + w))
- + "\n\n" + Properties.Resources.super_full_ask;
- return Helper.confirm(text, Properties.Resources.super_full_title, true);
+ + "\n" + string.Join("\n", ways.Select(w => "• " + w));
}
///
@@ -791,11 +838,119 @@ static void change_page()
MainWindow.THIS.fastboot_devices_page.Visibility = showActions ? Visibility.Collapsed : Visibility.Visible;
MainWindow.THIS.fastboot_actions_page.Visibility = showActions ? Visibility.Visible : Visibility.Collapsed;
- MainWindow.THIS.fastboot_device_chip.Visibility = showActions ? Visibility.Visible : Visibility.Collapsed;
- MainWindow.THIS.fastboot_remove.Visibility = showActions ? Visibility.Visible : Visibility.Collapsed;
+ // The device bar above the page shows the phone, its mode and Disconnect; the page header no longer repeats them.
MainWindow.THIS.flash_target_device.Text = showActions && cur_serial != null
? string.Format(Properties.Resources.flash_target, cur_serial)
: Properties.Resources.flash_target_none;
+ updateDeviceBar();
+ }
+
+ /// The status bar's device count, the same text the rail used to show.
+ static void setStatus(string text)
+ {
+ MainWindow.THIS.status_devices.Text = text;
+ if (cur_status != FastbootStatus.show_actions)
+ MainWindow.THIS.bar_device_detail.Text = text + " · " + Properties.Resources.bar_no_device_hint;
+ }
+
+ ///
+ /// The bar above every page: the phone that is open (product, serial, slot, mode,
+ /// lock state) and what can be done to it; or that none is.
+ ///
+ static void updateDeviceBar()
+ {
+ MainWindow window = MainWindow.THIS;
+ bool open = cur_status == FastbootStatus.show_actions && cur_serial != null;
+ FastbootData data = fastbootData;
+
+ window.bar_disconnect.Visibility = open ? Visibility.Visible : Visibility.Collapsed;
+ window.bar_reboot.Visibility = open ? Visibility.Visible : Visibility.Collapsed;
+ window.bar_usb_check.Visibility = open ? Visibility.Collapsed : Visibility.Visible;
+ window.bar_icon.Stroke = Palette.Get(open ? "Accent" : "Dim");
+
+ if (!open)
+ {
+ window.bar_device_name.Text = Properties.Resources.bar_no_device;
+ window.bar_device_detail.Text = window.status_devices.Text.Length > 0
+ ? window.status_devices.Text + " · " + Properties.Resources.bar_no_device_hint
+ : Properties.Resources.bar_no_device_hint;
+ window.bar_mode_chip.Visibility = Visibility.Collapsed;
+ window.bar_lock_chip.Visibility = Visibility.Collapsed;
+ return;
+ }
+
+ string product = data != null && !string.IsNullOrEmpty(data.product) ? data.product : null;
+ window.bar_device_name.Text = product ?? cur_serial;
+ List detail = new List();
+ if (product != null)
+ detail.Add(string.Format(Properties.Resources.bar_serial, cur_serial));
+ if (data != null && !string.IsNullOrEmpty(data.current_slot))
+ detail.Add(string.Format(Properties.Resources.bar_slot, data.current_slot.TrimStart('_')));
+ window.bar_device_detail.Text = detail.Count > 0 ? string.Join(" · ", detail) : cur_serial;
+
+ if (data != null)
+ {
+ window.bar_mode_text.Text = data.fastbootd ? "fastbootd" : "bootloader";
+ window.bar_mode_chip.Visibility = Visibility.Visible;
+ window.bar_lock_text.Text = data.unlocked == true ? Properties.Resources.bar_unlocked
+ : data.unlocked == false ? Properties.Resources.bar_locked : null;
+ window.bar_lock_text.Foreground = Palette.Get(data.unlocked == false ? "Warn" : "Dim");
+ window.bar_lock_chip.Visibility = window.bar_lock_text.Text == null ? Visibility.Collapsed : Visibility.Visible;
+ }
+ else
+ {
+ window.bar_mode_chip.Visibility = Visibility.Collapsed;
+ window.bar_lock_chip.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ /// The status bar's "last: fastboot flash boot · 1.2 s".
+ static void setLastCommand(string command, TimeSpan took)
+ {
+ string shown = command.Length > 48 ? command.Substring(0, 45) + "…" : command;
+ MainWindow.THIS.status_last.Text = string.Format(Properties.Resources.status_last, shown,
+ string.Format(Properties.Resources.status_seconds, took.TotalSeconds.ToString("0.0", System.Globalization.CultureInfo.InvariantCulture)));
+ }
+
+ /// Reads "fastboot --version" and "adb --version" once, for the status bar.
+ static void readToolVersions()
+ {
+ Thread reader = new Thread(delegate ()
+ {
+ string fastbootVersion = null, adbVersion = null;
+ try
+ {
+ string output;
+ Fastboot.Run(null, "--version", Fastboot.ShortCommand, out output);
+ fastbootVersion = firstVersion(output);
+ }
+ catch (Exception)
+ {
+ }
+ try
+ {
+ adbVersion = firstVersion(Adb.Run("--version", Adb.ShortCommand).Output);
+ }
+ catch (Exception)
+ {
+ }
+ string text = string.Join(" · ", new[] { fastbootVersion != null ? "fastboot " + fastbootVersion : null,
+ adbVersion != null ? "adb " + adbVersion : null }.Where(v => v != null));
+ MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate { MainWindow.THIS.status_tools.Text = text; }));
+ });
+ reader.IsBackground = true;
+ reader.Start();
+ }
+
+ /// "35.0.2" out of "fastboot version 35.0.2-12147458" or "Android Debug Bridge version 1.0.41 / Version 35.0.2-…".
+ static string firstVersion(string output)
+ {
+ if (string.IsNullOrEmpty(output))
+ return null;
+ System.Text.RegularExpressions.Match match = System.Text.RegularExpressions.Regex.Match(output, @"(?im)^(?:Version|fastboot version)\s+(\d+(?:\.\d+)+)");
+ if (!match.Success)
+ match = System.Text.RegularExpressions.Regex.Match(output, @"(\d+\.\d+\.\d+)");
+ return match.Success ? match.Groups[1].Value : null;
}
class StepCmdRunnerParam
@@ -823,9 +978,9 @@ class StepCmdRunnerParam
public StepCmdRunnerParam(string cmd, int step_count, bool hint_on_done, bool skip_var_refresh = false)
{
- this.timeout = cmd.StartsWith("reboot") || cmd.StartsWith("set_active") || cmd.StartsWith("snapshot-update")
- ? Fastboot.LongCommand
- : Fastboot.NoLimit;
+ // Every step command gets a deadline: a phone that stops answering mid-flash no
+ // longer hangs the app for good. Fifteen minutes is far beyond any image over USB.
+ this.timeout = Fastboot.LongCommand;
this.cmd = cmd;
this.step_count = step_count;
this.show_dialog_on_done = hint_on_done;
@@ -839,6 +994,8 @@ static void runStep(StepCmdRunnerParam param)
// Locked here, on the click, so a second click cannot start the command again
// before the worker gets going.
action_lock();
+ flashing = true;
+ MainWindow.THIS.bar_cancel.Visibility = Visibility.Visible;
if (param.step_count <= 0)
MainWindow.THIS.fastboot_progress_bar.IsIndeterminate = true;
@@ -853,11 +1010,13 @@ static void step_cmd_runner_err(object raw_param)
appendLog("> fastboot " + param.cmd);
string failure = null;
+ System.Diagnostics.Stopwatch took = System.Diagnostics.Stopwatch.StartNew();
try
{
using (Fastboot fastboot = new Fastboot(param.serial, param.cmd, param.timeout))
{
+ activeStep = fastboot;
int count = 0;
while (true)
{
@@ -879,11 +1038,14 @@ static void step_cmd_runner_err(object raw_param)
}
int? exitCode = fastboot.WaitForExit();
+ activeStep = null;
if (exitCode != 0)
{
failure = "fastboot " + param.cmd + ": " + (exitCode == null
? "did not finish within " + param.timeout.TotalMinutes + " minutes and was stopped"
: "exited with code " + exitCode);
+ if (fastboot.Aborted)
+ failure = Properties.Resources.step_cancelled;
appendLog(failure);
}
}
@@ -893,10 +1055,15 @@ static void step_cmd_runner_err(object raw_param)
failure = e.Message;
appendLog("fastboot " + param.cmd + " failed: " + e.Message);
}
+ activeStep = null;
+ took.Stop();
MainWindow.THIS.Dispatcher.BeginInvoke(new Action(delegate
{
+ flashing = false;
MainWindow.THIS.fastboot_progress_bar.IsIndeterminate = false;
+ MainWindow.THIS.bar_cancel.Visibility = Visibility.Collapsed;
+ setLastCommand(param.cmd, took.Elapsed);
action_unlock();
if (failure != null)
@@ -952,11 +1119,11 @@ static bool slotSwitchAllowed(string target)
Properties.Resources.slot_switch_title, MessageBoxButton.OK, MessageBoxImage.Error);
return false;
case SlotCheckLevel.Danger:
- return Helper.confirm(string.Format(Properties.Resources.slot_switch_danger, target) + "\n\n" + details,
- Properties.Resources.slot_switch_title, true);
+ return Helper.confirm(string.Format(Properties.Resources.slot_switch_danger, target) + "\n\n" + details
+ + "\n\n" + deviceLine(), Properties.Resources.slot_switch_title, true);
case SlotCheckLevel.Warn:
- return Helper.confirm(string.Format(Properties.Resources.slot_switch_warn, target) + "\n\n" + details,
- Properties.Resources.slot_switch_title);
+ return Helper.confirm(string.Format(Properties.Resources.slot_switch_warn, target) + "\n\n" + details
+ + "\n\n" + deviceLine(), Properties.Resources.slot_switch_title);
default:
return true;
}
@@ -992,7 +1159,7 @@ static void bootOnce(string path)
if (fastbootData.fastbootd)
{
- if (Helper.confirm(Properties.Resources.boot_once_fastbootd, Properties.Resources.fastboot_boot_once_title))
+ if (Helper.confirm(Properties.Resources.boot_once_fastbootd + "\n\n" + deviceLine(), Properties.Resources.fastboot_boot_once_title))
runStep(new StepCmdRunnerParam("reboot bootloader", 2, false));
return;
}
@@ -1020,7 +1187,10 @@ static void checkBootImage(string target, string path, Action flash)
BootImageAnalysis image = null;
Exception failure = null;
- MainWindow.THIS.fastboot_flash.IsEnabled = false;
+ // Locked, and the phone remembered: while the image is read nothing else may run,
+ // and if the phone was removed or swapped meanwhile the flash does not start.
+ string serial = cur_serial;
+ action_lock();
Helper.offloadAndRun(delegate
{
try
@@ -1033,7 +1203,13 @@ static void checkBootImage(string target, string path, Action flash)
}
}, delegate
{
- MainWindow.THIS.fastboot_flash.IsEnabled = true;
+ action_unlock();
+ if (serial == null || serial != cur_serial || fastbootData == null)
+ {
+ appendLog("boot image check: the phone changed while " + path + " was being read; nothing flashed");
+ ThemedDialog.Show(Properties.Resources.fastboot_device_not_exist);
+ return;
+ }
if (failure != null)
{
appendLog("boot image check: cannot read " + path + ": " + failure.Message);
@@ -1152,37 +1328,35 @@ static bool logicalCheck()
return false;
}
+ /// True when the user said no to one of the pending-update questions.
static bool vabStagingCheck()
{
- if (fastbootData.HasPendingUpdate)
+ foreach (KeyValuePair problem in vabStagingProblems())
{
- bool proceed = Helper.confirm(
- Properties.Resources.fastboot_vab_staging_str1 + "\n" +
- Properties.Resources.fastboot_vab_staging_str2 + "\n" +
- Properties.Resources.fastboot_vab_staging_str3,
- Properties.Resources.fastboot_vab_staging_str0, true);
-
- if (!proceed)
- {
+ if (!Helper.confirm(problem.Value + "\n\n" + deviceLine(), problem.Key, true))
return true;
- }
}
+ return false;
+ }
+ ///
+ /// A Virtual A/B update still pending on the phone, and COW partitions left in super:
+ /// each as (title, text), empty when neither applies.
+ ///
+ static List> vabStagingProblems()
+ {
+ List> problems = new List>();
+ if (fastbootData.HasPendingUpdate)
+ problems.Add(new KeyValuePair(Properties.Resources.fastboot_vab_staging_str0,
+ Properties.Resources.fastboot_vab_staging_str1 + "\n" +
+ Properties.Resources.fastboot_vab_staging_str2 + "\n" +
+ Properties.Resources.fastboot_vab_staging_str3));
if (fastbootData.HasCowPartitions)
- {
- bool proceed = Helper.confirm(
+ problems.Add(new KeyValuePair(Properties.Resources.fastboot_cow_exist_str0,
Properties.Resources.fastboot_cow_exist_str1 + "\n" +
Properties.Resources.fastboot_cow_exist_str2 + "\n" +
- Properties.Resources.fastboot_cow_exist_str3,
- Properties.Resources.fastboot_cow_exist_str0, true);
-
- if (!proceed)
- {
- return true;
- }
- }
-
- return false;
+ Properties.Resources.fastboot_cow_exist_str3));
+ return problems;
}
///
@@ -1233,17 +1407,31 @@ static void openPayloadThenFlash(string path, string serial)
return;
}
+ // Everything worth knowing is gathered here and asked once, at the end.
+ List points = new List();
+ foreach (KeyValuePair problem in vabStagingProblems())
+ points.Add(new ThemedDialog.SummaryItem { Text = problem.Key + "\n" + problem.Value, Destructive = true });
+
// Logical partitions the update adds (or the phone lost) are created first.
if (missing.Create.Count > 0)
{
appendLog("missing logical partitions: " + string.Join(", ", missing.Create));
- if (!Helper.confirm(string.Format(Properties.Resources.create_missing,
- string.Join(", ", missing.Create)), Properties.Resources.create_missing_title))
+ points.Add(new ThemedDialog.SummaryItem
{
- opened.Dispose();
- action_unlock();
- return;
- }
+ Text = string.Format(Properties.Resources.create_missing, string.Join(", ", missing.Create)),
+ });
+ }
+
+ List odd = opened.Partitions.Select(part => part.Name)
+ .Where(name => !AdbCommand.IsSafePartitionName(name)).ToList();
+ if (odd.Count > 0)
+ {
+ appendLog("payload refused: partition names that cannot go on a command line: " + string.Join(", ", odd));
+ ThemedDialog.Show(string.Format(Properties.Resources.payload_bad_names, string.Join(", ", odd)),
+ Properties.Resources.error, MessageBoxButton.OK, MessageBoxImage.Error);
+ opened.Dispose();
+ action_unlock();
+ return;
}
List blocked = opened.Partitions
@@ -1265,14 +1453,12 @@ static void openPayloadThenFlash(string path, string serial)
.Select(part => part.Name)
.ToList();
- if (unverifiable.Count > 0 && !Helper.confirm(
- string.Format(Properties.Resources.flash_unverified, string.Join(", ", unverifiable)),
- Properties.Resources.confirm_title, true))
- {
- opened.Dispose();
- action_unlock();
- return;
- }
+ if (unverifiable.Count > 0)
+ points.Add(new ThemedDialog.SummaryItem
+ {
+ Text = string.Format(Properties.Resources.flash_unverified, string.Join(", ", unverifiable)),
+ Destructive = true,
+ });
// The device must still be the one the user picked when they clicked flash.
if (serial == null || serial != cur_serial || fastbootData == null)
@@ -1292,12 +1478,9 @@ static void openPayloadThenFlash(string path, string serial)
.Select(part => new KeyValuePair(
createdAs.ContainsKey(part.Name) ? createdAs[part.Name] : part.Name, part.UnpackedSize))
.ToList();
- if (!superSpaceAllowed(writes, missing.Create))
- {
- opened.Dispose();
- action_unlock();
- return;
- }
+ string superProblem = superSpaceProblem(writes, missing.Create);
+ if (superProblem != null)
+ points.Add(new ThemedDialog.SummaryItem { Text = superProblem, Destructive = true });
// "Flash both slots": physical A/B partitions also go to the other slot.
IReadOnlyDictionary otherSlot = new Dictionary();
@@ -1306,17 +1489,34 @@ static void openPayloadThenFlash(string path, string serial)
otherSlot = BothSlots.OtherSlotTargets(fastbootData, opened.Partitions.Select(part => part.Name),
new HashSet(opened.LogicalPartitionNames(), StringComparer.Ordinal));
if (otherSlot.Count == 0)
- {
appendLog("flash both slots: nothing to write to another slot on this phone");
- }
- else if (!Helper.confirm(string.Format(Properties.Resources.flash_both_slots_confirm,
- BothSlots.Other(fastbootData.current_slot.TrimStart('_')), string.Join(", ", otherSlot.Keys)),
- Properties.Resources.flash_both_slots))
- {
- opened.Dispose();
- action_unlock();
- return;
- }
+ else
+ points.Add(new ThemedDialog.SummaryItem
+ {
+ Text = string.Format(Properties.Resources.flash_both_slots_confirm,
+ BothSlots.Other(fastbootData.current_slot.TrimStart('_')), string.Join(", ", otherSlot.Keys)),
+ });
+ }
+
+ long total = opened.Partitions.Sum(part => part.UnpackedSize);
+ string summary = string.Format(Properties.Resources.flash_summary, Path.GetFileName(path),
+ opened.Partitions.Count, Helper.byte2AUnit(total));
+ if (!ThemedDialog.Summary(Properties.Resources.flash_summary_title, summary, deviceLine(), points,
+ Properties.Resources.flash_summary_go))
+ {
+ appendLog("flash not confirmed");
+ opened.Dispose();
+ action_unlock();
+ return;
+ }
+
+ // The phone may have gone while the summary was open.
+ if (serial != cur_serial || fastbootData == null)
+ {
+ opened.Dispose();
+ action_unlock();
+ ThemedDialog.Show(Properties.Resources.flash_no_device);
+ return;
}
flashPayload(opened, serial, missing.Create, otherSlot);
@@ -1348,7 +1548,7 @@ static string createLogicalPartitions(string serial, IReadOnlyList names
appendLog("Creating logical partition " + name);
int? exitCode;
using (Fastboot fastboot = new Fastboot(serial,
- "create-logical-partition \"" + name + "\" 0", Fastboot.LongCommand))
+ "create-logical-partition " + AdbCommand.WindowsArgument(name) + " 0", Fastboot.LongCommand))
{
while (true)
{
@@ -1411,6 +1611,11 @@ static void flashPayload(PayloadFile payload, string serial, IReadOnlyList targets[result.Partition].P
ticker.Stop();
clock.Stop();
MainWindow.THIS.flash_elapsed.Text = clock.Elapsed.ToString(@"mm\:ss");
+ MainWindow.THIS.bar_cancel.Visibility = Visibility.Collapsed;
+ setLastCommand("flash (" + parts.Count + " partitions)", clock.Elapsed);
action_unlock();
+ appendLog(summary == null ? "flash finished: " + flashedCount + " of " + parts.Count + " written in "
+ + clock.Elapsed.ToString(@"mm\:ss") : "flash failed after " + flashedCount + " of " + parts.Count);
+ LogStore.EndFile();
if (cur_serial == serial)
load_fastboot_vars();
@@ -1724,12 +1936,17 @@ string failure(PartitionResult result, int? code) => targets[result.Partition].P
{
setPhase(Properties.Resources.flash_phase_done, "Ok");
MainWindow.THIS.flash_overall_progress.Value = 100;
- string done = Properties.Resources.operation_completed;
+ // The result stays on the page, over the log, instead of a box that hides it.
+ List detail = new List();
+ detail.Add(clock.Elapsed.ToString(@"mm\:ss"));
if (otherSlot.Count > 0)
- done += "\n\n" + string.Format(Properties.Resources.flash_both_slots_done, string.Join(", ", otherSlot.Values));
+ detail.Add(string.Format(Properties.Resources.flash_both_slots_done, string.Join(", ", otherSlot.Values)));
if (lateNames != null)
- done += "\n\n" + string.Format(Properties.Resources.flash_deferred_done, lateNames);
- ThemedDialog.Done(done);
+ detail.Add(string.Format(Properties.Resources.flash_deferred_done, lateNames));
+ MainWindow.THIS.flash_result_title.Text = string.Format(Properties.Resources.flash_result_title, flashedCount, parts.Count);
+ MainWindow.THIS.flash_result_detail.Text = string.Join(" · ", detail);
+ MainWindow.THIS.flash_result_reboot.IsEnabled = cur_serial == serial;
+ MainWindow.THIS.flash_result.Visibility = Visibility.Visible;
return;
}
@@ -1825,7 +2042,7 @@ public static void init()
Thread refresher = new Thread(new ThreadStart(devicesListRefresher));
refresher.IsBackground = true;
refresher.Start();
- MainWindow.THIS.main_tabs.Tag = string.Format(Properties.Resources.rail_devices, 0);
+ setStatus(string.Format(Properties.Resources.rail_devices, 0));
MainWindow.THIS.fastboot_usb_check.Click += delegate
{
@@ -1850,6 +2067,51 @@ public static void init()
{
leaveDevice();
};
+ MainWindow.THIS.flash_result_log.Click += delegate { MainWindow.THIS.main_tabs.SelectedItem = MainWindow.THIS.logs_tab; };
+ MainWindow.THIS.flash_result_reboot.Click += delegate
+ {
+ MainWindow.THIS.flash_result.Visibility = Visibility.Collapsed;
+ if (!checkCurDevExist())
+ return;
+ runStep(new StepCmdRunnerParam("reboot", 0, false, true));
+ leaveDevice();
+ };
+ MainWindow.THIS.bar_disconnect.Click += delegate { leaveDevice(); };
+ MainWindow.THIS.bar_usb_check.Click += delegate { checkUsb(); };
+ MainWindow.THIS.bar_cancel.Click += delegate { cancelCurrent(); };
+ MainWindow.THIS.bar_reboot.Click += delegate
+ {
+ System.Windows.Controls.ContextMenu menu = MainWindow.THIS.bar_reboot.ContextMenu;
+ menu.PlacementTarget = MainWindow.THIS.bar_reboot;
+ menu.IsOpen = true;
+ };
+ MainWindow.THIS.bar_reboot_system.Click += delegate
+ {
+ if (!checkCurDevExist())
+ return;
+ runStep(new StepCmdRunnerParam("reboot", 0, false, true));
+ leaveDevice();
+ };
+ MainWindow.THIS.bar_reboot_recovery.Click += delegate
+ {
+ if (!checkCurDevExist())
+ return;
+ runStep(new StepCmdRunnerParam("reboot recovery", 0, false, true));
+ leaveDevice();
+ };
+ MainWindow.THIS.bar_reboot_bootloader.Click += delegate
+ {
+ if (!checkCurDevExist())
+ return;
+ runStep(new StepCmdRunnerParam("reboot bootloader", 2, false));
+ };
+ MainWindow.THIS.bar_reboot_fastbootd.Click += delegate
+ {
+ if (!checkCurDevExist())
+ return;
+ runStep(new StepCmdRunnerParam("reboot fastboot", 3, false));
+ };
+ readToolVersions();
MainWindow.THIS.fastboot_reboot_d.Click += delegate
{
@@ -1891,7 +2153,8 @@ public static void init()
if (!checkCurDevExist())
return;
- string target = fastbootData.current_slot == "a" ? "b" : fastbootData.current_slot == "b" ? "a" : null;
+ string slot = fastbootData.current_slot?.TrimStart('_');
+ string target = slot == "a" ? "b" : slot == "b" ? "a" : null;
if (target == null)
{
ThemedDialog.Show(Properties.Resources.operation_not_supported);
@@ -1932,7 +2195,8 @@ public static void init()
string target = ((fastboot_partition_row)MainWindow.THIS.fastboot_partition_list.SelectedItem).name;
if (PartitionSafety.IsBrickRisk(target) && !ThemedDialog.ConfirmTyped(
- string.Format(Properties.Resources.confirm_critical_flash, target), Properties.Resources.critical_title, target))
+ string.Format(Properties.Resources.confirm_critical_flash, target) + "\n\n" + deviceLine(),
+ Properties.Resources.critical_title, target))
{
appendLog("flash of critical partition " + target + " not confirmed");
return;
@@ -1960,16 +2224,16 @@ public static void init()
string ext_arg = "";
- if (target == "vbmeta" || target == "vbmeta_" + fastbootData.current_slot
+ if (target == "vbmeta" || target == "vbmeta_" + fastbootData.current_slot?.TrimStart('_')
|| target == "vbmeta_a" || target == "vbmeta_b")
{
- if (Helper.confirm(Properties.Resources.fastboot_vbmeta_disable_verify,
+ if (Helper.confirm(Properties.Resources.fastboot_vbmeta_disable_verify + "\n\n" + deviceLine(),
Properties.Resources.fastboot_vbmeta_disable_verify_title))
{
ext_arg += "--disable-verity --disable-verification";
}
}
- string command = "flash " + ext_arg + " \"" + target + "\" \"" + path + "\"";
+ string command = "flash " + ext_arg + " " + AdbCommand.WindowsArgument(target) + " " + AdbCommand.WindowsArgument(path);
checkBootImage(target, path, delegate { runStep(new StepCmdRunnerParam(command, -1, true)); });
}), "Image File|*.img;*.image");
};
@@ -1985,13 +2249,14 @@ public static void init()
string target = ((fastboot_partition_row)MainWindow.THIS.fastboot_partition_list.SelectedItem).name;
bool confirmed = PartitionSafety.IsBrickRisk(target)
- ? ThemedDialog.ConfirmTyped(string.Format(Properties.Resources.confirm_critical_erase, target),
+ ? ThemedDialog.ConfirmTyped(string.Format(Properties.Resources.confirm_critical_erase, target) + "\n\n" + deviceLine(),
Properties.Resources.critical_title, target)
- : Helper.confirm(string.Format(Properties.Resources.confirm_erase, target), Properties.Resources.confirm_title, true);
+ : Helper.confirm(string.Format(Properties.Resources.confirm_erase, target) + "\n\n" + deviceLine(),
+ Properties.Resources.confirm_title, true);
if (!confirmed)
return;
- runStep(new StepCmdRunnerParam("erase \"" + target + "\"", 2, false));
+ runStep(new StepCmdRunnerParam("erase " + AdbCommand.WindowsArgument(target), 2, false));
};
MainWindow.THIS.fastboot_partition_list.SelectionChanged += delegate
@@ -2048,10 +2313,11 @@ public static void init()
string target = ((fastboot_partition_row)MainWindow.THIS.fastboot_partition_list.SelectedItem).name;
- if (!Helper.confirm(string.Format(Properties.Resources.confirm_delete, target), Properties.Resources.confirm_title, true))
+ if (!Helper.confirm(string.Format(Properties.Resources.confirm_delete, target) + "\n\n" + deviceLine(),
+ Properties.Resources.confirm_title, true))
return;
- runStep(new StepCmdRunnerParam("delete-logical-partition \"" + target + "\"", 2, false));
+ runStep(new StepCmdRunnerParam("delete-logical-partition " + AdbCommand.WindowsArgument(target), 2, false));
};
MainWindow.THIS.fastboot_logical_create.Click += delegate
@@ -2062,8 +2328,13 @@ public static void init()
new FastbootActionWindow(FastbootActionWindow.StartType.CREATE, "", 0,
delegate (string name, ulong size)
{
+ if (!AdbCommand.IsSafePartitionName(name))
+ {
+ ThemedDialog.Show(Properties.Resources.operation_not_supported);
+ return;
+ }
runStep(new StepCmdRunnerParam(
- "create-logical-partition \"" + name + "\" \"" + size.ToString() + "\"", 2, false));
+ "create-logical-partition " + AdbCommand.WindowsArgument(name) + " " + size.ToString(), 2, false));
}).ShowDialog();
};
@@ -2098,9 +2369,7 @@ public static void init()
if (!checkCurDevExist())
return;
- if (vabStagingCheck())
- return;
-
+ // The pending-update questions are part of the one summary shown before the flash.
string serial = cur_serial;
Helper.fileSelect(new Helper.PathSelectCallback(delegate (string path)
{
diff --git a/Help/ar/flash.md b/Help/ar/flash.md
index f3fddd2..3582329 100644
--- a/Help/ar/flash.md
+++ b/Help/ar/flash.md
@@ -5,9 +5,9 @@
1. افتح الجوال في صفحة **الجهاز**. في **fastbootd** كل الأقسام تنكتب؛ والبوت لودر ما يكتب الأقسام المنطقية.
2. خذ نسخة احتياطية أول من صفحة النسخ الاحتياطي.
3. اضغط **تفليش Payload.bin** واختر ملف الـ OTA أو payload.bin المسوي لجوالك.
-4. جاوب على الفحوصات: أقسام ناقصة في الجوال (تنسوى فاضية في fastbootd)، وملف بدون بصمات SHA-256، والمساحة في super.
+4. اقرأ الملخص الواحد قبل التفليش: الملف، والجوال (الرقم والموديل والسلوت والوضع)، وكل نقطة لازم تعرفها: أقسام ناقصة في الجوال (تنسوى فاضية في fastbootd)، وملف بدون بصمات SHA-256، والمساحة في super، والسلوت الثاني. النقطة اللي ممكن تضيّع بيانات تحتاج تعلّم **قريت هذا**. وبعدها **فلّش**.
5. تابع القائمة: يطلّع، تحقق، يفلّش، انفلش. الأقسام اللي يرفضها fastbootd (مثل مودم OnePlus) تنكتب من البوت لودر في الآخر.
-6. لما يقول خلص، أعد تشغيل الجوال.
+6. لما الشريط الأخضر يقول كم قسم انكتب، اضغط **إعادة تشغيل الجوال**، أو **فتح السجل**. والفلاش كامل ينحفظ بعد كملف (السجل ← فتح مجلد السجلات).
## danger
- هذا يبدّل نظام الجوال كامل. لو انقطع التفليش في النص (الكيبل، أو البطارية، أو قفلت التطبيق) ممكن الجوال ما يقلع.
@@ -18,7 +18,8 @@
## tips
- الصور تنكتب في الخانة النشطة.
-- ما ينحفظ شي على الكمبيوتر: كل صورة تنحذف بعد ما تنكتب.
+- ما ينحفظ شي على الكمبيوتر: كل صورة تنحذف بعد ما تنكتب. بس سجل الفلاش ينحفظ في %APPDATA%\Fastboot Studio\logs.
+- **إيقاف** في الشريط فوق الصفحات يوقّف الأمر الشغّال؛ والقسم اللي انكتب نصه تفلّشه مرة ثانية قبل إعادة التشغيل.
- عشان تفلّش قسم واحد، روح الجهاز ← الأقسام ← تفليش.
## terms
diff --git a/Help/ar/logs.md b/Help/ar/logs.md
index 25e7b6c..1d472dd 100644
--- a/Help/ar/logs.md
+++ b/Help/ar/logs.md
@@ -5,6 +5,7 @@
1. سوّ الشي اللي خرب مرة ثانية، عشان ينكتب في السجل.
2. اضغط **نسخ**، والصقه في رسالتك للقروب أو في مشكلة على GitHub.
3. **مسح** يفضّي السجل، وهو أصلاً يبدأ فاضي مع كل تشغيل للتطبيق.
+4. **فتح مجلد السجلات**: كل فلاش payload ينحفظ بعد كملف هناك (flash-التاريخ-الرقم.log، وآخر 30 يبقون)، عشان تعرف وش صار للجوال حتى بعد ما تقفل التطبيق.
## tips
- السجل فيه الأرقام التسلسلية لجوالاتك. لو تبي، احذفها قبل ما تنشره للعامة.
diff --git a/Help/ar/settings.md b/Help/ar/settings.md
index f21913f..cc40a06 100644
--- a/Help/ar/settings.md
+++ b/Help/ar/settings.md
@@ -1,14 +1,17 @@
## purpose
-إعدادات التطبيق: اللغة، والمظهر، وحجم الخط، وطريقة الرسم، والبحث عن تحديثات، وتعريفات USB. ومن هنا بعد تفتح جولة الترحيب والجديد.
+إعدادات التطبيق: اللغة، والمظهر، وحجم الخط، والخلفية الزجاجية، وطريقة الرسم، والبحث عن تحديثات، وتعريفات USB، وإذا الجوال المتصل ينسأل عن الروت. ومن هنا بعد جولة الترحيب والجديد واختصارات الكيبورد.
## steps
-1. **اللغة**: اختر وحدة، والتطبيق يعيد تشغيله فيها. العربي يقلب النافذة كاملة من اليمين لليسار.
+1. **اللغة**: العربي أو الإنجليزي أو الصيني أو الياباني أو الكوري، والتطبيق يعيد تشغيله فيها. العربي يقلب النافذة كاملة من اليمين لليسار.
2. **المظهر**: داكن أو فاتح أو مثل ويندوز، ويتطبق بعد إعادة التشغيل.
-3. **حجم الخط**: صغير أو افتراضي أو كبير أو أكبر، وكل الصفحات تتغير على طول.
+3. **حجم الخط**: صغير أو افتراضي أو كبير أو أكبر، وكل الصفحات تتغير على طول، فالصفحة نفسها هي المعاينة.
+ **الخلفية الزجاجية** (Windows 11): سطح المكتب يبان من ورا النافذة مع تمويه؛ لو مطفأة، النافذة تحتفظ بتدرجها.
4. **طريقة الرسم**: لو النافذة ترمش، أو تختفي عناصر القائمة، أو تطلع الأزرار مخططة (بسبب بعض تعريفات كرت الشاشة وبرامج التحكم عن بعد)، اختر **برمجي (ثابت)**.
5. **التحديثات**: خل **تحقق من التحديثات تلقائياً** شغّال، أو اضغط **تحقق الحين**. الإصدار الجديد يوريك وش تغيّر، وما يتحمّل إلا إذا وافقت.
-6. **تعريفات USB**: توريك إذا تعريف قوقل وتعريف سامسونج مثبّتين. **ثبّته…** يحمّل التعريف من شركته، ويفحصه، ويخلي الويندوز يضيفه. تعريف قوقل لأجهزة Pixel والجوالات على معرّفات قوقل، وتعريف سامسونج لوضع التحميل.
-7. **اعرض الجولة مرة ثانية** يمشيك على التطبيق، و**الجديد** يوريك تغييرات هالإصدار.
+6. **تعريفات USB**: نقطة خضراء أو حمراء تقول إذا تعريف قوقل وتعريف سامسونج مثبّتين. **ثبّته…** يحمّل التعريف من شركته، ويفحصه، ويخلي الويندوز يضيفه. تعريف قوقل لأجهزة Pixel والجوالات على معرّفات قوقل، وتعريف سامسونج لوضع التحميل.
+7. **الجوال**: **اطلب صلاحيات الروت من الجوال لما يتصل بـ ADB** مطفأ افتراضياً. لو شغّلته، الجوال المتصل بـ ADB ينسأل su عشان ينقرأ تقرير Companion (حالة الروت وAVB وتعارض الموديولات)؛ وMagisk يطلع طلب على الجوال أول مرة.
+8. **اعرض الجولة مرة ثانية** يمشيك على التطبيق، و**الجديد** يوريك تغييرات هالإصدار.
+9. **اختصارات الكيبورد**: Ctrl+O يفتح ملف في الصفحة اللي أنت فيها، وCtrl+L السجل، وF1 مساعدة الصفحة، وCtrl+, الإعدادات.
## tips
- التحديث اللي يتحمّل ما ينحفظ إلا إذا طابقت بصمته SHA-256 حق الإصدار، فالملف الخربان أو المبدّل ما يبقى أبداً.
diff --git a/Help/ar/terminal.md b/Help/ar/terminal.md
index 426adff..b92ead8 100644
--- a/Help/ar/terminal.md
+++ b/Help/ar/terminal.md
@@ -10,6 +10,7 @@
- الأوامر هنا تروح للجوال على طول. تفليش أو مسح قسم حساس يطلب منك تكتب اسمه، و**lock** يطلب تكتب lock، و dd على قسم يطلب تكتب dd.
- قفل البوت لودر في جوال عليه أي شي غير نظامه الأصلي ممكن يخليه ما يقلع.
- fastboot -w، ومسح userdata أو metadata أو cache، يمسحون الجوال؛ والتطبيق يسألك أول.
+- flashall وupdate يكتبون كل أقسام الحزمة، وset_active يغيّر السلوت اللي يقلع منه الجوال، وdelete-logical-partition وsnapshot-update يلمسون super: كل واحد يسألك أول.
## tips
- هنا بس adb و fastboot؛ و adb shell التفاعلي ما يشتغل، فاكتب الأمر بعد adb shell.
diff --git a/Help/en/flash.md b/Help/en/flash.md
index fd28efc..77b9052 100644
--- a/Help/en/flash.md
+++ b/Help/en/flash.md
@@ -5,9 +5,9 @@ Flashes a whole OTA (an OTA zip or a payload.bin) to the phone opened on the Dev
1. Open the phone on the **Device** page. In **fastbootd** every partition can be written; the bootloader cannot write logical ones.
2. Back up first on the Backup page.
3. Press **Flash Payload.bin** and pick the OTA zip or payload.bin made for this phone.
-4. Answer the checks: partitions the phone lacks (created empty in fastbootd), a payload without SHA-256, and room in super.
+4. Read the one summary before the flash: the file, the phone (serial, product, slot, mode) and every point to know: partitions the phone lacks (created empty in fastbootd), a payload without SHA-256, room in super, the second slot. A point that can cost data needs **I have read this** ticked. Then **Flash**.
5. Watch the queue: Extracting, Verified, Flashing, Flashed. Partitions fastbootd refuses (a OnePlus modem, for one) are written from the bootloader at the end.
-6. When it says done, restart the phone.
+6. When the green strip says how many partitions were written, press **Restart the phone**, or **Open the log**. The whole flash is also saved as a file (Logs → Open log folder).
## danger
- This replaces the phone's whole software. A flash cut half way (cable, battery, closing the app) can leave the phone unable to start.
@@ -18,7 +18,8 @@ Flashes a whole OTA (an OTA zip or a payload.bin) to the phone opened on the Dev
## tips
- Images are written to the active slot.
-- Nothing is kept on disk: each image is deleted once written.
+- Nothing is kept on disk: each image is deleted once written. Only the log of the flash is kept, in %APPDATA%\Fastboot Studio\logs.
+- **Stop** in the bar above the pages ends the command running; a half-written partition is then flashed again before a restart.
- To flash one partition, use Device → Partitions → Flash.
## terms
diff --git a/Help/en/logs.md b/Help/en/logs.md
index d4e20e4..251a457 100644
--- a/Help/en/logs.md
+++ b/Help/en/logs.md
@@ -5,6 +5,7 @@ Everything the app ran in this session, and every answer from fastboot and adb.
1. Do what went wrong once more, so it is in the log.
2. Press **Copy**, and paste it in your message to the group or in a GitHub issue.
3. **Clear** empties the log; it starts again empty with each start of the app.
+4. **Open log folder**: every payload flash is also saved as a file there (flash-date-serial.log, the newest 30 kept), so what happened to a phone can be read after the app is closed.
## tips
- The log shows serial numbers of your phones. Remove them before posting in public if you prefer.
diff --git a/Help/en/settings.md b/Help/en/settings.md
index 38e8b12..9a573bf 100644
--- a/Help/en/settings.md
+++ b/Help/en/settings.md
@@ -1,14 +1,17 @@
## purpose
-The app's settings: the language, the appearance, the text size, the drawing mode, update checks and USB drivers. The welcome tour and What's new open from here too.
+The app's settings: the language, the appearance, the text size, the glass backdrop, the drawing mode, update checks, USB drivers, and whether a connected phone is asked for root. The welcome tour, What's new and the keyboard shortcuts are here too.
## steps
-1. **Language**: pick one, and the app restarts in it. Arabic turns the whole window right to left.
+1. **Language**: English, Arabic, Chinese, Japanese or Korean; the app restarts in it. Arabic turns the whole window right to left.
2. **Appearance**: Dark, Light, or As Windows. It applies after a restart.
-3. **Text size**: Small, Default, Large or Larger. Every page follows it right away.
+3. **Text size**: Small, Default, Large or Larger. Every page follows it right away, so the page is its own preview.
+ **Glass backdrop** (Windows 11): the desktop shows through the window, blurred; off, the window keeps its own gradient.
4. **Drawing**: if the window flickers, loses menu items or shows striped buttons (some graphics drivers and remote-desktop apps), choose **Software (steady)**.
5. **Updates**: leave **Check for updates automatically** on, or press **Check now**. A new version shows what changed and downloads only if you say so.
-6. **USB drivers**: shows whether Google's and Samsung's drivers are installed. **Install…** downloads the driver from its maker, checks it, and lets Windows add it. Google's fits Pixels and phones on Google's USB ids; Samsung's is for Download mode.
-7. **Show the tour again** walks you through the app; **What's new** lists this version's changes.
+6. **USB drivers**: a green or red dot says whether Google's and Samsung's drivers are installed. **Install…** downloads the driver from its maker, checks it, and lets Windows add it. Google's fits Pixels and phones on Google's USB ids; Samsung's is for Download mode.
+7. **Phone**: **Ask the phone for root when it connects** is off by default. On, a phone over ADB is asked for su so the Companion's report (root state, AVB, module conflicts) is read; Magisk shows a prompt on the phone the first time.
+8. **Show the tour again** walks you through the app; **What's new** lists this version's changes.
+9. **Keyboard shortcuts**: Ctrl+O opens a file on the page you are on, Ctrl+L the log, F1 this page's help, Ctrl+, the settings.
## tips
- An update download is kept only when its SHA-256 matches the release, so a damaged or swapped file never stays.
diff --git a/Help/en/terminal.md b/Help/en/terminal.md
index 694d6cf..0f89e6b 100644
--- a/Help/en/terminal.md
+++ b/Help/en/terminal.md
@@ -10,6 +10,7 @@ Runs your own adb and fastboot commands with the tools that come with the app, w
- Commands here go straight to the phone. A flash or erase of a critical partition asks you to type its name, **lock** asks you to type lock, and dd to a partition asks you to type dd.
- Locking the bootloader on a phone that runs anything but its own stock software can leave it unable to start.
- fastboot -w, and erasing userdata, metadata or cache, wipe the phone; you are asked first.
+- flashall and update write every partition in a package, set_active changes the slot the phone starts from, delete-logical-partition and snapshot-update touch super: each asks first.
## tips
- Only adb and fastboot run here; an interactive adb shell is not supported, so add the command after adb shell.
diff --git a/HelpUI.cs b/HelpUI.cs
index f00f62d..3d4ae47 100644
--- a/HelpUI.cs
+++ b/HelpUI.cs
@@ -99,6 +99,13 @@ static Border pageHeader(TabItem tab)
return (tab.Content as Panel)?.Children.OfType().FirstOrDefault(b => b.Style == style);
}
+ /// Opens the help of (F1); a page without help does nothing.
+ public static void Open(TabItem tab)
+ {
+ if (tab != null)
+ open(tab);
+ }
+
static void open(TabItem tab)
{
string page;
diff --git a/ImageToolsUI.cs b/ImageToolsUI.cs
index a4f863a..170a778 100644
--- a/ImageToolsUI.cs
+++ b/ImageToolsUI.cs
@@ -712,13 +712,14 @@ static void extract()
long start = before;
try
{
- using (FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 1 << 20))
+ using (AtomicFile part = AtomicFile.Create(path, FileAccess.Write, 1 << 20))
{
- SuperImage.Extract(stream, row.Partition, file, new Progress(done =>
+ SuperImage.Extract(stream, row.Partition, part.Stream, new Progress(done =>
{
report(start + done, total);
ui(delegate { row.Progress = size > 0 ? done * 100.0 / size : 100; });
}), token);
+ part.Commit();
}
log(" " + row.Name + ": " + ByteSize.Format(size) + " -> " + path);
ui(delegate
diff --git a/Languages.cs b/Languages.cs
index d70afc1..b0d423d 100644
--- a/Languages.cs
+++ b/Languages.cs
@@ -37,6 +37,9 @@ public Option(string code, string nativeName)
new Option("ko-KR", "한국어"),
};
+ /// The languages Settings and the tour offer: every one whose translation is complete.
+ public static readonly Option[] Offered = All;
+
/// For automated runs: overrides the saved choice without touching it.
const string OverrideVariable = "FASTBOOT_STUDIO_LANG";
diff --git a/LogStore.cs b/LogStore.cs
index 9eef588..06751b4 100644
--- a/LogStore.cs
+++ b/LogStore.cs
@@ -1,4 +1,7 @@
using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
using System.Text;
namespace FastbootEnhance
@@ -7,14 +10,26 @@ namespace FastbootEnhance
/// The session log. Everything fastboot prints, and what the app did about it, lands here;
/// the Logs page and the Flash page's live log both listen to it. It replaces the old
/// pop-up logger, which only recorded while its window happened to be open.
+ /// While a flash runs (), every line also goes to a file in the
+ /// logs folder, so what happened to a phone can be read back after the app is closed.
///
static class LogStore
{
const int MaxChars = 2000000;
const int TrimTo = 1500000;
+ /// Older flash logs are deleted past this many.
+ const int KeepFiles = 30;
+
static readonly object gate = new object();
static readonly StringBuilder text = new StringBuilder();
+ static StreamWriter file;
+
+ /// Where the per-flash logs are kept: %APPDATA%\Fastboot Studio\logs.
+ public static string Folder => Path.Combine(Settings.Folder, "logs");
+
+ /// The file the current flash is written to; null between flashes.
+ public static string CurrentFile { get; private set; }
/// Raised on the writer's thread with the stamped line.
public static event Action LineAdded;
@@ -33,6 +48,17 @@ public static void Append(string line)
text.Append(stamped).Append('\n');
if (text.Length > MaxChars)
text.Remove(0, text.Length - TrimTo);
+ if (file != null)
+ {
+ try
+ {
+ file.WriteLine(stamped);
+ }
+ catch (IOException)
+ {
+ closeFile();
+ }
+ }
}
Action handler = LineAdded;
@@ -55,5 +81,71 @@ public static void Clear()
if (handler != null)
handler();
}
+
+ ///
+ /// Starts writing the log to "flash-<date>-<what>.log" in the logs folder as well,
+ /// until . A folder that cannot be written is simply not written to.
+ /// Returns the file's path, or null.
+ ///
+ public static string BeginFile(string what)
+ {
+ lock (gate)
+ {
+ closeFile();
+ try
+ {
+ Directory.CreateDirectory(Folder);
+ string safe = new string((what ?? "").Select(c => Path.GetInvalidFileNameChars().Contains(c) ? '_' : c).ToArray());
+ string path = Path.Combine(Folder, "flash-" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + (safe.Length > 0 ? "-" + safe : "") + ".log");
+ file = new StreamWriter(path, false, new UTF8Encoding(false)) { AutoFlush = true };
+ file.WriteLine("Fastboot Studio " + MainWindow.version + " · " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+ CurrentFile = path;
+ prune();
+ return path;
+ }
+ catch (Exception e) when (e is IOException || e is UnauthorizedAccessException)
+ {
+ file = null;
+ CurrentFile = null;
+ return null;
+ }
+ }
+ }
+
+ /// Closes the current flash log file, if one is open.
+ public static void EndFile()
+ {
+ lock (gate)
+ closeFile();
+ }
+
+ static void closeFile()
+ {
+ if (file == null)
+ return;
+ try
+ {
+ file.Dispose();
+ }
+ catch (IOException)
+ {
+ }
+ file = null;
+ CurrentFile = null;
+ }
+
+ /// Keeps the newest flash logs.
+ static void prune()
+ {
+ try
+ {
+ List logs = new DirectoryInfo(Folder).GetFiles("flash-*.log").OrderByDescending(f => f.Name).ToList();
+ foreach (FileInfo old in logs.Skip(KeepFiles))
+ old.Delete();
+ }
+ catch (Exception e) when (e is IOException || e is UnauthorizedAccessException)
+ {
+ }
+ }
}
}
diff --git a/MainWindow.xaml b/MainWindow.xaml
index 8eca059..0b23998 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -7,9 +7,9 @@
xmlns:local="clr-namespace:FastbootEnhance"
mc:Ignorable="d"
Title="{x:Static props:Resources.app_name}"
- Height="780" Width="1220" MinHeight="640" MinWidth="1000"
+ Height="780" Width="1220" MinHeight="680" MinWidth="1000"
WindowStartupLocation="CenterScreen"
- Background="{StaticResource Bg}" Foreground="{StaticResource Text}"
+ Background="{StaticResource SkyBrush}" Foreground="{StaticResource Text}"
FontFamily="{StaticResource UiFont}" FontSize="13"
TextOptions.TextFormattingMode="Display" UseLayoutRounding="True">
@@ -17,9 +17,66 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -220,9 +277,6 @@
-
-
-
@@ -439,8 +493,6 @@
-
-
@@ -461,16 +513,34 @@
-
+
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -496,11 +566,11 @@
-
+
-
-
+
+
@@ -509,7 +579,20 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -518,10 +601,16 @@
-
+
-
+
+
+
+
+
+
@@ -531,33 +620,38 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
@@ -566,228 +660,148 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
+
+
-
+
-
-
-
+
+
+
-
+
-
+
@@ -796,64 +810,111 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
@@ -863,164 +924,138 @@
-
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
@@ -1029,222 +1064,135 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
@@ -1253,148 +1201,101 @@
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
+
-
-
+
-
+
-
-
-
+
+
+
-
+
-
+
@@ -1403,114 +1304,62 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
@@ -1520,87 +1369,441 @@
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
@@ -1623,35 +1826,34 @@
-
+
-
-
-
-
+
-
+
-
+
-
+
+
+
-
@@ -1663,6 +1865,8 @@
+
@@ -1679,122 +1883,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -1808,24 +1898,23 @@
-
+
-
-
-
+
-
-
-
+
+
+
@@ -1841,7 +1930,7 @@
-
+
@@ -1850,18 +1939,17 @@
-
-
-
-
+
+
+
+
+
+
+
@@ -1907,6 +1995,154 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 2518eef..d7ffb77 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.IO;
+using System.Linq;
using System.Windows;
namespace FastbootEnhance
@@ -11,7 +12,10 @@ namespace FastbootEnhance
public partial class MainWindow : Window
{
public static MainWindow THIS;
- internal const string version = "2.9.0";
+ internal const string version = "3.0.0";
+
+ /// "v3.0.0", for the rail and About.
+ public static string versionLabel => "v" + version;
public MainWindow()
{
@@ -64,11 +68,19 @@ public MainWindow()
HelpUI.init();
WelcomeUI.init();
- // Esc closes the tour or the help panel, whichever is on top.
+ // Esc closes the tour or the help panel, whichever is on top; then the shortcuts.
PreviewKeyDown += (sender, e) =>
{
- if (!WelcomeUI.HandleKey(e))
- HelpUI.HandleKey(e);
+ if (!WelcomeUI.HandleKey(e) && !HelpUI.HandleKey(e))
+ handleShortcut(e);
+ };
+
+ backdrop.IsChecked = DarkTitleBar.BackdropWanted;
+ backdrop.IsEnabled = DarkTitleBar.BackdropAvailable && Rendering.Chosen == Rendering.Mode.Gpu;
+ backdrop.Click += delegate
+ {
+ Settings.Set(DarkTitleBar.BackdropKey, backdrop.IsChecked == true ? "on" : "off");
+ DarkTitleBar.Apply(this);
};
// Closing mid-flash kills the worker between partitions and can leave the phone
@@ -104,7 +116,7 @@ public MainWindow()
void wireLanguages()
{
Languages.Option current = Languages.CurrentOption;
- foreach (Languages.Option option in Languages.All)
+ foreach (Languages.Option option in Languages.Offered.Concat(new[] { current }).Distinct())
{
Languages.Option choice = option;
System.Windows.Controls.Button button = new System.Windows.Controls.Button
@@ -226,6 +238,10 @@ void showDrivers()
{
settings_google_driver_status.Text = google ? Properties.Resources.driver_google_ok : Properties.Resources.driver_google_missing;
settings_samsung_driver_status.Text = samsung ? Properties.Resources.samsung_driver_ok : Properties.Resources.samsung_driver_missing;
+ settings_google_driver_dot.Fill = Palette.Get(google ? "Ok" : "Danger");
+ settings_samsung_driver_dot.Fill = Palette.Get(samsung ? "Ok" : "Danger");
+ settings_google_driver.Visibility = google ? Visibility.Collapsed : Visibility.Visible;
+ settings_samsung_driver.Visibility = samsung ? Visibility.Collapsed : Visibility.Visible;
}));
}
@@ -263,6 +279,49 @@ void wireTextSize()
};
}
+ ///
+ /// Ctrl+O opens a file on the page that takes one, Ctrl+L the log, F1 this page's help,
+ /// Ctrl+, the settings. Nothing fires while a text box has the keyboard, except F1.
+ ///
+ void handleShortcut(System.Windows.Input.KeyEventArgs e)
+ {
+ bool ctrl = (System.Windows.Input.Keyboard.Modifiers & System.Windows.Input.ModifierKeys.Control) != 0;
+ if (e.Key == System.Windows.Input.Key.F1)
+ {
+ HelpUI.Open(main_tabs.SelectedItem as System.Windows.Controls.TabItem);
+ e.Handled = true;
+ return;
+ }
+ if (!ctrl || System.Windows.Input.Keyboard.FocusedElement is System.Windows.Controls.TextBox)
+ return;
+ if (e.Key == System.Windows.Input.Key.L)
+ {
+ main_tabs.SelectedItem = logs_tab;
+ e.Handled = true;
+ }
+ else if (e.Key == System.Windows.Input.Key.OemComma)
+ {
+ main_tabs.SelectedItem = settings_tab;
+ e.Handled = true;
+ }
+ else if (e.Key == System.Windows.Input.Key.O)
+ {
+ System.Windows.Controls.Button open =
+ main_tabs.SelectedItem == payload_tab ? payload_load_btn
+ : main_tabs.SelectedItem == images_tab ? images_open
+ : main_tabs.SelectedItem == samsung_tab ? samsung_open
+ : main_tabs.SelectedItem == super_tab ? super_import
+ : main_tabs.SelectedItem == root_tab ? root_pick
+ : main_tabs.SelectedItem == flash_tab ? fastboot_flash_payload
+ : null;
+ if (open != null && open.IsEnabled && open.IsVisible)
+ {
+ open.RaiseEvent(new RoutedEventArgs(System.Windows.Controls.Primitives.ButtonBase.ClickEvent));
+ e.Handled = true;
+ }
+ }
+ }
+
void paintTextSizes()
{
foreach (System.Windows.Controls.Button button in text_size_buttons.Children)
@@ -317,6 +376,26 @@ void wireLogs()
}));
log_clear.Click += delegate { LogStore.Clear(); };
+ log_open_folder.Click += delegate
+ {
+ try
+ {
+ Directory.CreateDirectory(LogStore.Folder);
+ Process.Start(new ProcessStartInfo("explorer.exe", FastbootEnhance.Core.Adb.AdbCommand.WindowsArgument(LogStore.Folder))
+ {
+ UseShellExecute = true
+ });
+ }
+ catch (Exception e) when (e is IOException || e is UnauthorizedAccessException || e is System.ComponentModel.Win32Exception)
+ {
+ ThemedDialog.Show(e.Message, Properties.Resources.error, MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ };
+ root_probe.IsChecked = AdbFacts.RootProbe;
+ root_probe.Click += delegate
+ {
+ Settings.Set(AdbFacts.RootProbeKey, root_probe.IsChecked == true ? "on" : "off");
+ };
log_copy.Click += delegate
{
try
diff --git a/OdinWindow.xaml b/OdinWindow.xaml
index 0a6dd83..9fc5732 100644
--- a/OdinWindow.xaml
+++ b/OdinWindow.xaml
@@ -6,8 +6,8 @@
SizeToContent="Height" Width="700" ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
Foreground="{StaticResource Text}" FontFamily="{StaticResource UiFont}" FontSize="13" UseLayoutRounding="True">
-
+
@@ -18,7 +18,7 @@
-
+
-
-
-
-
+
+
+
+
@@ -134,7 +134,7 @@
+ BorderBrush="{StaticResource Line}" BorderThickness="0,1,0,0" CornerRadius="0,0,15,15">
diff --git a/OdinWindow.xaml.cs b/OdinWindow.xaml.cs
index 4a2a0af..c75c265 100644
--- a/OdinWindow.xaml.cs
+++ b/OdinWindow.xaml.cs
@@ -564,7 +564,8 @@ void renderPlan()
"← " + item.Source.Name, Helper.byte2AUnit(item.Source.Size), "Dim", false, true));
// An image whose name the PIT does not know: the person picks its partition.
- List names = last.Pit.Entries.Where(e => !e.IsModem).Select(e => e.Partition).OrderBy(n => n, StringComparer.Ordinal).ToList();
+ List names = last.Pit.Entries.Where(e => !e.IsModem && !OdinFlashPlan.IsProtected(e.Partition))
+ .Select(e => e.Partition).OrderBy(n => n, StringComparer.Ordinal).ToList();
foreach (OdinFlashSource source in sources.Where(x => x.Part == null && !x.FileName.EndsWith(".pit", StringComparison.OrdinalIgnoreCase)
&& last.Pit.ForFile(x.FileName) == null))
{
@@ -628,22 +629,29 @@ void updateFlashButton()
void confirmFlash()
{
- if (plan == null || plan.Blocked || found == null)
+ OdinPortInfo port = found;
+ OdinFlashPlan ready = plan;
+ if (ready == null || ready.Blocked || port == null)
return;
- if (!Helper.confirm(string.Format(Properties.Resources.odin_flash_confirm, plan.Items.Count, Helper.byte2AUnit(plan.TotalBytes)),
+ if (!Helper.confirm(string.Format(Properties.Resources.odin_flash_confirm, ready.Items.Count, Helper.byte2AUnit(ready.TotalBytes)),
Properties.Resources.odin_flash_title))
return;
- flash();
+ // The scan kept running during the question: the phone may have gone, or another appeared.
+ if (found == null || found.Port != port.Port || plan != ready)
+ {
+ log("flash: the phone changed while the question was open; nothing sent");
+ updateFlashButton();
+ return;
+ }
+ flash(port, ready);
}
///
/// The flash itself, off the UI thread. The window cannot be closed meanwhile: a phone
/// left in the middle of a file is worse off than one never started.
///
- void flash()
+ void flash(OdinPortInfo port, OdinFlashPlan flashing)
{
- OdinPortInfo port = found;
- OdinFlashPlan flashing = plan;
OdinReboot reboot = plan_restart.IsChecked == true ? OdinReboot.Normal : OdinReboot.None;
poll.Stop();
reading = true;
diff --git a/PayloadUI.cs b/PayloadUI.cs
index 84798d1..febc41f 100644
--- a/PayloadUI.cs
+++ b/PayloadUI.cs
@@ -234,6 +234,11 @@ static void onExtractClicked(object sender, RoutedEventArgs args)
// zeros is a separate, explicit choice ("ignore unknown operations").
Helper.pathSelect(new Helper.PathSelectCallback(delegate (string path)
{
+ // A boot.img already there may be a patched one the person needs: ask first.
+ List existing = selected.Select(name => Path.Combine(path, name + ".img")).Where(File.Exists).ToList();
+ if (existing.Count > 0 && !Helper.confirm(string.Format(Properties.Resources.images_overwrite,
+ string.Join("\n", existing.Select(Path.GetFileName))), Properties.Resources.confirm_title, true))
+ return;
startExtraction(selected, path, ignoreUnsupported, skipChecks);
}));
}
diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs
index af027a2..3a9ca23 100644
--- a/Properties/Resources.Designer.cs
+++ b/Properties/Resources.Designer.cs
@@ -3036,6 +3036,15 @@ public static string images_overwrite {
return ResourceManager.GetString("images_overwrite", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to The payload names partitions that cannot be put on a command line: {0}. Nothing was flashed. The file may be damaged or tampered with..
+ ///
+ public static string payload_bad_names {
+ get {
+ return ResourceManager.GetString("payload_bad_names", resourceCulture);
+ }
+ }
///
/// Looks up a localized string similar to Done in {0} s.
@@ -9512,5 +9521,469 @@ public static string odin_check_WipesData {
return ResourceManager.GetString("odin_check_WipesData", resourceCulture);
}
}
+
+
+ ///
+ /// Looks up a localized string similar to {0} fits {1} on a UFS phone but not on an eMMC one ({2}; an eMMC partition holds at most {3}), and the PIT does not say which this phone is. On an eMMC phone the bootloader refuses it mid-flash..
+ ///
+ public static string odin_check_MayNotFit {
+ get {
+ return ResourceManager.GetString("odin_check_MayNotFit", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to This command changes the active slot: the phone starts from the other slot next time, whatever is on it. If that slot holds an older or broken system, the phone may not boot. Run it?.
+ ///
+ public static string terminal_slot {
+ get {
+ return ResourceManager.GetString("terminal_slot", resourceCulture);
+ }
+ }
+
+
+ ///
+ /// Looks up a localized string similar to I have read this.
+ ///
+ public static string summary_ack {
+ get {
+ return ResourceManager.GetString("summary_ack", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Confirm the flash.
+ ///
+ public static string flash_summary_title {
+ get {
+ return ResourceManager.GetString("flash_summary_title", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to {0}: {1} partitions, {2}. Nothing is written until every image is extracted and its hash checks out..
+ ///
+ public static string flash_summary {
+ get {
+ return ResourceManager.GetString("flash_summary", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Flash.
+ ///
+ public static string flash_summary_go {
+ get {
+ return ResourceManager.GetString("flash_summary_go", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Phone: {0} · {1} · slot {2} · {3}.
+ ///
+ public static string confirm_device_line {
+ get {
+ return ResourceManager.GetString("confirm_device_line", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Open log folder.
+ ///
+ public static string logs_open_folder {
+ get {
+ return ResourceManager.GetString("logs_open_folder", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Every flash is also saved as a file in the log folder (the newest 30 are kept)..
+ ///
+ public static string logs_file_note {
+ get {
+ return ResourceManager.GetString("logs_file_note", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Stopped by you. The phone may hold a half-written partition; flash it again before restarting..
+ ///
+ public static string step_cancelled {
+ get {
+ return ResourceManager.GetString("step_cancelled", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Stop.
+ ///
+ public static string bar_cancel {
+ get {
+ return ResourceManager.GetString("bar_cancel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Phone.
+ ///
+ public static string settings_phone {
+ get {
+ return ResourceManager.GetString("settings_phone", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Ask the phone for root when it connects over ADB.
+ ///
+ public static string root_probe {
+ get {
+ return ResourceManager.GetString("root_probe", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Reads the Companion's report (root state, AVB, module conflicts). Magisk shows a prompt on the phone the first time. Off, the Phone page asks only when you read the phone yourself..
+ ///
+ public static string root_probe_note {
+ get {
+ return ResourceManager.GetString("root_probe_note", resourceCulture);
+ }
+ }
+
+
+ ///
+ /// Looks up a localized string similar to Phone.
+ ///
+ public static string nav_group_phone {
+ get {
+ return ResourceManager.GetString("nav_group_phone", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Files.
+ ///
+ public static string nav_group_files {
+ get {
+ return ResourceManager.GetString("nav_group_files", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to More tools.
+ ///
+ public static string nav_group_more {
+ get {
+ return ResourceManager.GetString("nav_group_more", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Restart ▾.
+ ///
+ public static string bar_reboot {
+ get {
+ return ResourceManager.GetString("bar_reboot", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No phone connected.
+ ///
+ public static string bar_no_device {
+ get {
+ return ResourceManager.GetString("bar_no_device", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Plug a phone in fastboot in; Android phones over ADB are read on the Phone page..
+ ///
+ public static string bar_no_device_hint {
+ get {
+ return ResourceManager.GetString("bar_no_device_hint", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SN {0}.
+ ///
+ public static string bar_serial {
+ get {
+ return ResourceManager.GetString("bar_serial", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to slot {0}.
+ ///
+ public static string bar_slot {
+ get {
+ return ResourceManager.GetString("bar_slot", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to unlocked.
+ ///
+ public static string bar_unlocked {
+ get {
+ return ResourceManager.GetString("bar_unlocked", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to locked.
+ ///
+ public static string bar_locked {
+ get {
+ return ResourceManager.GetString("bar_locked", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to last: fastboot {0} · {1}.
+ ///
+ public static string status_last {
+ get {
+ return ResourceManager.GetString("status_last", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to {0} s.
+ ///
+ public static string status_seconds {
+ get {
+ return ResourceManager.GetString("status_seconds", resourceCulture);
+ }
+ }
+
+
+ ///
+ /// Looks up a localized string similar to {0} of {1} partitions written.
+ ///
+ public static string flash_result_title {
+ get {
+ return ResourceManager.GetString("flash_result_title", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Open the log.
+ ///
+ public static string flash_result_log {
+ get {
+ return ResourceManager.GetString("flash_result_log", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Restart the phone.
+ ///
+ public static string flash_result_reboot {
+ get {
+ return ResourceManager.GetString("flash_result_reboot", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to critical.
+ ///
+ public static string flash_critical {
+ get {
+ return ResourceManager.GetString("flash_critical", resourceCulture);
+ }
+ }
+
+
+ ///
+ /// Looks up a localized string similar to Drop a file here, or choose one.
+ ///
+ public static string drop_title {
+ get {
+ return ResourceManager.GetString("drop_title", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Phone (Download mode).
+ ///
+ public static string samsung_match_phone_label {
+ get {
+ return ResourceManager.GetString("samsung_match_phone_label", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to not read yet.
+ ///
+ public static string samsung_match_unknown {
+ get {
+ return ResourceManager.GetString("samsung_match_unknown", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About the firmware.
+ ///
+ public static string samsung_details {
+ get {
+ return ResourceManager.GetString("samsung_details", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Drop partition images here, or import them.
+ ///
+ public static string super_drop_hint {
+ get {
+ return ResourceManager.GetString("super_drop_hint", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to system, vendor, product… as raw or sparse images; or read the layout from a phone in fastbootd..
+ ///
+ public static string super_drop_detail {
+ get {
+ return ResourceManager.GetString("super_drop_detail", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Before you start.
+ ///
+ public static string root_prereq {
+ get {
+ return ResourceManager.GetString("root_prereq", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Bootloader unlocked.
+ ///
+ public static string root_prereq_unlock {
+ get {
+ return ResourceManager.GetString("root_prereq_unlock", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to USB debugging on, phone in Android.
+ ///
+ public static string root_prereq_adb {
+ get {
+ return ResourceManager.GetString("root_prereq_adb", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The stock image of the firmware on the phone.
+ ///
+ public static string root_prereq_image {
+ get {
+ return ResourceManager.GetString("root_prereq_image", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to A backup of boot and the data you care about.
+ ///
+ public static string root_prereq_backup {
+ get {
+ return ResourceManager.GetString("root_prereq_backup", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to done.
+ ///
+ public static string root_step_done {
+ get {
+ return ResourceManager.GetString("root_step_done", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to now.
+ ///
+ public static string root_step_current {
+ get {
+ return ResourceManager.GetString("root_step_current", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Glass backdrop behind the window (Windows 11).
+ ///
+ public static string settings_backdrop {
+ get {
+ return ResourceManager.GetString("settings_backdrop", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The desktop shows through the window, blurred. Off, the window keeps its own gradient..
+ ///
+ public static string settings_backdrop_note {
+ get {
+ return ResourceManager.GetString("settings_backdrop_note", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Keyboard shortcuts.
+ ///
+ public static string settings_shortcuts {
+ get {
+ return ResourceManager.GetString("settings_shortcuts", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Open a file on this page.
+ ///
+ public static string shortcut_open {
+ get {
+ return ResourceManager.GetString("shortcut_open", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Log.
+ ///
+ public static string shortcut_log {
+ get {
+ return ResourceManager.GetString("shortcut_log", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Help for this page.
+ ///
+ public static string shortcut_help {
+ get {
+ return ResourceManager.GetString("shortcut_help", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Settings.
+ ///
+ public static string shortcut_settings {
+ get {
+ return ResourceManager.GetString("shortcut_settings", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Links.
+ ///
+ public static string about_links {
+ get {
+ return ResourceManager.GetString("about_links", resourceCulture);
+ }
+ }
}
}
diff --git a/Properties/Resources.ar.resx b/Properties/Resources.ar.resx
index 0803afd..b28d0ff 100644
--- a/Properties/Resources.ar.resx
+++ b/Properties/Resources.ar.resx
@@ -3355,4 +3355,166 @@ adb shell يحتاج أمر بعده، مثل adb shell getprop. وزر إيقا
{0} يمسح كل شي في الجوال (فورمات). استخدم HOME_CSC عشان تحافظ على بياناتك.
+
+ {0} فاضي: ما فيه شي يتفلش.
+
+
+ {0} اسمه مو مثل أسماء رومات سامسونج، فما نقدر نتأكد إنه لهذا الجوال. فلّشه بس إذا متأكد إنه له.
+
+
+ ملف الـ payload فيه أسماء أقسام ما تنفع تنحط في أمر: {0}. ما انفلش شي. يمكن الملف خربان أو معدّل.
+
+
+ {0} يتسع في {1} على جوال UFS بس مو على eMMC ({2}، وقسم eMMC يتحمل {3} بالكثير)، والـ PIT ما يقول نوع هالجوال. على جوال eMMC البوت لودر يرفضه بنص الفلاش.
+
+
+ هذا الأمر يغيّر السلوت الفعّال: الجوال يقلع من السلوت الثاني المرة الجاية، أياً كان اللي عليه. لو فيه نظام أقدم أو خربان ممكن ما يقلع. تنفيذه؟
+
+
+ قريت هذا
+
+
+ تأكيد التفليش
+
+
+ {0}: {1} قسم، {2}. ما ينكتب شي لين تنستخرج كل الصور ويتأكد الهاش حقها.
+
+
+ فلّش
+
+
+ الجوال: {0} · {1} · السلوت {2} · {3}
+
+
+ فتح مجلد السجلات
+
+
+ كل فلاش ينحفظ كمان كملف في مجلد السجلات (آخر 30 ملف تبقى).
+
+
+ وقّفته أنت. ممكن يكون في الجوال قسم نص مكتوب، فلّشه مرة ثانية قبل ما تعيد التشغيل.
+
+
+ إيقاف
+
+
+ الجوال
+
+
+ اطلب صلاحيات الروت من الجوال لما يتصل بـ ADB
+
+
+ يقرأ تقرير Companion (حالة الروت وAVB وتعارض الموديولات). Magisk يطلع طلب على الجوال أول مرة. لو مطفأ، صفحة الجوال تسأل بس لما تقرأ الجوال بنفسك.
+
+
+ الجوال
+
+
+ الملفات
+
+
+ أدوات أكثر
+
+
+ إعادة تشغيل ▾
+
+
+ ما فيه جوال متصل
+
+
+ وصّل جوال بوضع fastboot؛ جوالات أندرويد عبر ADB تنقرأ من صفحة الجوال.
+
+
+ الرقم {0}
+
+
+ السلوت {0}
+
+
+ مفتوح
+
+
+ مقفول
+
+
+ آخر أمر: fastboot {0} · {1}
+
+
+ {0} ث
+
+
+ انكتب {0} من {1} قسم
+
+
+ فتح السجل
+
+
+ إعادة تشغيل الجوال
+
+
+ حرج
+
+
+ اسحب ملف هنا أو اختر…
+
+
+ الجوال (وضع التحميل)
+
+
+ ما انقرأ بعد
+
+
+ عن الروم
+
+
+ اسحب صور الأقسام هنا أو استوردها
+
+
+ system وvendor وproduct… صور raw أو sparse؛ أو اقرأ التوزيع من جوال بوضع fastbootd.
+
+
+ قبل ما تبدأ
+
+
+ البوت لودر مفتوح
+
+
+ تصحيح USB شغّال والجوال بالنظام
+
+
+ صورة النظام الأصلية للروم اللي على الجوال
+
+
+ نسخة احتياطية من boot ومن البيانات المهمة
+
+
+ تم
+
+
+ الحين
+
+
+ خلفية زجاجية خلف النافذة (Windows 11)
+
+
+ سطح المكتب يبان من وراء النافذة مع تمويه. يحتاج رسم «كرت الشاشة» تحت؛ لو مطفأ، النافذة تحتفظ بلونها.
+
+
+ اختصارات الكيبورد
+
+
+ فتح ملف في هالصفحة
+
+
+ السجل
+
+
+ مساعدة هالصفحة
+
+
+ الإعدادات
+
+
+ الروابط
+
diff --git a/Properties/Resources.ja-JP.resx b/Properties/Resources.ja-JP.resx
index 6c817cc..26740d5 100644
--- a/Properties/Resources.ja-JP.resx
+++ b/Properties/Resources.ja-JP.resx
@@ -157,7 +157,7 @@
(仮想A/Bのアップデート中でなければ「COW」で終わる一時パーティションを手動で削除すればこの警告を解消することが可能です)
- 続行をしますか?
+ 続行しますか?
新しい論理パーティションの作成
@@ -169,10 +169,10 @@
現在のスロット
- デバイス名
+ デバイス
- デバイス
+ デバイス名
対象デバイスがありません
@@ -292,10 +292,10 @@
以下の書き込むパーティションが不明な場合があります:
- 不明なパーティションを無視にチェックを入れるとこの警告を無効にすることができます。未知のパーティションですがデバイスの書き込みに失敗したり、文鎮化する訳ではありません。
+ 「不明なパーティションを無視」にチェックを入れると、この警告は表示されなくなります。不明なパーティションがあっても、書き込みに失敗したり文鎮化したりするとは限りません。
- fastbootdモードの再起動が必要な可能性があります。
+ fastbootd モードで再起動する必要があるかもしれません。
システムアップデートの状態
@@ -316,16 +316,18 @@
デバイスのシステムアップデート中です。操作を強制するとデバイスが文鎮化する可能性があります。
- (デバイスのシステムアップデートが完了するまでしばらくお待ちください)
+ (デバイスをシステムで再起動し、アップデート処理が完了するまでしばらくお待ちください)
- 続行をしますか?
+ 続行しますか?
- vbmetaのVerificationを無効化しますか?
+ この vbmeta で dm-verity と AVB の検証を無効にしますか? (--disable-verity --disable-verification)
+
+カスタムまたはパッチ済みのシステムに必要です。ブートローダーがアンロックされている場合のみ有効で、この変更の後は通常、端末のワイプ (初期化) が必要です。
- Verificationを無効化
+ 検証を無効化
ログを記録
@@ -403,7 +405,7 @@
動的パーティションのメタデータがありません
- Payloadを指定していない場合は、「参照」をクリックまたは「ファイルをドラッグ&ドロップ」してください。
+ payload が指定されていません。「参照」をクリックするか、ファイルをドラッグしてください。
パーティション
@@ -463,7 +465,7 @@
Payloadのバージョン
- プログラムは既に実行中です。
+ プログラムは既に実行中です
リリース先: www.akr-developers.com
@@ -480,4 +482,3039 @@
はい
+
+ デバイス
+
+
+ 書き込み
+
+
+ ログ
+
+
+ デバイスの状態、パーティション、クイック操作をリアルタイムで表示
+
+
+ 接続中のデバイス
+
+
+ デバイスをダブルクリックするか、選択して Enter キーを押してください。
+
+
+ bootloader または fastbootd のデバイスがまだありません。接続すると 1 秒以内にここに表示されます。
+
+
+ デバイス変数
+
+
+ クイック操作
+
+
+ 書き込み前のチェック
+
+
+ パーティション操作
+
+
+ ブートローダーはアンロック済み: イメージを書き込めます
+
+
+ ブートローダーはロック中: デバイスは書き込みを拒否します
+
+
+ 保留中の仮想A/Bアップデートはありません
+
+
+ 仮想A/Bアップデートが {0} です: 書き込む前にキャンセルしてください
+
+
+ 残った COW パーティションが見つかりました: 書き込む前に削除してください
+
+
+ fastbootd で実行中: 論理パーティションを書き込めます
+
+
+ bootloader で実行中: 論理パーティションを書き込むには fastbootd で再起動してください
+
+
+ アクティブなスロット: {0}
+
+
+ fastboot モードのデバイス: {0} 台
+
+
+ fastboot.exe が見つかりません
+
+
+ すべてのイメージを並列で抽出し、書き込む前にマニフェストと照合します
+
+
+ payload が選択されていません
+
+
+ 先に「デバイス」ページでデバイスを選んでください。
+
+
+ デバイスが選択されていません
+
+
+ 対象: {0}
+
+
+ 各イメージは書き込む前に SHA-256 で検証されます。
+
+
+ すべてのイメージが正常に抽出されるまで、デバイスには何も書き込まれません。
+
+
+ 待機中
+
+
+ 抽出中
+
+
+ 書き込み中
+
+
+ 完了
+
+
+ 失敗
+
+
+ 待機中
+
+
+ 抽出中
+
+
+ 検証済み
+
+
+ 書き込み中
+
+
+ 書き込み済み
+
+
+ 失敗
+
+
+ 後で bootloader から
+
+
+ bootloader から書き込み中
+
+
+ fastbootd では {0} を書き込めなかったため、アプリが端末を bootloader で再起動してそこで書き込みました。端末は現在 bootloader にあります。
+
+
+ 端末が bootloader で戻ってきませんでした。次のパーティションはまだ書き込まれていません: {0}
+
+
+ 未書き込み
+
+
+ フェーズ
+
+
+ 経過時間
+
+
+ 書き込み済み
+
+
+ リアルタイムログ
+
+
+ このセッションで実行したすべての fastboot コマンドとその出力
+
+
+ コピー
+
+
+ クリア
+
+
+ payload.bin または OTA zip を開いて内容を確認し、イメージを抽出します
+
+
+ payload.bin または OTA zip をここにドロップ
+
+
+ コーデック
+
+
+ 抽出可能
+
+
+ 進捗
+
+
+ 状態
+
+
+ パーティション
+
+
+ サイズ
+
+
+ Payload エンジン: zstd、xz、bzip2、複数エクステント操作、SHA-256 検証付きの並列抽出
+
+
+ よろしいですか?
+
+
+ パーティション「{0}」を消去しますか? 中のデータはすべて失われます。
+
+
+ 論理パーティション「{0}」を super から削除しますか? 元に戻せません。
+
+
+ payload の書き込み中です。今閉じると途中で停止し、デバイスが起動しなくなる可能性があります。それでも閉じますか?
+
+
+ 一部のイメージが不完全です: このビルドで適用できない操作はゼロで埋められ、それらのイメージはマニフェストと照合されていません。
+
+
+ {0} 件の操作をスキップ、未検証
+
+
+ イメージを抽出中です。今閉じると抽出が停止し、未完成のファイルは削除されます。それでも閉じますか?
+
+
+ 次のパーティションは payload に SHA-256 が含まれていないため、書き込む前にイメージを検証できません:
+
+{0}
+
+それでも書き込みますか?
+
+
+ キャンセル
+
+
+ 警告
+
+
+ 完了
+
+
+ 開発者
+
+
+ オリジナルの作者
+
+
+ LibXZR による Fastboot Enhance をベースにしており、MIT ライセンスで公開されています。Copyright © 2021 LibXZR.
+
+
+ オリジナルのプロジェクト
+
+
+ ライセンス
+
+
+ バックアップ
+
+
+ パーティションや端末内の任意のファイルを adb 経由でこのコンピューターに保存します
+
+
+ ADB 接続のデバイス
+
+
+ モデル
+
+
+ モード
+
+
+ デバイスを探しています… USB デバッグを有効にして Android を起動するか、カスタムリカバリー (TWRP、OrangeFox) を起動してください。
+
+
+ adb で接続されたデバイスがありません。開発者向けオプションで USB デバッグを有効にして端末を接続するか、カスタムリカバリーを起動してください。
+
+
+ 端末のロックを解除し、このコンピューターからの USB デバッグを許可してください。
+
+
+ デバイスは「{0}」モードです。パーティションとファイルには Android またはカスタムリカバリーが必要です。
+
+
+ ファイルは今すぐコピーできます。パーティションのバックアップには root (Magisk、KernelSU) またはカスタムリカバリーが必要です。「パーティションテーブルを読み込む」を押して確認してください。
+
+
+ root シェルが使えます (リカバリーまたは adb root): パーティションをバックアップできます。
+
+
+ su による root: パーティションをバックアップできます。
+
+
+ root 権限を要求しています。端末に確認が表示されたら許可してください。
+
+
+ パーティションの読み込みには root が必要です。Magisk または KernelSU で端末を root 化して確認を許可するか、TWRP や OrangeFox などのカスタムリカバリーを起動してください。ファイルは「ファイル」タブから引き続きコピーできます。
+
+
+ このデバイスからパーティションテーブルを読み込めませんでした。
+
+
+ パーティション
+
+
+ ファイル
+
+
+ パーティションテーブルを読み込む
+
+
+ 重要なものを選択
+
+
+ クリア
+
+
+ 名前で絞り込む
+
+
+ 保存先
+
+
+ 変更…
+
+
+ 選択したものをバックアップ
+
+
+ キャンセル
+
+
+ バックアップを検証…
+
+
+ バックアップの検証
+
+
+ フォルダーを開く
+
+
+ 各イメージは SHA-256 とともに backup-info.txt の隣の SHA256SUMS に保存されます。復元するには「デバイス › パーティション」から書き込んでください。
+
+
+ 読み込み中
+
+
+ 保存済み
+
+
+ スキップ
+
+
+ 重要
+
+
+ 先にバックアップするパーティションにチェックを入れるか、「重要なものを選択」を押してください。
+
+
+ 次のパーティションはサイズが大きく、時間がかかり、多くのディスク容量を使います:
+
+{0}
+
+それでもバックアップしますか?
+
+
+ {1} のうち {0} を読み込みました。デバイスからの送信が止まりました (権限がないか切断されました)
+
+
+ {0} 個のパーティションを保存し、SHA-256 を次の場所に記録しました:
+{1}
+
+
+ {1} 個中 {0} 個のパーティションを次の場所に保存しました:
+{2}
+
+
+ 停止しました。未完成のファイルは削除されました。
+
+
+ このフォルダーには SHA256SUMS ファイルがないため、照合できません。
+
+
+ {0} 個すべてのファイルが SHA-256 と一致しました。
+
+
+ {1} 個中 {0} 個のファイルが見つからないか、一致しません:
+
+
+ 上へ
+
+
+ 開く
+
+
+ 内部ストレージ
+
+
+ カメラ
+
+
+ 画像
+
+
+ ダウンロード
+
+
+ ドキュメント
+
+
+ 名前
+
+
+ 種類
+
+
+ フォルダー
+
+
+ ファイル
+
+
+ リンク
+
+
+ このフォルダーは空か、root なしでは Android が読み込みを許可していません。
+
+
+ フォルダー {0} 個、ファイル {1} 個
+
+
+ {0} をコピー中…
+
+
+ コンピューターにコピー
+
+
+ ファイルやフォルダーを選択して (複数は Ctrl または Shift、すべては Ctrl+A) コピーします。フォルダーは中身ごとコピーされます。フォルダーをダブルクリックすると開きます。
+
+
+ 先にコピーするファイルまたはフォルダーを選択してください。
+
+
+ {0} 個の項目を次の場所にコピーしました:
+{1}
+
+
+ {1} 個中 {0} 個の項目を次の場所にコピーしました:
+{2}
+
+
+ コンテナー
+
+
+ OTA zip (そのまま読み込み)
+
+
+ OTA zip (一時フォルダーに展開)
+
+
+ セキュリティパッチ
+
+
+ 部分アップデート
+
+
+ APEX パッケージ
+
+
+ 操作
+
+
+ {0} 個のパーティション · {1} · {2}
+
+
+ {1} 個中 {0} 個のパーティションを書き込みました
+
+
+ {0} ({1} 秒)
+
+
+ 最小化
+
+
+ 最大化
+
+
+ 元に戻す
+
+
+ 閉じる
+
+
+ 言語
+
+
+ 新しい言語は再起動後に適用されます。今すぐ Fastboot Studio を再起動しますか?
+
+
+ 言語を変更する前に、現在の書き込みまたは抽出が終わるまでお待ちください。
+
+
+ イメージツール
+
+
+ Android イメージの確認、変換、展開: sparse、super、ext4、EROFS など
+
+
+ イメージを開く…
+
+
+ イメージをここにドロップ
+
+
+ system.img、super.img、vendor.img… sparse でも raw でも可。複数に分割されたイメージ (system.img_sparsechunk.0、.1…) は、どれか 1 つを開けば残りは自動で見つかります。
+
+
+ 詳細
+
+
+ super 内のパーティション
+
+
+ Sparse チャンク
+
+
+ すべて選択
+
+
+ グループ
+
+
+ 種類
+
+
+ 開始ブロック
+
+
+ ブロック数
+
+
+ パーティションを抽出 (lpunpack)
+
+
+ raw に変換 (simg2img)
+
+
+ sparse に変換 (img2simg)
+
+
+ 分割 (simg2simg)
+
+
+ 分割する最大サイズ
+
+
+ 空のスロット
+
+
+ 複数のファイルが選択されましたが、1 つのイメージの sparse パーツではありません。イメージは 1 つずつ開いてください。
+
+
+ Super (動的パーティション)
+
+
+ ext4 ファイルシステム
+
+
+ EROFS ファイルシステム
+
+
+ F2FS ファイルシステム
+
+
+ Boot イメージ
+
+
+ Vendor boot イメージ
+
+
+ vbmeta (Android Verified Boot)
+
+
+ OTA payload (Payload Dumper で開いてください)
+
+
+ Zip アーカイブ
+
+
+ ファイル
+
+
+ {0} パーツ
+
+
+ 形式
+
+
+ Raw イメージ
+
+
+ 内容
+
+
+ イメージサイズ
+
+
+ ディスク上のサイズ
+
+
+ ブロックサイズ
+
+
+ ブロック
+
+
+ {1} / {2} / {3}
+
+
+ チャンク
+
+
+ CRC-32
+
+
+ 記録なし
+
+
+ メタデータ
+
+
+ バージョン {0}、スロット {1} 個
+
+
+ バックアップコピーから読み込み
+
+
+ 仮想A/B
+
+
+ パーティション
+
+
+ データあり {0} 個、合計 {1} 個
+
+
+ グループ
+
+
+ 制限なし
+
+
+ Super サイズ
+
+
+ パーティションは sparse かどうかに関係なくイメージから直接読み込まれ、すべてのメタデータのチェックサムが検証されます。それぞれ name.img としてイメージの隣のフォルダーに保存されます。
+
+
+ raw への変換では (全パーツをまとめて) 完全なイメージを再構築し、含まれる CRC-32 を検証します。分割すると、fastboot で 1 つずつ書き込めるパーツが作られます。
+
+
+ sparse への変換では、繰り返しのブロックを 1 つのレコードとして保存します。fastboot やファクトリーイメージで使われる形式です。出力は AOSP の img2simg とバイト単位で一致します。
+
+
+ 次のファイルは既に存在し、置き換えられます:
+
+{0}
+
+続行しますか?
+
+
+ {0} 秒で完了
+
+
+ Raw イメージを書き込みました:
+{0}
+{1}
+
+
+ CRC-32 {0}
+
+
+ 記録されたチェックサム {0} 個を検証しました
+
+
+ 最大パーツサイズをメガバイト単位で入力してください (例: 512)。
+
+
+ 分割するには sparse イメージを 1 つだけ開いてください。パーツを結合するには、先に raw に変換してください。
+
+
+ sparse ファイルを {0} 個書き込みました ({1}):
+{2}
+
+
+ 先に抽出するパーティションにチェックを入れてください。
+
+
+ {0} 個のパーティションを次の場所に抽出しました:
+{1}
+
+
+ データ / フィル / don't care
+
+
+ {0} は Fastboot モードです
+
+
+ Fastboot はパーティションを書き込めますが、読み戻すことはできません。市販の端末では Android がそれを許可していません。バックアップは adb で行うため、次のいずれかの方法で端末を Fastboot から抜ける必要があります:
+
+
+ Android を起動
+
+
+ ファイルはすぐにコピーできます。USB デバッグを有効にする必要があり、パーティションのバックアップには root (Magisk または KernelSU) も必要です。
+
+
+ リカバリーを起動
+
+
+ インストール済みのカスタムリカバリー (TWRP、OrangeFox) 用: パーティションとファイル、root 不要。純正リカバリーには adb がありません。
+
+
+ リカバリーイメージをインストールせずに 1 回だけ起動
+
+
+ この端末用の TWRP または OrangeFox イメージを送信して起動します。端末内は何も変更されません。ブートローダーのアンロックが必要です。
+
+
+ リカバリーイメージを選択…
+
+
+ {0} を再起動中… 端末が adb で応答すると、このページは自動で切り替わります。
+
+
+ {0} を端末に送信中…
+
+
+ リカバリーイメージを送信して起動しました。読み込みが終わると端末が adb でここに表示され、バックアップを開始できます。
+
+
+ 端末はイメージを起動しませんでした。
+
+{0}
+
+ブートローダーがアンロックされていること、イメージがこの端末用であることを確認してください。一部の端末 (Samsung など) は、書き込まずにイメージを起動する機能に対応していません。
+
+
+ このファイルは boot またはリカバリーイメージではありません。この端末用の TWRP または OrangeFox の .img を選んでください。
+
+
+ 端末は fastbootd にあり、イメージを起動できません。今すぐ bootloader で再起動しますか? 戻ったらもう一度イメージを選んでください。
+
+
+ fastboot が完了しませんでした: {0}
+
+
+ Super 作成
+
+
+ パーティションイメージを fastboot で書き込める 1 つの super.img にまとめます
+
+
+ super.img からインポート…
+
+
+ 端末からサイズを読み込む
+
+
+ レイアウト
+
+
+ 仮想A/B
+
+
+ A/B
+
+
+ シングルスロット
+
+
+ インポートした super と同じ
+
+
+ Android 11 以降のほとんどの端末。パーティションには _a と _b が付き、ファクトリーイメージと同様にスロット b は空のままです。
+
+
+ 仮想A/B 非対応の A/B 端末 (主に Android 10)。各スロットに super の半分が割り当てられます。
+
+
+ A/B スロットのない端末: パーティション名はそのままです。
+
+
+ グループ、スロット、パーティションの順序は {0} からコピーされます。同じ名前のパーティションはイメージで置き換えられます。
+
+
+ SUPER サイズ (バイト)
+
+
+ 例: 9126805504
+
+
+ グループサイズ (バイト)
+
+
+ グループ名
+
+
+ 自動
+
+
+ 自動: {0}
+
+
+ {1} 中 {0} 使用 · 空き {2}
+
+
+ super のサイズを入力すると、パーティションの使用量が表示されます。
+
+
+ イメージを追加…
+
+
+ フォルダーを追加…
+
+
+ 削除
+
+
+ クリア
+
+
+ パーティションイメージ (system.img、vendor.img、product.img…) を追加するか、既存の super.img のレイアウトをインポートしてください。イメージツールで展開したイメージは自動で見つかります。
+
+
+ イメージ
+
+
+ 空
+
+
+ 出力
+
+
+ Sparse
+
+
+ Raw
+
+
+ Sparse はサイズが小さく、ファクトリーイメージで使われる形式です。Raw は super のフルサイズになります。
+
+
+ 作成後にイメージを検証する
+
+
+ super.img を作成…
+
+
+ super.img を作成中
+
+
+ super.img を検証中
+
+
+ 書き込みコマンド: fastboot flash super super.img。先に端末の現在の super をバックアップしておいてください。
+
+
+ super.img の作成と検証が完了しました: すべてのパーティションを読み戻し、元のイメージと一致しました。
+
+{0}
+{1} · {2} 個のパーティション
+
+
+ super.img の作成が完了しました。
+
+{0}
+{1} · {2} 個のパーティション
+
+
+ super.img は書き出されましたが検証に失敗しました。書き込まないでください:
+
+{0}
+
+
+ super のサイズを入力してください: 端末から読み込むか、super.img をインポートしてください。
+
+
+ super のサイズは 4096 バイトの倍数である必要があります。
+
+
+ このレイアウトのメタデータ設定は使用できません。
+
+
+ メタデータ領域に対してパーティションが多すぎます。
+
+
+ パーティションイメージを 1 つ以上追加してください。
+
+
+ 「{0}」は有効な名前ではありません (英字、数字、_ . - のみ、最大 36 文字)。
+
+
+ 「{0}」が重複しています。
+
+
+ グループ「{0}」は存在しません。
+
+
+ グループ {0} が小さすぎます: パーティションに {1} 必要ですが、上限は {2} です。
+
+
+ パーティションに {0} 必要ですが、super は {1} です。
+
+
+ {0} のレイアウト · {1} · メタデータスロット {2} 個 · グループ {3}
+
+
+ {1} にパーティションイメージが {0} 個見つかりました。
+
+
+ このファイルは super イメージではありません。
+
+
+ 次のファイルはファイルシステムイメージではないため、super には含めないものと思われます (boot や vbmeta などは個別に書き込みます):
+
+{0}
+
+それでも追加しますか?
+
+
+ ファイルシステムイメージではないファイル {0} 個をスキップしました: {1}
+
+
+ このフォルダーにパーティションイメージが見つかりませんでした。
+
+
+ リストからすべてのパーティションイメージを削除しますか?
+
+
+ fastboot モードの端末がありません。bootloader または fastbootd で接続して、もう一度お試しください。
+
+
+ {0} から読み込みました: super は {1} ({2} バイト)。レイアウト: {3}。
+
+
+ 端末から super のサイズを読み込めませんでした:
+
+{0}
+
+
+ 端末から読み込み中…
+
+
+ {0} のイメージを選択
+
+
+ 出力ファイルが super に含めるイメージの 1 つと同じです。別の名前を選んでください。
+
+
+ Qualcomm 書き込みパッケージのピース ({0})
+
+
+ これら {0} 個のファイルは 1 つの {1} イメージのピースで、{2} によって配置されます。1 つのイメージに結合するか、ピースから直接パーティションを抽出してください。
+
+
+ sparse として結合
+
+
+ raw として結合
+
+
+ {0} 個のピースを 1 つのイメージに結合しました:
+
+{1}
+{2}
+
+{3}
+
+
+ 書き込みコマンド: fastboot flash super super.img
+
+
+ raw イメージはパーティションのフルサイズになります。fastboot には sparse の方が小さくて済みます。
+
+
+ 確認のため {0} と入力してください:
+
+
+ 重要なパーティション
+
+
+ {0} はブートチェーンの一部か、端末の固有情報 (IMEI、キャリブレーション、キー) を保持しています。ここに間違ったイメージを書き込むと、bootloader にすら入れなくなったり、どのファームウェアでも戻せないデータが失われたりする可能性があります。
+
+この端末専用のイメージだけを書き込み、現在のイメージのバックアップを取っておいてください。
+
+
+ {0} を消去すると、端末が起動しなくなったり、IMEI、キャリブレーション、キーが完全に消えたりする可能性があります。元に戻すことはできません。
+
+
+ スロットの切り替え
+
+
+ スロット {0} はこのままでは起動できないため、アクティブにしませんでした。
+
+
+ スロット {0} はおそらく起動しません。それでも切り替えますか?
+
+
+ スロット {0} に切り替えますか?
+
+
+ スロット {0} はまだ起動を完了していません。書き込んだ直後なら正常ですが、そうでない場合は端末がもう一方のスロットに戻ったり、起動に失敗したりする可能性があります。
+
+
+ bootloader はスロット {0} を起動不可としてマークしています。
+
+
+ スロット {0} は起動の試行回数が残っておらず、一度も正常に起動していません。
+
+
+ スロット {0} の次のパーティションが存在しないか空です: {1}。先にそのスロット (またはファームウェア全体) を書き込んでください。
+
+
+ イメージを 1 回だけ起動…
+
+
+ 1 回だけ起動
+
+
+ boot またはリカバリーイメージを書き込まずに 1 回だけ起動します。端末を再起動すると、インストール済みの状態に戻ります。
+
+
+ このイメージにはカーネルがありません (init_boot イメージ、またはそれと同じ種類の boot イメージ)。そのため端末はこれ単体では起動できません。完全な boot.img を起動するか、代わりに init_boot を書き込んでください。
+
+
+ これは vendor_boot イメージです: ramdisk とデバイスツリーのみを含み、単体で起動するものはありません。
+
+
+ このファイルは boot またはリカバリーイメージではありません。
+
+
+ 端末は fastbootd にあり、イメージを起動できません。今すぐ bootloader で再起動しますか? その後もう一度イメージを選んでください。
+
+
+ イメージを送信し、端末が起動しています。通常どおり再起動すると、インストール済みのシステムに戻ります。
+
+
+ Super
+
+
+ fastbootd で表示されます: bootloader は super 内のパーティションを一覧表示しません。
+
+
+ 端末が super のサイズを報告していません。
+
+
+ 合計 {0}、空き約 {1}
+
+
+ スロット {0}: {1}
+
+
+ (使用中)
+
+
+ アップデートのコピー (COW): {0}
+
+
+ スロットなし: {0}
+
+
+ super の空き容量が足りません
+
+
+ これらのイメージには super にあと約 {0} の空きが必要ですが ({1})、空きは約 {2} しかありません。fastbootd は "Not enough space to resize partition" で停止します。
+
+空きを作る方法:
+
+
+ スロット {0} のパーティションを削除: {1}。スロット {0} は再度書き込むまで起動しなくなります。
+
+
+ 以前のアップデートの残りを削除: 保留中のアップデートをキャンセルする (更新を中断する) か、COW パーティションを削除します。
+
+
+ super を使用しているものは他にありません。これらのイメージはこの端末の super より大きいです。
+
+
+ 数値は推定値です。それでも書き込みますか?
+
+
+ 存在しないパーティション
+
+
+ 端末に {0} がありません。これらはこのアップデートが super 内に配置するパーティションなので、今ここで (空の状態で) 作成してから書き込むことができます。
+
+fastbootd は新しいパーティションを端末本来のグループ (main_a など) ではなく "default" グループに置きます。端末は通常どおり起動し、次回のフルアップデートかファクトリーの super の書き込みで元のグループに戻ります。
+
+作成して続行しますか?
+
+
+ fastbootd は新しいパーティションを端末本来のグループ (main_a など) ではなく "default" グループに置きます。動作には問題なく、次回のフルアップデートで元のグループに戻ります。
+
+
+ USB チェック
+
+
+ USB チェック
+
+
+ {0}: Windows にドライバーがないため、fastboot と adb から認識できません。
+
+
+ {0}: ドライバーはインストールされていますが動作していません (コード {1})。抜き差しするか、ドライバーを再インストールしてください。
+
+
+ {0}: 端末は QFIL で使われる Qualcomm 緊急ダウンロードモード (EDL、9008) です。fastboot はこのモードを扱えません。電源キーを 10〜15 秒長押しして抜けてください。
+
+
+ {0}: 端末は SP Flash Tool で使われる MediaTek BROM または preloader モードです。fastboot は扱えません。ケーブルを抜き、端末のキーの組み合わせで fastboot を起動してください。
+
+
+ {0}: 端末は Unisoc (Spreadtrum) のダウンロードモードです。fastboot は扱えません。ケーブルを抜き、端末のキーの組み合わせで fastboot を起動してください。
+
+
+ {0}: 端末は Samsung のダウンロード (Odin) モードです。Samsung の端末には fastboot がなく、このモードでは Odin を使います。
+
+
+ {0}: ドライバーが正常に動作している fastboot インターフェースです。端末が一覧に表示されない場合は、抜き差ししてください。
+
+
+ {0}: 端末は fastboot ではなく Android またはリカバリー (adb) で接続されています。
+
+
+ Windows は USB 上に端末を認識していません。
+
+• データ通信対応のケーブルを使ってください。充電専用のケーブルも多くあります。
+• 別の USB ポートを試してください。可能なら PC 本体の USB 2.0 ポートに直接接続してください。
+• 端末が fastboot (bootloader または fastbootd) になっているか、adb の場合は USB デバッグが有効になっているか確認してください。
+
+
+ ドライバーのインストール方法: Google USB Driver (developer.android.com/studio/run/win-usb) または端末メーカーのドライバーを入手してください。それでも Windows が端末をドライバーなしと表示する場合は、デバイスマネージャーで右クリック → ドライバーの更新 → コンピューターを参照 → 一覧から選択 → Android Device → fastboot なら "Android Bootloader Interface"、adb なら "Android ADB Interface" を選んでください。
+
+
+ 今すぐデバイスマネージャーを開きますか?
+
+
+ ここに表示されるよう、今すぐ bootloader で再起動しますか?
+
+
+ adb で複数の端末が接続されています ({0})。正しい端末が再起動するよう、他の端末を外してからもう一度お試しください。
+
+
+ adb で使える端末がありません。端末で USB デバッグを許可してから、もう一度お試しください。
+
+
+ 外観
+
+
+ ダーク
+
+
+ ライト
+
+
+ Windows の設定に合わせる
+
+
+ 新しい外観は再起動後に適用されます。今すぐ Fastboot Studio を再起動しますか?
+
+
+ 外観を変更する前に、現在の書き込みまたは抽出が終わるまでお待ちください。
+
+
+ ターミナル
+
+
+ アプリに付属のツールで adb や fastboot のコマンドを直接実行します
+
+
+ フォルダー…
+
+
+ フォルダー: {0} · パスなしで指定したファイルはここから探します。ファイルを行にドロップするとパスが追加されます
+
+
+ 実行
+
+
+ 停止
+
+
+ adb または fastboot のコマンドを入力して Enter キーを押してください。例: fastboot getvar all
+上下キーで以前のコマンドを呼び出せます。詳しくは help と入力してください。
+
+
+ コマンドは adb または fastboot で始まり、アプリに付属のツールで実行されます。
+ cd FOLDER ファイルを読み込むフォルダーを変更
+ clear この画面をクリア
+端末を文鎮化させる可能性があるコマンド (重要なパーティション、ブートローダーのロック、パーティションへの dd) は、先に単語の入力を求めます。データを消去するコマンドも確認を求めます。
+adb shell の後にはコマンドが必要です (例: adb shell getprop)。「停止」で logcat など実行中のものを終了します。
+
+
+ ここで実行できるのは adb と fastboot のコマンドだけです。行を adb または fastboot で始めてください。
+
+
+ ここでは adb shell の後にコマンドが必要です。例: adb shell getprop ro.product.model
+
+
+ 引用符が閉じられていません。
+
+
+ 書き込み中です。同時に端末と通信しないよう、終わるまでお待ちください。
+
+
+ 実行しませんでした。
+
+
+ [終了コード {0}]
+
+
+ [停止しました]
+
+
+ フォルダーが存在しません: {0}
+
+
+ コマンドを開始できませんでした: {0}
+
+
+ このコマンドは {0} を書き込みまたは消去します。これはブートチェーンまたは端末の固有情報 (IMEI、キャリブレーション、キー) の一部です。間違ったイメージを書き込むと、bootloader にすら入れなくなったり、どのファームウェアでも戻せないデータが失われたりする可能性があります。
+
+
+ ブートローダーをロックします。純正以外のソフトウェア (カスタム ROM、root、パッチ済み boot、GSI) を使っている端末では、ロックされたブートローダーは起動を拒否します。アンロックするまで端末が起動しなくなる可能性があり、アンロックするとデータは消去されます。
+
+
+ dd で端末のパーティションに直接書き込みます。イメージやパーティションは一切チェックされません。間違えると端末が起動しなくなる可能性があります。
+
+
+ このコマンドは端末のユーザーデータ (アプリ、写真、ファイル) を消去します。実行しますか?
+
+
+ {0} に書き込む前のチェック
+
+
+ イメージを読み込めませんでした: {0}
+
+
+ このファイルは boot イメージではありませんが、{0} には boot イメージが入ります。ここに書き込むと、端末はおそらく起動しなくなります。
+
+
+ このイメージにはカーネルがありません (init_boot イメージ、またはそれと同様の構成) が、{0} にはカーネルが必要です。端末は起動しません。
+
+
+ この端末には {0} があります。このイメージはそこに書き込みます。
+
+
+ このイメージにはカーネルが含まれていますが、{0} には ramdisk しか入りません。カーネル入りのイメージは boot 用です。
+
+
+ このイメージは {0} 用ではありません: vendor_boot イメージは vendor_boot に、boot イメージは決して vendor_boot には書き込みません。
+
+
+ カーネルは {0} 用にビルドされていますが、端末は {1} で動作しています。別の KMI 用のカーネルは起動せず、端末はブートループします。
+
+
+ カーネルのバージョンは {0} ですが、端末は {1} で動作しています。起動しない可能性があります。
+
+
+ イメージのセキュリティパッチ ({0}) が端末のもの ({1}) より古いです。端末によっては起動を拒否したり、keystore に保存されたキー (指紋、一部アプリのログイン) が失われたりします。
+
+
+ カーネル: {0}
+
+
+ Root: {0}
+
+
+ root 化されていません (純正イメージ)。
+
+
+ ヒント: Android の起動中にこの端末を一度「バックアップ」ページで開くと、カーネルとセキュリティパッチもここでチェックされます。
+
+
+ {1} に {0} が adb で報告した内容と比較しました。
+
+
+ それでも {0} に書き込みますか?
+
+
+ ヘッダー
+
+
+ バージョン {0}、ページ {1}
+
+
+ Android
+
+
+ セキュリティパッチ
+
+
+ カーネル
+
+
+ KMI
+
+
+ GKI ではない
+
+
+ カーネルの圧縮
+
+
+ {0} (読み込み不可)
+
+
+ バージョンが見つかりません
+
+
+ なし (init_boot)
+
+
+ Ramdisk
+
+
+ {0}、ファイル {1} 個
+
+
+ Root
+
+
+ なし (純正)
+
+
+ コマンドライン
+
+
+ カーネル (adb で最後に確認)
+
+
+ セキュリティパッチ (adb 経由)
+
+
+ {0} は Android で起動中: カーネル {1}。
+
+
+ {0} は Android で起動中: カーネル {1}、Fastboot Studio Companion {2} ({3})。
+
+
+ カーネルが記録されたので、書き込む前に boot イメージと照合されます。bootloader で再起動するには「USB チェック」を使ってください。
+
+
+ Companion (adb 経由)
+
+
+ AVB (adb 経由)
+
+
+ モジュールの競合 (adb 経由)
+
+
+ 隠蔽モジュールがプロパティを変更しています
+
+
+ なし
+
+
+ 前回端末が Android で起動していたとき、Fastboot Studio Companion が root モジュール間の競合を {0} 件検出しました。
+
+
+ このイメージは {0} で root 化されていますが、端末は {1} を使っています。書き込むと {1} のモジュールと設定は動作しなくなります。
+
+
+ Root
+
+
+ Magisk、KernelSU、APatch で端末をステップごとに root 化します
+
+
+ 1 · root アプリと純正イメージ
+
+
+ root に使うアプリを選び、次に端末で現在動作しているファームウェアの純正イメージを選んでください: boot.img または init_boot.img、または OTA 全体 (payload.bin または zip) を選ぶと適切なイメージが取り出されます。
+
+
+ イメージまたは OTA を選択…
+
+
+ 読み込み中…
+
+
+ {0} · {1}
+
+
+ 純正、root 化されていません
+
+
+ 既に root 化済み: {0}
+
+
+ {0} は init_boot を持つ端末 (Android 13 以降) では init_boot にパッチを当てます。この OTA には init_boot があるため、そのイメージを使います。
+
+
+ このファイルは boot または init_boot イメージではありません。
+
+
+ この OTA には boot または init_boot イメージがありません。
+
+
+ このイメージは既にパッチ済みです ({0})。端末で動作しているのと同じファームウェアの純正イメージにパッチを当ててください。
+
+
+ APatch は boot に含まれるカーネルにパッチを当てます: boot.img (または OTA) を選んでください。
+
+
+ 2 · 端末に送信
+
+
+ 端末は USB デバッグを有効にした状態で Android を起動している必要があります。イメージは Download フォルダーに {0} として保存されます。
+
+
+ 端末に送信
+
+
+ adb で端末が見つかりません。Android を起動し、USB デバッグを許可した状態で接続してください。
+
+
+ {1} の {0} に送信しました。
+
+
+ イメージを送信できませんでした: {0}
+
+
+ 3 · 端末でパッチを当てる
+
+
+ Magisk を開く → インストール → パッチするファイルの選択 → Download → {0} → 次に進む。「All done」と表示されたら、下のボタンを押してください。
+
+
+ KernelSU を開く → インストール → ファイルを選択 → Download → {0} → 次へ。完了したら、下のボタンを押してください。
+
+
+ APatch を開く → パッチ (インストールボタン) → boot イメージを選択 → Download → {0}、スーパーキーを設定 → 開始。完了したら、下のボタンを押してください。
+
+
+ パッチ済みイメージを取得
+
+
+ 純正イメージを送信した後、Download にパッチ済みイメージが見つかりません。先に root アプリでパッチを当ててください。
+
+
+ {0} を取得しました: {1}。
+
+
+ パッチ済みイメージに root が見つかりませんでした。
+
+
+ パッチ済みイメージが純正イメージと同じ種類ではありません (一方にはカーネルがあり、もう一方にはありません)。
+
+
+ パッチ済みイメージのカーネルが純正イメージと異なります: 別のイメージにパッチを当てた可能性があります。
+
+
+ このパッチ済みイメージは正しくないようです:
+
+
+ 4 · 書き込む
+
+
+ 端末が bootloader で再起動し、パッチ済みイメージがアクティブなスロットの {0} に書き込まれます。ブートローダーのアンロックが必要です。純正イメージは後で元に戻せるようフォルダーに残ります。
+
+
+ bootloader で再起動して書き込む
+
+
+ まず 1 回だけ試す
+
+
+ パッチ済み boot イメージを書き込まずに、端末を 1 回だけ起動します。正常に起動したら書き込むか、root アプリ自体にインストールさせてください (直接インストール)。
+
+
+ フォルダーを開く
+
+
+ {0} を bootloader で再起動し、{1} を {2} に書き込みますか?
+
+ブートローダーのアンロックが必要です。その後端末が起動しない場合は、同じ方法でフォルダー内の純正イメージを {2} に書き込んでください。
+
+
+ bootloader の端末を待っています…
+
+
+ 2 分以内に端末が fastboot に表示されませんでした。ドライバーを確認してから (デバイスページ → USB チェック)、デバイスページから {0} を書き込んでください。
+
+
+ {0} を書き込み中…
+
+
+ 書き込みに失敗しました: {0}
+
+
+ {0} にパッチ済みイメージを書き込みました。今すぐ端末を再起動しますか?
+
+
+ 完了しました。端末が起動したら root アプリを開いてください: セットアップの完了ともう一度の再起動を求められる場合があります。
+
+
+ パッチ済みイメージで端末を 1 回だけ起動中…
+
+
+ イメージを起動できませんでした: {0}
+
+
+ 端末はパッチ済みイメージで起動中です。root が動作したら書き込むか、root アプリの「直接インストール」を使ってください。
+
+
+ {0} でパッチ済み
+
+
+ 端末
+
+
+ Android 起動中の端末: スペック、セキュリティ、端末内のバックアップ。Fastboot Studio Companion があればさらに詳しく表示します。
+
+
+ リカバリー
+
+
+ bootloader で再起動
+
+
+ 再読み込み
+
+
+ Android で起動中の端末がありません
+
+
+ USB デバッグを有効にして端末を接続し、端末に確認が表示されたらこのコンピューターを許可してください。bootloader の端末は「デバイス」ページに表示されます。
+
+
+ {0} が待機中です: 端末の画面でこのコンピューターからの USB デバッグを許可してください。
+
+
+ {0} を読み込み中…
+
+
+ デバイス
+
+
+ モデル
+
+
+ チップ
+
+
+ Android
+
+
+ セキュリティパッチ
+
+
+ スロット
+
+
+ バッテリー
+
+
+ ストレージ
+
+
+ カーネルとセキュリティ
+
+
+ カーネル
+
+
+ ブートローダー
+
+
+ Root
+
+
+ ロック中
+
+
+ アンロック済み
+
+
+ 見つかりません
+
+
+ Companion で確認できます
+
+
+ ROM または隠蔽モジュールが boot プロパティ (ro.boot.*) をロック状態に見えるよう変更しています。ここに表示されているのが本当の状態です: root はアンロックされたブートローダーでしか動作しません。
+
+
+ AVB は端末のプロパティに基づく値です。隠蔽モジュールによって変更されている可能性があります。Companion はブートローダー自身の値を読み取ります。
+
+
+ 書き込む前に、boot イメージはこのカーネルと照合されます。
+
+
+ 健全性 {0}%
+
+
+ {0} サイクル
+
+
+ 充電 {0}%
+
+
+ {0} · 消耗 {1}–{2}%
+
+
+ {0} · 定格寿命を超過
+
+
+ 予備ブロックが残りわずか
+
+
+ A/B スロットなし
+
+
+ 動的
+
+
+ ベータ
+
+
+ root マネージャーに Companion のレポートを要求しています… 確認が表示されたら Shell を許可してください。
+
+
+ Companion は Magisk、KernelSU、APatch 用の root モジュールですが、この端末は root 化されていません。ここに表示されている内容はすべて Companion なしで読み取ったものです。
+
+
+ この端末にはインストールされていません。インストールすると、このページにブートローダー自身の AVB 状態、root マネージャー、ストレージの消耗度、モジュール間の競合も表示されます。
+
+
+ Companion を入手
+
+
+ root が拒否されたか、応答がありませんでした。root マネージャーで Shell を許可してから、再読み込みしてください。
+
+
+ {0} 個のモジュール、競合なし
+
+
+ モジュール間の競合: {0} 件
+
+
+ 同じファイル: {0}
+
+
+ 同じファイル {1} 個: {0}
+
+
+ {0} がフォルダーを置き換え、{1} を隠しています
+
+
+ 同じプロパティ: {0}
+
+
+ と
+
+
+ 端末内のバックアップ
+
+
+ {0} 個のバックアップ · {1}
+
+
+ 最新: {0}
+
+
+ PC のバックアップフォルダーを開く
+
+
+ 端末にはまだバックアップがありません。Companion の「バックアップ」タブから /sdcard/FastbootStudio/Backups に作成できます。
+
+
+ root なしで adb 経由でコピーし、すべてのファイルを SHA256SUMS と照合します。デバイスページから、これらを使ってパーティションを書き戻せます。
+
+
+ バックアップ
+
+
+ 種類
+
+
+ ファイル
+
+
+ サイズ
+
+
+ 日付
+
+
+ PC 上
+
+
+ フル
+
+
+ 重要
+
+
+ Boot
+
+
+ なし
+
+
+ コピー済み
+
+
+ コピー中…
+
+
+ 検証中…
+
+
+ ✓ コピー済み・一致
+
+
+ ✗ {1} 個中 {0} 個のファイルが一致しません
+
+
+ コピーに失敗しました: {0}
+
+
+ コピーして検証
+
+
+ 開く
+
+
+ {0} を {1} で再起動しますか?
+
+
+ 端末が再起動しませんでした: {0}
+
+
+ 描画
+
+
+ ソフトウェア (安定)
+
+
+ グラフィックカード
+
+
+ ソフトウェア描画にすると、一部のグラフィックドライバーやリモートデスクトップアプリで起こるちらつき、メニュー項目の消失、ボタンの縞模様がなくなります。
+
+
+ 新しい描画モードは再起動後に適用されます。今すぐ Fastboot Studio を再起動しますか?
+
+
+ 両方のスロットに書き込む (a と b)
+
+
+ modem や boot などのファームウェアパーティションは、もう一方のスロットにも書き込まれます。super 内のパーティションは除外されます。
+
+
+ 使用中のスロットに加えて、次のパーティションをスロット {0} にも書き込みます。端末がそのスロットから起動した場合でも同じファームウェアが使われます:
+
+{1}
+
+super 内のパーティション (system、vendor…) は除外されます。続行しますか?
+
+
+ もう一方のスロットにも書き込みました: {0}
+
+
+ アップデート
+
+
+ 自動でアップデートを確認する
+
+
+ 1 日に 1 回、アプリの GitHub ページから確認します。オフの場合は、ここから手動で確認してください。
+
+
+ 今すぐ確認
+
+
+ 確認中…
+
+
+ 最新バージョンです ✓
+
+
+ {0} が利用可能です
+
+
+ 確認できませんでした: {0}
+
+
+ アップデート {0} が利用可能
+
+
+ アップデートが利用可能: {0}
+
+
+ 現在 v{0} · {1} リリース
+
+
+ 現在 v{0}
+
+
+ 新機能と修正点
+
+
+ 変更点はリリースページに記載されています。
+
+
+ アプリの GitHub ページからダウンロードし、開く前に SHA-256 を検証します。winget でインストールした場合: winget upgrade IFOKNR.FastbootStudio
+
+
+ アップデートをダウンロード
+
+
+ 後で
+
+
+ このバージョンをスキップ
+
+
+ リリースページを開く
+
+
+ {0} をダウンロード中…
+
+
+ ダウンロードが終わると SHA-256 が検証され、フォルダーが開きます。アプリを閉じて展開し、新しいバージョンを実行してください。
+
+
+ ダウンロード完了、SHA-256 も一致 ✓
+
+
+ ダウンロードフォルダー: {0}
+
+
+ アプリを閉じ、古いものに上書きして (または任意のフォルダーに) 展開し、FastbootStudio.exe を実行してください。設定とバックアップはそのまま残ります。
+
+
+ フォルダーを開いてアプリを閉じる
+
+
+ フォルダーを開く
+
+
+ 閉じる
+
+
+ アップデートをダウンロードできませんでした
+
+
+ ダウンロードしたファイルが SHA-256 と一致しないため削除しました。もう一度試すか、リリースページからダウンロードしてください。
+
+
+ リリースに zip の SHA-256 が記載されていないため、アプリは保存しません。リリースページからダウンロードしてください。
+
+
+ このリリースにはアプリでダウンロードできる Windows 用 zip がありません。リリースページを開いて入手してください。
+
+
+ ダウンロードできませんでした: {0}
+
+
+ アプリは書き込みまたは抽出中です。完了してから閉じてください。
+
+
+ すべてのファイル
+
+
+ Samsung
+
+
+ Samsung のファームウェアを開き、必要なイメージを取り出し、端末に合うか確認して、ダウンロードモードで書き込みます。
+
+
+ Samsung のファームウェアを開く
+
+
+ AP、BL、CP、CSC、HOME_CSC (.tar.md5)、それらが入ったフォルダー、または配布元の zip。ここにドロップするか選択してください。
+
+
+ ファームウェアを開く…
+
+
+ フォルダーを開く…
+
+
+ ファームウェアを読み込み中…
+
+
+ zip を展開中 · {0}%
+
+
+ Samsung ファームウェア
+
+
+ Samsung のファームウェアファイルが見つかりませんでした。ファイル名は AP_、BL_、CP_、CSC_、HOME_CSC_ で始まり、.tar.md5 で終わります。
+
+
+ ファームウェアファイル
+
+
+ このファームウェアについて
+
+
+ モデル
+
+
+ ビルド (PDA)
+
+
+ ブートローダーのバイナリ
+
+
+ ビルド日
+
+
+ Android
+
+
+ CSC
+
+
+ 読み込まず (ファームウェアのパーツではありません)
+
+
+ MD5 {0}%
+
+
+ MD5 ✓
+
+
+ MD5 なし
+
+
+ MD5 ✕ 破損
+
+
+ 読み込み不可
+
+
+ {0} の MD5 を検証中
+
+
+ 各ファイルの MD5 を検証中
+
+
+ {0} は破損しているか不完全です: MD5 が一致しません。もう一度ダウンロードしてください。このファイルからは何も取り出しません。
+
+
+ ファームウェアと端末の照合
+
+
+ 端末を確認
+
+
+ adb で端末を探しています…
+
+
+ USB デバッグを有効にした Android の状態で端末を接続し、「端末を確認」を押してください。ファームウェア単体のチェックは引き続き行われます。
+
+
+ adb で {0} ({1}) と比較しました。
+
+
+ このファームウェアはお使いの端末に適合します
+
+
+ Odin で書き込んでください: AP、BL、CP、そしてデータを残すなら HOME_CSC。
+
+
+ 書き込む前にお読みください
+
+
+ ファームウェアは書き込めますが、先に以下の点を確認してください。
+
+
+ このファームウェアをお使いの端末に書き込まないでください
+
+
+ Odin で端末に拒否されるか、別の端末用に作られています。
+
+
+ ファームウェア {0} · 端末 {1}
+
+
+ この端末は Samsung ではありません
+
+
+ 同じモデル
+
+
+ 別のモデル用
+
+
+ 同じブートローダーバイナリ
+
+
+ 新しいブートローダーバイナリ
+
+
+ ファームウェア {0} · 端末 {1}。書き込み後は、バイナリ {1} のファームウェアをインストールできなくなります。
+
+
+ ブートローダーバイナリが端末より古い
+
+
+ ファームウェア {0} · 端末 {1}。Samsung はこのダウングレードをブロックしており、Odin は SW REV CHECK FAIL で停止します。
+
+
+ Android バージョン
+
+
+ 端末より古い Android
+
+
+ ファームウェア {0} · 端末 {1}。戻すには完全な CSC が必要で、端末のデータが消去されます。
+
+
+ お使いの地域がこのファームウェアに含まれています
+
+
+ 別の CSC (地域)
+
+
+ ファームウェア {0} · 端末 {1}。変更するには完全な CSC が必要で、端末のデータが消去されます。
+
+
+ CSC は端末のデータを消去します
+
+
+ データを残すには、Odin の CSC 欄に HOME_CSC を入れてください。
+
+
+ このファームウェアには HOME_CSC がありません: 書き込むと端末のデータが消去されます。
+
+
+ 異なるファームウェアのファイルが混在
+
+
+ 中身
+
+
+ Boot イメージ
+
+
+ {0} 個選択 · {1}
+
+
+ 元ファイル
+
+
+ ファイル
+
+
+ 選択したものを抽出 (lz4 を解除)
+
+
+ {0} 個のファイルを抽出中
+
+
+ {0} 個のファイルを LZ4 を解除して次の場所に保存しました:
+{1}
+
+
+ 先に取り出すファイルを選んでください。
+
+
+ super をイメージツールで開く
+
+
+ Magisk で root 化…
+
+
+ Magisk 用のファイルを準備中
+
+
+ 先に AP ファイルを開いてください: Magisk はその init_boot (または boot) と vbmeta にパッチを当てます。
+
+
+ {0} は端末の Download フォルダーにあります。
+
+Magisk で: インストール › パッチするファイルの選択 › このファイルを選びます。Magisk が完了を表示したら OK を押すと、パッチ済みファイルを取得して検証します。
+
+
+ {0} を次の場所に用意しました:
+{1}
+
+adb で端末が見つかりませんでした。端末にコピーして Magisk でパッチを当て (インストール › パッチするファイルの選択)、「Magisk ファイルを検証」で結果を確認してください。
+
+
+ パッチ済みファイルを取得中
+
+
+ 端末の Download フォルダーに、送信したファイルより新しい magisk_patched の tar が見つかりませんでした。Magisk でパッチを当ててから、もう一度お試しください。
+
+
+ Magisk ファイルを検証…
+
+
+ パッチ済みファイルを検証中
+
+
+ {0} は Magisk でパッチ済みです ✓
+
+Odin で {1} を AP に入れ、同じファームウェアの BL、CP、CSC と一緒に書き込んでください。AP だけを書き込まないでください。
+• 初めて Magisk を入れる場合: HOME_CSC ではなく CSC。端末のデータは消去されますが、Magisk にはこの消去が必要です。
+• 既に root 化済みの端末のアップデート: データを残すため HOME_CSC。
+
+ブートローダーのアンロックが必要で、Knox は永久にトリップします。
+
+
+ このファイル内の {0} は Magisk でパッチされていません。root 化のためにこれを書き込まないでください。
+
+
+ この tar には boot または init_boot イメージがありません。
+
+
+ Odin 用 tar…
+
+
+ イメージ
+
+
+ Odin 用の tar を作成中
+
+
+ {0} は Odin の AP 欄に使えます。中身: {1}。
+
+
+ {0}: Odin のファイル名は 99 文字以内である必要があります。
+
+
+ イメージは LZ4 を解除した通常の .img として保存されます。super は sparse のままで、イメージツールで展開できます。書き込みは Odin で行います。
+
+
+ ヘルプ
+
+
+ ヘルプを閉じる (Esc)
+
+
+ このページのヘルプ
+
+
+ Telegram で質問
+
+
+ それでも解決しない場合は、グループで質問してください。
+
+
+ このページのヘルプはまだありません。
+
+
+ このページの用途
+
+
+ 手順
+
+
+ 知っておくと便利
+
+
+ 用語
+
+
+ 危険: 先にお読みください
+
+
+ ツアーと新機能
+
+
+ ツアーをもう一度表示
+
+
+ {0} の新機能
+
+
+ このバージョンにはリリースノートが含まれていません。
+
+
+ {0} の新機能
+
+
+ Fastboot Studio がアップデートされました。変更点は次のとおりです:
+
+
+ OK
+
+
+ ツアーを見る
+
+
+ スキップ
+
+
+ 戻る
+
+
+ 次へ
+
+
+ 開始
+
+
+ Fastboot Studio へようこそ
+
+
+ 書き込み、root、バックアップをひとつのアプリで。まずは簡単なツアーをどうぞ。1 分ほどで終わり、スキップもできます。
+
+
+ 使用中
+
+
+ 各ページの役割
+
+
+ 各ページには 1 つの役割があり、どのページにも隅に ? があって手順を説明します。ツアー終了後に開くページを選んでください。
+
+
+ ツアー終了後にこのページを開く
+
+
+ fastboot の端末: 状態、パーティション、クイック再起動
+
+
+ Android の端末: スペック、セキュリティ、バックアップ
+
+
+ OTA 全体を書き込み。全イメージを事前に検証
+
+
+ OTA の中身を確認してイメージを取り出す
+
+
+ boot イメージの確認、sparse の変換、super の展開
+
+
+ パーティションイメージから 1 つの super.img を作成
+
+
+ Samsung ファームウェア: MD5、適合チェック、Magisk、Odin 用 tar
+
+
+ パーティションとファイルをこの PC に保存
+
+
+ Magisk、KernelSU、APatch でステップごとに root 化
+
+
+ adb と fastboot のコマンドを自分で実行
+
+
+ アプリが実行したすべての記録。ヘルプを求めるときにコピー
+
+
+ バージョン、言語、テーマ、アップデート
+
+
+ 簡単なチェック
+
+
+ 端末を接続する前に、この PC の準備状況を確認します。
+
+
+ 確認中…
+
+
+ adb と fastboot があります
+
+
+ アプリに付属しています (platform-tools 37.0.1): インストールは不要です。
+
+
+ adb または fastboot が見つかりません
+
+
+ FastbootStudio.exe と同じ場所に必要です。exe だけでなく、ダウンロードしたものをすべて展開し直してください。
+
+
+ Samsung USB ドライバーがインストールされています
+
+
+ ダウンロードモードの Samsung 端末用です。
+
+
+ Samsung USB ドライバーがインストールされていません
+
+
+ 必要なのはダウンロードモードの Samsung 端末だけです。アプリが Samsung から入手できます。
+
+
+ インストール…
+
+
+ USB デバイスを読み取れませんでした
+
+
+ ドライバーが動作していない端末があります
+
+
+ fastboot で接続された端末があります
+
+
+ Android またはリカバリー (adb) で接続された端末があります
+
+
+ ダウンロードモードの Samsung 端末があります
+
+
+ チップのダウンロードモード (EDL、BROM…) の端末があります
+
+
+ 端末が接続されていません
+
+
+ 問題ありません。後で接続してください。Android では開発者向けオプションで USB デバッグを有効にしてください。
+
+
+ 書き込みの前に
+
+
+ ほとんどのトラブルを防ぐ 4 つのルール。
+
+
+ まずバックアップ
+
+
+ 「バックアップ」ページで。何か問題が起きても、端末を元の状態に戻せます。
+
+
+ バッテリーは 50% 以上
+
+
+ 書き込みの途中で電源が切れると、端末が起動しなくなる可能性があります。
+
+
+ ケーブルを抜かない
+
+
+ 品質の良いデータケーブルをハブではなく PC 本体のポートに挿し、アプリが完了を表示するまで待ってください。
+
+
+ お使いの端末専用のファイル
+
+
+ 同じモデル、同じソフトウェアバージョンのもの。アプリは確認できる範囲でチェックし、書き込む前に警告します。
+
+
+ このツアーは「バージョン情報」からもう一度見られます。
+
+
+ Samsung USB ドライバー
+
+
+ developer.samsung.com から · 約 37 MB
+
+
+ 既にインストールされているようです。再インストールしても問題ありません。
+
+
+ ダウンロードモードの Samsung 端末には Samsung 独自のドライバーが必要です。Odin が使うものと同じです。
+
+アプリが Samsung からダウンロードし、Windows が Samsung の署名を確認できることを確かめてから、インストーラーを開きます。Windows が許可を求めますが、ドライバーでは通常のことです。
+
+
+ ダウンロードしてインストール
+
+
+ Samsung のドライバーをダウンロード中
+
+
+ Samsung から直接ダウンロードします。実行前に検証されます。
+
+
+ ダウンロードに失敗しました: {0}
+
+
+ Samsung のリンクが安全な (https) アドレスで終わっていなかったため、ファイルは使用しませんでした。
+
+
+ ファイルが Samsung のドライバーよりはるかに大きいため、保存しませんでした。
+
+
+ Windows がファイルに Samsung Electronics の有効な署名を見つけられなかったため、削除して実行しませんでした。
+
+
+ Samsung のインストーラーが開いています
+
+
+ インストーラーの手順に従ってください。完了すると、このウィンドウがドライバーの有無を確認します。
+
+
+ Windows でインストーラーを実行する許可が得られませんでした。
+
+
+ Samsung のドライバーがインストールされました
+
+
+ Samsung の端末が接続されている場合は、抜き差ししてください。
+
+
+ 閉じる
+
+
+ ドライバーはまだインストールされていません
+
+
+ インストーラーがまだ開いている場合は先に完了させてから、「再確認」を押してください。
+
+
+ 再確認
+
+
+ Samsung のドライバーはインストールされませんでした
+
+
+ Samsung のページから自分でダウンロードすることもできます。
+
+
+ 再試行
+
+
+ Samsung のページを開く
+
+
+ {0} に書き込みますか?
+
+
+ このイメージは {0} で root 化されています。端末を root 化するならこれで正しいです。root を外すには、同じファームウェアの純正イメージを書き込んでください。
+
+
+ まずデバイスページの「イメージを 1 回だけ起動…」で試してください: {0} に書き込まずにリカバリーを起動するので、端末に合わなくても何も変わりません。端末によってはこの方法でイメージを起動できません。
+
+
+ この PC には Samsung の USB ドライバーがインストールされておらず、この端末にはそれが必要です。今すぐ Samsung からダウンロードしてインストールしますか?
+
+
+ Samsung USB ドライバーがインストールされています: ダウンロードモードを認識できます。
+
+
+ Samsung USB ドライバーがインストールされていません。ダウンロードモードには必要です。
+
+
+ Knox: 正常 (0x0)
+
+
+ 端末の報告による値です。Samsung 以外のもの (root、カスタムリカバリー、カーネル) を書き込むと、永久にトリップします。
+
+
+ Knox がトリップしています (0x1)
+
+
+ この端末では Samsung Wallet、セキュアフォルダ、Samsung Pass が使えなくなっています。公式ファームウェアを書き込んでも Knox は戻りません。
+
+
+ Knox は 0x0 ですが、ブートローダーはアンロックされています
+
+
+ アンロックだけでは Knox はトリップしません。しかし非公式なもの (root、カスタムリカバリー、カーネル) を一度でも書き込んでいれば Knox は永久にトリップしており、隠蔽モジュールが 0x0 と表示させています。Samsung Wallet、セキュアフォルダ、Samsung Pass は実際の eFuse に従います。
+
+
+ ダウンロードモード
+
+
+ ダウンロードモードの端末を読み取る: パーティションテーブル (PIT)、モデル、地域
+
+
+ ダウンロードモードで端末を読み取る
+
+
+ パーティションテーブル (PIT)、モデル、地域を読み取り、それらと照合したうえで書き込みます。
+
+
+ 端末の電源を切り、ケーブルを抜いてください。
+
+
+ 音量アップと音量ダウンを同時に押しながら、ケーブルをコンピューターに接続してください。ホームボタンのある古い端末: 音量ダウン + ホーム + 電源。
+
+
+ 青い警告画面で音量アップを 1 回押して続行します。画面に Downloading と表示されます。
+
+
+ One UI 8.5 の Galaxy S26 と Z Fold 7: Samsung が先にメンテナンスモードを求める場合があります (設定 › デバイスケア › メンテナンスモード)。
+
+
+ 端末を探しています…
+
+
+ ダウンロードモードの端末はまだありません。この表示は自動で更新されます。
+
+
+ ダウンロードモードの端末が {0} で見つかりました。
+
+
+ ダウンロードモードの端末が {0} 台あります: 1 台だけ接続したままにしてください。
+
+
+ ダウンロードモードの端末がありますが、Windows に動作するドライバーがありません: Samsung の USB ドライバーをインストールしてください。
+
+
+ Samsung の USB ドライバーがありません。ダウンロードモードには必要です。
+
+
+ 読み取り後:
+
+
+ Android で再起動
+
+
+ ダウンロードモードで再起動
+
+
+ 端末は接続ごとに 1 回の Odin セッションしか受け付けないため、読み取り後に再起動します。
+
+
+ 端末を読み取る
+
+
+ 端末を読み取り中…
+
+
+ ケーブルを抜かないでください。数秒かかります。
+
+
+ 読み取りに失敗しました
+
+
+ 別のプログラムが端末のポート ({0}) を使用しています: Odin、Smart Switch、その他の書き込みツールを閉じてから、もう一度お試しください。
+
+
+ 端末のポートが消えました: ケーブルが抜けたか、端末がダウンロードモードを抜けませんでしたか?
+
+
+ 端末のポートを開けませんでした: {0}
+
+
+ 端末がダウンロードモードの端末として応答しませんでした。
+
+
+ 端末が応答しなくなりました: {0}
+
+
+ もう一度試す前に、端末をダウンロードモードで再起動してください: 音量ダウン + 電源を約 7 秒長押しし、画面が暗くなったらダウンロードモードのキーを押し続けます。
+
+
+ データ通信対応のケーブルを、ハブを使わずコンピューターに直接接続してください。
+
+
+ 再試行
+
+
+ 端末を読み取りました
+
+
+ {0} を読み取りました
+
+
+ 端末には何も書き込まれていません。
+
+
+ モデル
+
+
+ シリアル
+
+
+ 地域 (CSC)
+
+
+ キャリア
+
+
+ Odin プロトコル
+
+
+ v{0}
+
+
+ v{0}、LZ4 ファームウェア対応
+
+
+ パーティションテーブル
+
+
+ {0} 個のパーティション
+
+
+ このブートローダーはモデルを報告しません。パーティションテーブルは読み取りました。
+
+
+ モデルを読み取れませんでした。パーティションテーブルは読み取りました。
+
+
+ ID
+
+
+ パーティション
+
+
+ ファイル
+
+
+ ブロック数
+
+
+ 端末は Android で再起動しています。
+
+
+ 端末はダウンロードモードで再起動しています。
+
+
+ 端末がセッションの終了に応答しませんでした: 音量ダウン + 電源を約 7 秒長押しして再起動してください。
+
+
+ PIT を保存…
+
+
+ 保存しました: {0}
+
+
+ 詳細をコピー
+
+
+ コピーしました
+
+
+ この端末は自動ではダウンロードモードで再起動しません: Android で再起動しています。
+
+
+ 設定
+
+
+ 言語、外観、アップデート。
+
+
+ 外観
+
+
+ 文字サイズ
+
+
+ すべてのページにすぐ反映されます。
+
+
+ 小
+
+
+ 標準
+
+
+ 大
+
+
+ 特大
+
+
+ 文字はこのように表示されます
+
+
+ 安全に書き込み、バックアップ、root 化。
+
+
+ Windows から Android 端末を安全に書き込み、バックアップ、root 化。
+
+
+ 無料のオープンソース
+
+
+ アップデートを確認
+
+
+ ベース
+
+
+ 内蔵
+
+
+ チェック
+
+
+ ツール
+
+
+ Telegram グループ
+
+
+ すべてのツール
+
+
+ おそらくアンロック済み
+
+
+ プロパティはロック中と示していますが、この端末には {0} があり、root にはアンロックされたブートローダーが必要です: ROM や隠蔽モジュールがロック中に見せかけています。本当の状態を読み取るには、root マネージャーで Shell に root を許可するか、bootloader で再起動してデバイスページを開いてください。
+
+
+ Companion のバックアップ
+
+
+ {0}、Shell には未許可
+
+
+ Google USB ドライバー
+
+
+ dl.google.com から · 約 8 MB
+
+
+ Pixel や、Google の USB ID を使う多くの端末で fastboot と adb を使うには、Google のドライバーが必要です。Android Studio がインストールするものと同じです。
+
+アプリが Google からダウンロードし、サイズとチェックサムを Google の一覧と照合してから、Windows に追加を依頼します。他のドライバーと同様に、Windows が許可を求めます。
+
+
+ Google のドライバーをダウンロード中
+
+
+ Google から直接ダウンロードします。使用前に検証されます。
+
+
+ ファイルが Google の一覧の内容 ({0}) と一致しないため、削除して使用しませんでした。
+
+
+ Google のドライバーを追加中
+
+
+ Windows が許可を求めてから、ドライバーを追加します。数秒かかります。
+
+
+ Google のドライバーがインストールされました
+
+
+ 端末が接続されている場合は、抜き差ししてください。他のメーカーの端末では、そのメーカー独自のドライバーが必要な場合があります。
+
+
+ Google のドライバーはインストールされませんでした
+
+
+ Windows がドライバーを追加できませんでした (pnputil の終了コード {0})。
+
+
+ Google のページから自分でダウンロードすることもできます。
+
+
+ Google のページを開く
+
+
+ Google USB ドライバーがインストールされています: Google の USB ID の fastboot と adb を認識できます。
+
+
+ Google USB ドライバーがインストールされていません。Pixel や Google の USB ID を使う端末には必要です。
+
+
+ USB ドライバー
+
+
+ fastboot、adb、ダウンロードモードの端末を認識するには、Windows にドライバーが必要です。
+
+
+ この端末には Google の USB ドライバーが適合します (Google の USB ID)。今すぐ Google からダウンロードしてインストールしますか?
+
+
+ 書き込み…
+
+
+ 端末に書き込む
+
+
+ 書き込むものを選んでください: 単体のイメージ (boot.img、.lz4)、Magisk の tar、またはファームウェアの BL、AP、CP、HOME_CSC ファイル。送信する前に、すべてのファイルをこの端末のパーティションテーブルとモデルに照合します。
+
+
+ ファイルを選択…
+
+
+ Samsung ファームウェアとイメージ
+
+
+ {0} を検証中
+
+
+ {0}
+
+ファイルが破損しているか不完全です。もう一度ダウンロードしてください。
+
+
+ {0} 個のファイル · {1}
+
+
+ {0} のパーティション:
+
+
+ 上の警告を読み、続行します
+
+
+ 完了したら端末を再起動する
+
+
+ 端末をダウンロードモードにして接続してください。端末が見つかると「書き込み」が有効になります。
+
+
+ {0} 個のファイル ({1}) を端末に書き込みますか?
+
+終わるまで端末を抜いたり、このウィンドウを閉じたりしないでください。途中で止まった場合でも、端末はダウンロードモードのままで、もう一度書き込めます。
+
+
+ {0} を書き込み中
+
+
+ {1} 中 {0}
+
+
+ 端末を抜いたり、このウィンドウを閉じたりしないでください。
+
+
+ 書き込みが完了しました
+
+
+ 端末を再起動します。ファームウェア書き込み後の初回起動には数分かかることがあります。
+
+
+ 端末はダウンロードモードのままです。再起動するには、電源と音量ダウンを 7 秒長押ししてください。
+
+
+ 書き込み済み: {0}
+
+
+ 書き込みが停止しました
+
+
+ {0} の書き込み中に停止しました: {1}
+
+
+ 何も書き込む前に停止しました: {0}
+
+
+ この端末のパーティションテーブルが、ファイルを照合したものと異なります (別の端末を接続しましたか?)。何も書き込まれていません。端末をもう一度読み取ってください。
+
+
+ 端末はダウンロードモードのままです。再起動せずに、もう一度接続して書き込み直してください。画面にエラーが表示されている場合は、写真を撮っておいてください。
+
+
+ もう一度書き込む
+
+
+ 戻る
+
+
+ 書き込むものがありません: この端末にパーティションがあるファイルが 1 つもありません。
+
+
+ {0}: この端末にはその名前のパーティションがありません。下から選んでください。
+
+
+ {0}: この端末のパーティションではありません。Odin と同様に除外します。
+
+
+ {0}: パーティションテーブルです。書き込まれず、端末のパーティションはそのままです。
+
+
+ {0} は {1} の容量を超えています ({2}、最大 {3})。
+
+
+ {0} は端末の固有情報 (IMEI、キー) を保持しています。ここでは決して書き込みません。
+
+
+ {0} 用のファイルが 2 つあります。1 つだけ残してください。
+
+
+ CSC と HOME_CSC の両方が選択されています。データを残すなら HOME_CSC、端末を消去するなら CSC を残してください。
+
+
+ ファームウェアは {0} 用ですが、この端末は {1} です。書き込めません。
+
+
+ 端末がモデルを報告しなかったため、ファームウェア ({0}) と照合できません。この端末用であることを確認してください。
+
+
+ これらのファイルは別のビルドのものです: {0}。1 つのファームウェアの BL、AP、CP、CSC を使ってください。
+
+
+ {0} はブートローダーの一部です。間違ったものを書き込むと端末が起動しなくなる可能性があり、古いものは端末に拒否されます。
+
+
+ {0} はモデムです。間違ったものを書き込むと端末が圏外になる可能性があります。
+
+
+ {0} は端末のすべてのデータを消去します (初期化)。データを残すには HOME_CSC を使ってください。
+
+
+ {0} は空です: 書き込む内容がありません。
+
+
+ {0} は Samsung ファームウェアの命名規則に従っていないため、対象の端末を確認できません。この端末用だと確信できる場合のみ書き込んでください。
+
+
+ payload にコマンドラインで扱えないパーティション名が含まれています: {0}。何も書き込まれていません。ファイルが破損しているか改ざんされている可能性があります。
+
+
+ {0} は UFS の端末では {1} に収まりますが、eMMC の端末では収まりません ({2}、eMMC のパーティションは最大 {3})。PIT からはこの端末がどちらか分かりません。eMMC の端末では、書き込みの途中でブートローダーに拒否されます。
+
+
+ このコマンドはアクティブなスロットを変更します: 次回、端末はもう一方のスロットから、その内容に関係なく起動します。そのスロットに古いシステムや壊れたシステムが入っていると、起動しない可能性があります。実行しますか?
+
+
+ 内容を読みました
+
+
+ 書き込みの確認
+
+
+ {0}: {1} 個のパーティション、{2}。すべてのイメージが抽出され、ハッシュの検証に合格するまで何も書き込まれません。
+
+
+ 書き込む
+
+
+ 端末: {0} · {1} · スロット {2} · {3}
+
+
+ ログフォルダーを開く
+
+
+ 書き込みのたびにログフォルダーにファイルとしても保存されます (最新 30 件を保持)。
+
+
+ ユーザーにより停止しました。パーティションが書き込み途中の可能性があります。再起動する前にもう一度書き込んでください。
+
+
+ 停止
+
+
+ 端末
+
+
+ ADB で接続したときに端末に root を要求する
+
+
+ Companion のレポート (root の状態、AVB、モジュールの競合) を読み取ります。Magisk は初回に端末で確認を表示します。オフの場合、端末ページは自分で読み取ったときだけ要求します。
+
+
+ 端末
+
+
+ ファイル
+
+
+ その他のツール
+
+
+ 再起動 ▾
+
+
+ 端末が接続されていません
+
+
+ fastboot の端末を接続してください。ADB の Android 端末は「端末」ページで読み取ります。
+
+
+ SN {0}
+
+
+ スロット {0}
+
+
+ アンロック済み
+
+
+ ロック中
+
+
+ 最終: fastboot {0} · {1}
+
+
+ {0} 秒
+
+
+ {1} 個中 {0} 個のパーティションを書き込みました
+
+
+ ログを開く
+
+
+ 端末を再起動
+
+
+ 重要
+
+
+ ここにファイルをドロップするか、選択してください
+
+
+ 端末 (ダウンロードモード)
+
+
+ 未読み取り
+
+
+ ファームウェアについて
+
+
+ パーティションイメージをここにドロップするか、インポートしてください
+
+
+ system、vendor、product… の raw または sparse イメージ。fastbootd の端末からレイアウトを読み込むこともできます。
+
+
+ 始める前に
+
+
+ ブートローダーがアンロック済み
+
+
+ USB デバッグが有効で、端末が Android で起動中
+
+
+ 端末のファームウェアの純正イメージ
+
+
+ boot と大切なデータのバックアップ
+
+
+ 完了
+
+
+ 現在
+
+
+ ウィンドウの背景をすりガラスにする (Windows 11)
+
+
+ デスクトップがぼかされてウィンドウ越しに見えます。オフの場合は、ウィンドウ独自のグラデーションになります。
+
+
+ キーボードショートカット
+
+
+ このページでファイルを開く
+
+
+ ログ
+
+
+ このページのヘルプ
+
+
+ 設定
+
+
+ リンク
+
\ No newline at end of file
diff --git a/Properties/Resources.ko-KR.resx b/Properties/Resources.ko-KR.resx
index 1024d42..ebf9c97 100644
--- a/Properties/Resources.ko-KR.resx
+++ b/Properties/Resources.ko-KR.resx
@@ -178,7 +178,7 @@
해당 기기가 없습니다
- Fastboot 가상화
+ Fastboot 시각화
동적 파티션 확장하기
@@ -259,10 +259,10 @@
Fastbootd로 재부팅
- 복구모드로 재부팅
+ 리커버리로 재부팅
- 재부팅
+ 시스템으로 재부팅
연결 끊기
@@ -289,7 +289,7 @@
파티션이 선택되지 않았습니다.
- 다음 파티션이 플래싱 됐는지 알 수 없습니다:
+ 플래시할 다음 파티션은 알 수 없는 파티션일 수 있습니다:
"알 수 없는 파티션 무시하기" 확인란을 선택하여 이 경고를 비활성화할 수 있습니다. 알 수 없는 파티션이 있다고 해서 플래싱이 실패하거나 기기가 벽돌이 되는 것은 아닙니다.
@@ -322,7 +322,9 @@
계속 할까요?
- vbmeta 검증을 비활성화 할까요?
+ 이 vbmeta에서 dm-verity와 AVB 검증을 비활성화할까요? (--disable-verity --disable-verification)
+
+커스텀 또는 패치된 시스템에 필요합니다. 부트로더가 잠금 해제된 경우에만 작동하며, 변경 후에는 대개 휴대폰을 초기화(공장 초기화)해야 합니다.
검증 비활성화
@@ -364,7 +366,7 @@
Payload 추출기
- 동적 파티션 부가정보
+ 동적 파티션 메타데이터
오류가 발생했습니다.
@@ -394,13 +396,13 @@
매니페스트 크기
- 매니페스트 서명 (Base64)
+ 메타데이터 서명 (Base64)
- 매니페스트 서명 크기
+ 메타데이터 서명 크기
- 동적 파티션 부가정보가 없습니다.
+ 동적 파티션 메타데이터가 없습니다.
Payload 파일이 선택되지 않았습니다, 탐색 버튼을 눌러 열거나, 끌어다 놓아주세요.
@@ -472,7 +474,7 @@
저장할 위치를 선택하세요
- 알 수 없는
+ 알 수 없음
게시글 보기
@@ -480,4 +482,3039 @@
예
-
\ No newline at end of file
+
+ 기기
+
+
+ 플래시
+
+
+ 로그
+
+
+ 실시간 기기 상태, 파티션 및 빠른 작업
+
+
+ 연결된 기기
+
+
+ 기기를 두 번 클릭하거나, 선택한 뒤 Enter를 누르세요.
+
+
+ 아직 부트로더나 fastbootd 모드인 기기가 없습니다. 기기를 연결하면 1초 안에 여기에 표시됩니다.
+
+
+ 기기 변수
+
+
+ 빠른 작업
+
+
+ 플래시 전 점검
+
+
+ 파티션 작업
+
+
+ 부트로더 잠금 해제됨: 이미지를 기록할 수 있습니다
+
+
+ 부트로더 잠김: 기기가 플래시를 거부합니다
+
+
+ 대기 중인 가상 A/B 업데이트가 없습니다
+
+
+ 가상 A/B 업데이트가 {0} 상태입니다: 플래시 전에 취소하세요
+
+
+ 남아 있는 COW 파티션이 있습니다: 플래시 전에 제거하세요
+
+
+ fastbootd 모드: 동적 파티션을 기록할 수 있습니다
+
+
+ 부트로더 모드: 동적 파티션을 기록하려면 fastbootd로 재부팅하세요
+
+
+ 활성 슬롯: {0}
+
+
+ fastboot 모드 기기 {0}대
+
+
+ fastboot.exe가 없습니다
+
+
+ 모든 이미지를 병렬로 추출하고, 기록하기 전에 매니페스트와 대조해 검사합니다
+
+
+ 선택한 payload가 없습니다
+
+
+ 먼저 기기 페이지에서 기기를 선택하세요.
+
+
+ 선택한 기기 없음
+
+
+ 대상: {0}
+
+
+ 각 이미지는 기록하기 전에 SHA-256으로 검사합니다.
+
+
+ 모든 이미지가 문제없이 추출될 때까지 기기에는 아무것도 기록하지 않습니다.
+
+
+ 대기
+
+
+ 추출 중
+
+
+ 플래시 중
+
+
+ 완료
+
+
+ 실패
+
+
+ 대기 중
+
+
+ 추출 중
+
+
+ 검증됨
+
+
+ 플래시 중
+
+
+ 플래시됨
+
+
+ 실패
+
+
+ 나중에 부트로더에서
+
+
+ 부트로더에서 플래시 중
+
+
+ fastbootd가 {0}을(를) 기록하지 않아서, 앱이 휴대폰을 부트로더로 재시작한 뒤 그곳에서 기록했습니다. 지금 휴대폰은 부트로더 상태입니다.
+
+
+ 휴대폰이 부트로더로 돌아오지 않았습니다. 다음 파티션은 아직 기록되지 않았습니다: {0}
+
+
+ 기록 안 됨
+
+
+ 단계
+
+
+ 경과 시간
+
+
+ 기록됨
+
+
+ 실시간 로그
+
+
+ 이번 세션의 모든 fastboot 명령과 그 출력
+
+
+ 복사
+
+
+ 지우기
+
+
+ payload.bin 또는 OTA zip을 열어 내용을 살펴보고 이미지를 추출합니다
+
+
+ payload.bin 또는 OTA zip을 여기에 끌어다 놓으세요
+
+
+ 코덱
+
+
+ 추출 가능
+
+
+ 진행률
+
+
+ 상태
+
+
+ 파티션
+
+
+ 크기
+
+
+ Payload 엔진: zstd, xz, bzip2, 다중 extent 작업, SHA-256 검사를 포함한 병렬 추출
+
+
+ 정말 진행할까요?
+
+
+ "{0}" 파티션을 지울까요? 안에 있는 모든 데이터가 사라집니다.
+
+
+ super에서 동적 파티션 "{0}"을(를) 삭제할까요? 되돌릴 수 없습니다.
+
+
+ payload를 플래시하는 중입니다. 지금 닫으면 도중에 멈추고 기기가 부팅되지 않을 수 있습니다. 그래도 닫을까요?
+
+
+ 일부 이미지가 불완전합니다: 이 빌드에서 적용할 수 없는 작업은 0으로 채워졌고, 해당 이미지는 매니페스트와 대조하지 않았습니다.
+
+
+ 작업 {0}개 건너뜀, 검증 안 됨
+
+
+ 이미지를 추출하는 중입니다. 지금 닫으면 추출이 중지되고 완료되지 않은 파일은 삭제됩니다. 그래도 닫을까요?
+
+
+ 다음 파티션은 payload에 SHA-256이 없어서 기록하기 전에 이미지를 검사할 수 없습니다:
+
+{0}
+
+그래도 플래시할까요?
+
+
+ 취소
+
+
+ 경고
+
+
+ 완료
+
+
+ 개발자
+
+
+ 원작자
+
+
+ LibXZR의 Fastboot Enhance를 기반으로 하며, MIT 라이선스로 배포됩니다. Copyright © 2021 LibXZR.
+
+
+ 원본 프로젝트
+
+
+ 라이선스
+
+
+ 백업
+
+
+ adb로 휴대폰의 파티션과 모든 파일을 이 컴퓨터에 저장합니다
+
+
+ ADB 연결 기기
+
+
+ 모델
+
+
+ 모드
+
+
+ 기기를 찾는 중… USB 디버깅을 켠 상태로 Android를 부팅하거나, 커스텀 리커버리(TWRP, OrangeFox)로 부팅하세요.
+
+
+ adb로 연결된 기기가 없습니다. 개발자 옵션에서 USB 디버깅을 켜고 휴대폰을 연결하거나, 커스텀 리커버리로 부팅하세요.
+
+
+ 휴대폰 잠금을 풀고 이 컴퓨터의 USB 디버깅을 허용하세요.
+
+
+ 기기가 "{0}" 모드입니다. 파티션과 파일을 다루려면 Android나 커스텀 리커버리 상태여야 합니다.
+
+
+ 지금 파일을 복사할 수 있습니다. 파티션 백업에는 루트(Magisk, KernelSU)나 커스텀 리커버리가 필요합니다. 확인하려면 "파티션 테이블 읽기"를 누르세요.
+
+
+ 루트 셸 사용 가능(리커버리 또는 adb root): 파티션을 백업할 수 있습니다.
+
+
+ su를 통한 루트: 파티션을 백업할 수 있습니다.
+
+
+ 루트 권한을 요청하는 중입니다. 휴대폰에 요청 창이 뜨면 허용하세요.
+
+
+ 파티션을 읽으려면 루트가 필요합니다. Magisk나 KernelSU로 루팅한 뒤 요청을 허용하거나, TWRP나 OrangeFox 같은 커스텀 리커버리로 부팅하세요. 파일은 파일 탭에서 계속 복사할 수 있습니다.
+
+
+ 이 기기에서 파티션 테이블을 읽을 수 없습니다.
+
+
+ 파티션
+
+
+ 파일
+
+
+ 파티션 테이블 읽기
+
+
+ 중요 파티션 선택
+
+
+ 선택 해제
+
+
+ 이름으로 검색
+
+
+ 저장 위치
+
+
+ 변경…
+
+
+ 선택 항목 백업
+
+
+ 취소
+
+
+ 백업 검사…
+
+
+ 백업 검사
+
+
+ 폴더 열기
+
+
+ 각 이미지는 backup-info.txt 옆의 SHA256SUMS에 SHA-256과 함께 저장됩니다. 복원하려면 기기 › 파티션에서 해당 이미지를 플래시하세요.
+
+
+ 읽는 중
+
+
+ 저장됨
+
+
+ 건너뜀
+
+
+ 중요
+
+
+ 먼저 백업할 파티션을 체크하거나 "중요 파티션 선택"을 누르세요.
+
+
+ 다음 파티션은 용량이 커서 시간이 오래 걸리고 디스크 공간도 많이 차지합니다:
+
+{0}
+
+그래도 백업할까요?
+
+
+ {1} 중 {0}만 읽음. 기기가 전송을 멈췄습니다(권한 거부 또는 연결 끊김)
+
+
+ 파티션 {0}개를 저장하고 SHA-256을 다음 위치에 기록했습니다:
+{1}
+
+
+ 파티션 {1}개 중 {0}개를 다음 위치에 저장했습니다:
+{2}
+
+
+ 중지했습니다. 완료되지 않은 파일은 삭제했습니다.
+
+
+ 이 폴더에는 SHA256SUMS 파일이 없어서 대조할 기준이 없습니다.
+
+
+ 파일 {0}개 모두 SHA-256이 일치합니다.
+
+
+ 파일 {1}개 중 {0}개가 없거나 일치하지 않습니다:
+
+
+ 위로
+
+
+ 열기
+
+
+ 내장 저장소
+
+
+ 카메라
+
+
+ 사진
+
+
+ 다운로드
+
+
+ 문서
+
+
+ 이름
+
+
+ 종류
+
+
+ 폴더
+
+
+ 파일
+
+
+ 링크
+
+
+ 이 폴더가 비어 있거나, 루트 없이는 Android가 읽기를 허용하지 않습니다.
+
+
+ 폴더 {0}개, 파일 {1}개
+
+
+ {0} 복사 중…
+
+
+ 컴퓨터로 복사
+
+
+ 파일이나 폴더를 선택해서 복사하세요(여러 개는 Ctrl 또는 Shift, 전체는 Ctrl+A). 폴더는 안의 내용까지 모두 복사됩니다. 폴더를 열려면 두 번 클릭하세요.
+
+
+ 먼저 복사할 파일이나 폴더를 선택하세요.
+
+
+ 항목 {0}개를 다음 위치에 복사했습니다:
+{1}
+
+
+ 항목 {1}개 중 {0}개를 다음 위치에 복사했습니다:
+{2}
+
+
+ 컨테이너
+
+
+ OTA zip (그대로 읽음)
+
+
+ OTA zip (임시 폴더에 풀어서 읽음)
+
+
+ 보안 패치
+
+
+ 부분 업데이트
+
+
+ APEX 패키지
+
+
+ 작업
+
+
+ 파티션 {0}개 · {1} · {2}
+
+
+ 파티션 {1}개 중 {0}개를 기록했습니다
+
+
+ {0}, {1}초
+
+
+ 최소화
+
+
+ 최대화
+
+
+ 이전 크기로 복원
+
+
+ 닫기
+
+
+ 언어
+
+
+ 새 언어는 다시 시작한 후 적용됩니다. 지금 Fastboot Studio를 다시 시작할까요?
+
+
+ 언어를 바꾸기 전에 진행 중인 플래시나 추출이 끝날 때까지 기다리세요.
+
+
+ 이미지 도구
+
+
+ Android 이미지 검사, 변환, 풀기: sparse, super, ext4, EROFS 등
+
+
+ 이미지 열기…
+
+
+ 이미지를 여기에 끌어다 놓으세요
+
+
+ system.img, super.img, vendor.img… sparse 또는 raw. 여러 조각으로 나뉜 이미지(system.img_sparsechunk.0, .1…)는 아무 조각이나 하나만 열면 나머지는 자동으로 찾습니다.
+
+
+ 세부 정보
+
+
+ super 안의 파티션
+
+
+ Sparse 청크
+
+
+ 모두 선택
+
+
+ 그룹
+
+
+ 유형
+
+
+ 시작 블록
+
+
+ 블록
+
+
+ 파티션 추출 (lpunpack)
+
+
+ raw로 변환 (simg2img)
+
+
+ sparse로 변환 (img2simg)
+
+
+ 조각으로 나누기 (simg2simg)
+
+
+ 조각당 최대 크기
+
+
+ 빈 슬롯
+
+
+ 여러 파일을 선택했지만 한 이미지의 sparse 조각이 아닙니다. 이미지는 한 번에 하나씩 여세요.
+
+
+ Super (동적 파티션)
+
+
+ ext4 파일 시스템
+
+
+ EROFS 파일 시스템
+
+
+ F2FS 파일 시스템
+
+
+ boot 이미지
+
+
+ vendor_boot 이미지
+
+
+ vbmeta (Android Verified Boot)
+
+
+ OTA payload (Payload Dumper에서 여세요)
+
+
+ Zip 압축 파일
+
+
+ 파일
+
+
+ 조각 {0}개
+
+
+ 형식
+
+
+ Raw 이미지
+
+
+ 내용
+
+
+ 이미지 크기
+
+
+ 디스크 사용 크기
+
+
+ 블록 크기
+
+
+ 블록
+
+
+ {1} / {2} / {3}
+
+
+ 청크
+
+
+ CRC-32
+
+
+ 기록 안 됨
+
+
+ 메타데이터
+
+
+ 버전 {0}, 슬롯 {1}개
+
+
+ 백업 사본에서 읽음
+
+
+ 가상 A/B
+
+
+ 파티션
+
+
+ 데이터 있음 {0}개, 전체 {1}개
+
+
+ 그룹
+
+
+ 제한 없음
+
+
+ super 크기
+
+
+ 파티션은 sparse 여부와 관계없이 이미지에서 바로 읽으며, 모든 메타데이터 체크섬을 검증합니다. 각 파티션은 이미지 옆 폴더에 이름.img로 저장됩니다.
+
+
+ raw로 변환하면 전체 이미지(모든 조각 합본)를 다시 만들고, 포함된 CRC-32를 검증합니다. 나누기를 하면 fastboot로 하나씩 플래시할 수 있는 조각이 만들어집니다.
+
+
+ sparse로 변환하면 반복되는 블록을 하나의 레코드로 저장합니다. fastboot와 공장 이미지가 쓰는 형식입니다. 결과물은 AOSP img2simg와 바이트 단위로 같습니다.
+
+
+ 다음 파일이 이미 있어서 교체됩니다:
+
+{0}
+
+계속할까요?
+
+
+ {0}초 만에 완료
+
+
+ Raw 이미지를 기록했습니다:
+{0}
+{1}
+
+
+ CRC-32 {0}
+
+
+ 기록된 체크섬 {0}개 검증 완료
+
+
+ 조각의 최대 크기를 MB 단위로 입력하세요. 예: 512
+
+
+ 나누려면 sparse 이미지를 하나만 여세요. 조각을 합치려면 먼저 raw로 변환하세요.
+
+
+ sparse 파일 {0}개를 기록했습니다({1}):
+{2}
+
+
+ 먼저 추출할 파티션을 체크하세요.
+
+
+ 파티션 {0}개를 다음 위치에 추출했습니다:
+{1}
+
+
+ 데이터 / 채우기 / 무시
+
+
+ {0}이(가) Fastboot 모드입니다
+
+
+ Fastboot는 파티션을 기록할 수는 있지만 다시 읽을 수는 없습니다. 일반 판매용 휴대폰에서는 Android가 이를 허용하지 않습니다. 백업은 adb로 진행되므로, 다음 중 한 가지 방법으로 먼저 Fastboot에서 나와야 합니다:
+
+
+ Android 시작
+
+
+ 바로 파일을 복사할 수 있습니다. USB 디버깅이 켜져 있어야 하며, 파티션 백업에는 루트(Magisk 또는 KernelSU)도 필요합니다.
+
+
+ 리커버리 시작
+
+
+ 커스텀 리커버리(TWRP, OrangeFox)가 설치된 경우: 파티션과 파일 모두 가능하며 루트가 필요 없습니다. 순정 리커버리에는 adb가 없습니다.
+
+
+ 설치하지 않고 리커버리 이미지로 한 번만 부팅
+
+
+ 이 휴대폰용 TWRP 또는 OrangeFox 이미지를 보내서 실행합니다. 휴대폰에는 아무것도 바뀌지 않습니다. 부트로더 잠금 해제가 필요합니다.
+
+
+ 리커버리 이미지 선택…
+
+
+ {0}을(를) 재시작하는 중… 휴대폰이 adb에 응답하면 이 페이지가 자동으로 전환됩니다.
+
+
+ 휴대폰으로 {0} 보내는 중…
+
+
+ 리커버리 이미지를 보내고 실행했습니다. 로딩이 끝나면 휴대폰이 adb로 여기에 표시되고 백업을 시작할 수 있습니다.
+
+
+ 휴대폰이 이미지로 부팅하지 않았습니다.
+
+{0}
+
+부트로더가 잠금 해제되어 있는지, 이미지가 이 휴대폰용인지 확인하세요. 일부 휴대폰(삼성 등)은 플래시하지 않고 이미지로 부팅하는 기능을 지원하지 않습니다.
+
+
+ 이 파일은 boot 또는 recovery 이미지가 아닙니다. 이 휴대폰용 TWRP 또는 OrangeFox의 .img 파일을 선택하세요.
+
+
+ 휴대폰이 fastbootd 모드라서 이미지를 실행할 수 없습니다. 지금 부트로더로 재시작할까요? 돌아오면 이미지를 다시 선택하세요.
+
+
+ fastboot가 완료되지 않았습니다: {0}
+
+
+ Super 만들기
+
+
+ 파티션 이미지들을 fastboot로 플래시할 수 있는 하나의 super.img로 합칩니다
+
+
+ super.img에서 가져오기…
+
+
+ 휴대폰에서 크기 읽기
+
+
+ 레이아웃
+
+
+ 가상 A/B
+
+
+ A/B
+
+
+ 단일 슬롯
+
+
+ 가져온 super와 동일
+
+
+ Android 11 이후 대부분의 휴대폰. 파티션에 _a와 _b가 붙고, 공장 이미지처럼 슬롯 b는 비워 둡니다.
+
+
+ 가상 A/B가 없는 A/B 휴대폰(주로 Android 10). 각 슬롯이 super의 절반을 씁니다.
+
+
+ A/B 슬롯이 없는 휴대폰: 파티션 이름이 그대로 유지됩니다.
+
+
+ 그룹, 슬롯, 파티션 순서를 {0}에서 복사합니다. 이미지는 같은 이름의 파티션을 대체합니다.
+
+
+ SUPER 크기 (바이트)
+
+
+ 예: 9126805504
+
+
+ 그룹 크기 (바이트)
+
+
+ 그룹 이름
+
+
+ 자동
+
+
+ 자동: {0}
+
+
+ {1} 중 {0} 사용 · {2} 남음
+
+
+ super 크기를 입력하면 파티션이 얼마나 쓰는지 볼 수 있습니다.
+
+
+ 이미지 추가…
+
+
+ 폴더 추가…
+
+
+ 제거
+
+
+ 모두 지우기
+
+
+ 파티션 이미지(system.img, vendor.img, product.img…)를 추가하거나 기존 super.img의 레이아웃을 가져오세요. 이미지 도구로 풀어 둔 이미지는 자동으로 찾습니다.
+
+
+ 이미지
+
+
+ 비어 있음
+
+
+ 출력
+
+
+ Sparse
+
+
+ Raw
+
+
+ Sparse는 크기가 더 작고 공장 이미지에 쓰이는 형식입니다. raw는 super 전체 크기입니다.
+
+
+ 만든 후 이미지 검사
+
+
+ super.img 만들기…
+
+
+ super.img 만드는 중
+
+
+ super.img 검사 중
+
+
+ 플래시 명령: fastboot flash super super.img. 먼저 휴대폰의 현재 super를 백업해 두세요.
+
+
+ super.img가 준비되었고 검사도 마쳤습니다: 모든 파티션을 다시 읽어 각 이미지와 일치함을 확인했습니다.
+
+{0}
+{1} · 파티션 {2}개
+
+
+ super.img가 준비되었습니다.
+
+{0}
+{1} · 파티션 {2}개
+
+
+ super.img를 기록했지만 검사를 통과하지 못했습니다. 플래시하지 마세요:
+
+{0}
+
+
+ super 크기를 입력하세요: 휴대폰에서 읽거나 super.img를 가져오세요.
+
+
+ super 크기는 4096바이트의 배수여야 합니다.
+
+
+ 이 레이아웃의 메타데이터 설정은 사용할 수 없습니다.
+
+
+ 메타데이터 영역에 비해 파티션이 너무 많습니다.
+
+
+ 파티션 이미지를 하나 이상 추가하세요.
+
+
+ "{0}"은(는) 올바른 이름이 아닙니다(영문자, 숫자, _ . - 사용, 최대 36자).
+
+
+ "{0}"이(가) 두 번 나옵니다.
+
+
+ "{0}" 그룹이 없습니다.
+
+
+ {0} 그룹이 너무 작습니다: 파티션에 {1}이(가) 필요하지만 {2}만 허용됩니다.
+
+
+ 파티션에 {0}이(가) 필요하지만 super는 {1}입니다.
+
+
+ {0}의 레이아웃 · {1} · 메타데이터 슬롯 {2}개 · 그룹 {3}
+
+
+ {1}에서 파티션 이미지 {0}개를 찾았습니다.
+
+
+ 이 파일은 super 이미지가 아닙니다.
+
+
+ 다음 파일은 파일 시스템 이미지가 아니므로 super에 들어가지 않을 가능성이 높습니다(boot, vbmeta 등은 따로 플래시합니다):
+
+{0}
+
+그래도 추가할까요?
+
+
+ 파일 시스템 이미지가 아닌 파일 {0}개를 건너뛰었습니다: {1}
+
+
+ 이 폴더에서 파티션 이미지를 찾지 못했습니다.
+
+
+ 목록에서 모든 파티션 이미지를 제거할까요?
+
+
+ fastboot 모드인 휴대폰이 없습니다. 부트로더나 fastbootd 상태로 연결한 뒤 다시 시도하세요.
+
+
+ {0}에서 읽음: super는 {1}({2}바이트)입니다. 레이아웃: {3}.
+
+
+ 휴대폰에서 super 크기를 읽지 못했습니다:
+
+{0}
+
+
+ 휴대폰에서 읽는 중…
+
+
+ {0}에 쓸 이미지 선택
+
+
+ 출력 파일이 super에 들어갈 이미지 중 하나입니다. 다른 이름을 선택하세요.
+
+
+ Qualcomm 플래시 패키지 조각 ({0})
+
+
+ 이 파일 {0}개는 {2}에 따라 배치된 하나의 {1} 이미지 조각입니다. 하나의 이미지로 합치거나, 조각에서 바로 파티션을 추출하세요.
+
+
+ sparse로 합치기
+
+
+ raw로 합치기
+
+
+ 조각 {0}개를 하나의 이미지로 합쳤습니다:
+
+{1}
+{2}
+
+{3}
+
+
+ 플래시 명령: fastboot flash super super.img
+
+
+ raw 이미지는 파티션 전체 크기입니다. fastboot용으로는 sparse가 더 작습니다.
+
+
+ 확인하려면 {0}을(를) 입력하세요:
+
+
+ 중요 파티션
+
+
+ {0}은(는) 부팅 체인의 일부이거나 휴대폰의 고유 정보(IMEI, 보정값, 키)를 담고 있습니다. 여기에 잘못된 이미지를 넣으면 부트로더조차 진입하지 못하거나, 어떤 펌웨어로도 되살릴 수 없는 데이터를 잃을 수 있습니다.
+
+반드시 이 기종 전용 이미지로만 플래시하고, 현재 이미지를 백업해 두세요.
+
+
+ {0}을(를) 지우면 휴대폰이 부팅되지 않거나 IMEI, 보정값, 키가 영구히 지워질 수 있습니다. 되돌릴 수 없습니다.
+
+
+ 슬롯 전환
+
+
+ 슬롯 {0}은(는) 현재 상태로는 부팅할 수 없어서 활성화하지 않았습니다.
+
+
+ 슬롯 {0}은(는) 부팅되지 않을 가능성이 높습니다. 그래도 전환할까요?
+
+
+ 슬롯 {0}(으)로 전환할까요?
+
+
+ 슬롯 {0}은(는) 아직 부팅을 완료한 적이 없습니다. 방금 플래시했다면 정상이지만, 그렇지 않다면 휴대폰이 다른 슬롯으로 돌아가거나 부팅에 실패할 수 있습니다.
+
+
+ 부트로더가 슬롯 {0}을(를) 부팅 불가로 표시했습니다.
+
+
+ 슬롯 {0}은(는) 남은 부팅 시도 횟수가 없고, 한 번도 정상 부팅된 적이 없습니다.
+
+
+ 슬롯 {0}의 다음 파티션이 없거나 비어 있습니다: {1}. 먼저 해당 슬롯(또는 전체 펌웨어)을 플래시하세요.
+
+
+ 이미지로 한 번 부팅…
+
+
+ 한 번 부팅
+
+
+ boot 또는 recovery 이미지를 플래시하지 않고 한 번만 실행합니다. 휴대폰을 재시작하면 설치된 상태로 돌아갑니다.
+
+
+ 이 이미지에는 커널이 없어서(init_boot 이미지 또는 그런 형태의 boot 이미지) 단독으로 부팅할 수 없습니다. 완전한 boot.img로 부팅하거나, 대신 init_boot를 플래시하세요.
+
+
+ 이것은 vendor_boot 이미지입니다: 램디스크와 디바이스 트리만 있고 단독으로 실행되는 것은 없습니다.
+
+
+ 이 파일은 boot 또는 recovery 이미지가 아닙니다.
+
+
+ 휴대폰이 fastbootd 모드라서 이미지를 실행할 수 없습니다. 지금 부트로더로 재시작할까요? 그런 다음 이미지를 다시 선택하세요.
+
+
+ 이미지를 보냈고 휴대폰이 실행하는 중입니다. 휴대폰을 평소대로 재시작하면 설치된 시스템으로 돌아갑니다.
+
+
+ Super
+
+
+ fastbootd에서 표시됩니다: 부트로더는 super 안의 파티션을 보여 주지 않습니다.
+
+
+ 휴대폰이 super 크기를 알려 주지 않습니다.
+
+
+ 전체 {0}, 약 {1} 남음
+
+
+ 슬롯 {0}: {1}
+
+
+ (사용 중)
+
+
+ 업데이트 사본(COW): {0}
+
+
+ 슬롯 없음: {0}
+
+
+ super 공간 부족
+
+
+ 이 이미지들은 super에 약 {0}의 공간이 더 필요하지만({1}), 남은 공간은 약 {2}뿐입니다. fastbootd가 "Not enough space to resize partition" 오류로 멈출 것입니다.
+
+공간을 확보하는 방법:
+
+
+ 슬롯 {0}의 파티션 삭제: {1}. 슬롯 {0}은(는) 다시 플래시할 때까지 부팅되지 않습니다.
+
+
+ 이전 업데이트가 남긴 것을 제거: 대기 중인 업데이트를 취소(업데이트 취소)하거나 COW 파티션을 삭제하세요.
+
+
+ super를 쓰는 다른 것이 없습니다. 이 이미지들이 이 휴대폰의 super보다 큽니다.
+
+
+ 수치는 추정값입니다. 그래도 플래시할까요?
+
+
+ 없는 파티션
+
+
+ 휴대폰에 {0}이(가) 없습니다. 이 업데이트가 super 안에 두는 파티션이므로, 지금 그곳에 (빈 상태로) 만든 뒤 기록할 수 있습니다.
+
+fastbootd는 새 파티션을 휴대폰 고유 그룹(main_a 등)이 아닌 "default" 그룹에 둡니다. 휴대폰은 정상적으로 부팅되며, 다음 전체 업데이트나 공장 super 플래시 때 원래 그룹으로 돌아갑니다.
+
+만들고 계속할까요?
+
+
+ fastbootd는 새 파티션을 휴대폰 고유 그룹(main_a 등)이 아닌 "default" 그룹에 둡니다. 정상 동작하며, 다음 전체 업데이트 때 원래 그룹으로 돌아갑니다.
+
+
+ USB 점검
+
+
+ USB 점검
+
+
+ {0}: Windows에 드라이버가 없어서 fastboot와 adb가 인식하지 못합니다.
+
+
+ {0}: 드라이버가 설치되어 있지만 작동하지 않습니다(코드 {1}). 케이블을 뽑았다가 다시 꽂거나, 드라이버를 다시 설치하세요.
+
+
+ {0}: 휴대폰이 QFIL에서 쓰는 Qualcomm 긴급 다운로드 모드(EDL, 9008)입니다. fastboot로는 이 모드에 접근할 수 없습니다. 빠져나오려면 전원 키를 10~15초간 누르세요.
+
+
+ {0}: 휴대폰이 SP Flash Tool에서 쓰는 MediaTek BROM 또는 preloader 모드입니다. fastboot로는 접근할 수 없습니다. 케이블을 뽑고 휴대폰의 키 조합으로 fastboot를 시작하세요.
+
+
+ {0}: 휴대폰이 Unisoc(Spreadtrum) 다운로드 모드입니다. fastboot로는 접근할 수 없습니다. 케이블을 뽑고 휴대폰의 키 조합으로 fastboot를 시작하세요.
+
+
+ {0}: 휴대폰이 삼성 다운로드(Odin) 모드입니다. 삼성 휴대폰에는 fastboot가 없으며, 이 모드에서는 Odin을 사용합니다.
+
+
+ {0}: 드라이버가 정상 작동하는 fastboot 인터페이스입니다. 휴대폰이 목록에 없으면 케이블을 뽑았다가 다시 꽂으세요.
+
+
+ {0}: 휴대폰이 fastboot가 아닌 Android 또는 리커버리(adb) 상태로 연결되어 있습니다.
+
+
+ Windows에서 USB에 연결된 휴대폰을 찾지 못했습니다.
+
+• 데이터 케이블을 사용하세요. 충전만 되는 케이블이 많습니다.
+• 다른 USB 포트를 써 보세요. 가능하면 PC 본체의 USB 2.0 포트에 직접 연결하세요.
+• 휴대폰이 fastboot(부트로더 또는 fastbootd) 상태인지, adb라면 USB 디버깅이 켜져 있는지 확인하세요.
+
+
+ 드라이버 설치 방법: Google USB Driver(developer.android.com/studio/run/win-usb)나 제조사 드라이버를 받으세요. 그래도 Windows에서 휴대폰이 드라이버 없이 표시되면, 장치 관리자에서 해당 장치를 마우스 오른쪽 버튼으로 클릭 → 드라이버 업데이트 → 내 컴퓨터에서 드라이버 찾아보기 → 컴퓨터의 사용 가능한 드라이버 목록에서 직접 선택 → Android Device → fastboot는 "Android Bootloader Interface", adb는 "Android ADB Interface"를 선택하세요.
+
+
+ 지금 장치 관리자를 열까요?
+
+
+ 여기에 표시되도록 지금 부트로더로 재부팅할까요?
+
+
+ adb로 연결된 휴대폰이 두 대 이상입니다({0}). 올바른 휴대폰이 재시작되도록 다른 휴대폰을 뽑고 다시 시도하세요.
+
+
+ adb로 준비된 휴대폰이 없습니다. 휴대폰에서 USB 디버깅을 허용하고 다시 시도하세요.
+
+
+ 테마
+
+
+ 어둡게
+
+
+ 밝게
+
+
+ Windows 설정 따름
+
+
+ 새 테마는 다시 시작한 후 적용됩니다. 지금 Fastboot Studio를 다시 시작할까요?
+
+
+ 테마를 바꾸기 전에 진행 중인 플래시나 추출이 끝날 때까지 기다리세요.
+
+
+ 터미널
+
+
+ 앱에 포함된 도구로 adb와 fastboot 명령을 직접 실행합니다
+
+
+ 폴더…
+
+
+ 폴더: {0} · 경로 없이 쓴 파일 이름은 여기에서 찾습니다. 파일을 입력줄에 끌어다 놓으면 경로가 추가됩니다
+
+
+ 실행
+
+
+ 중지
+
+
+ adb 또는 fastboot 명령을 입력하고 Enter를 누르세요. 예: fastboot getvar all
+위/아래 키로 이전 명령을 불러올 수 있습니다. 자세한 내용은 help를 입력하세요.
+
+
+ 명령은 adb 또는 fastboot로 시작하며, 앱에 포함된 도구로 실행됩니다.
+ cd FOLDER 파일을 읽을 폴더 변경
+ clear 이 창 비우기
+휴대폰을 벽돌로 만들 수 있는 명령(중요 파티션, 부트로더 잠금, 파티션에 dd)은 먼저 단어를 입력해야 하며, 데이터를 지우는 명령도 확인을 요청합니다.
+adb shell 뒤에는 명령이 필요합니다. 예: adb shell getprop. 중지를 누르면 logcat처럼 계속 실행 중인 명령이 종료됩니다.
+
+
+ 여기서는 adb와 fastboot 명령만 실행됩니다. 줄을 adb나 fastboot로 시작하세요.
+
+
+ 여기서는 adb shell 뒤에 명령이 필요합니다. 예: adb shell getprop ro.product.model
+
+
+ 따옴표가 닫히지 않았습니다.
+
+
+ 플래시가 진행 중입니다. 둘이 동시에 휴대폰과 통신하지 않도록 끝날 때까지 기다리세요.
+
+
+ 실행하지 않았습니다.
+
+
+ [종료 코드 {0}]
+
+
+ [중지됨]
+
+
+ 해당 폴더가 없습니다: {0}
+
+
+ 명령을 시작하지 못했습니다: {0}
+
+
+ 이 명령은 부팅 체인이나 휴대폰 고유 정보(IMEI, 보정값, 키)의 일부인 {0}을(를) 기록하거나 지웁니다. 잘못된 이미지를 넣으면 부트로더조차 진입하지 못하거나, 어떤 펌웨어로도 되살릴 수 없는 데이터를 잃을 수 있습니다.
+
+
+ 부트로더를 잠급니다. 순정 소프트웨어가 아닌 것(커스텀 ROM, 루팅, 패치된 boot, GSI)이 설치된 휴대폰은 부트로더가 잠기면 부팅을 거부합니다. 다시 잠금 해제할 때까지 부팅되지 않을 수 있으며, 잠금 해제하면 데이터가 초기화됩니다.
+
+
+ dd로 휴대폰 파티션에 직접 기록합니다. 이미지나 파티션을 전혀 검사하지 않으므로, 실수하면 휴대폰이 부팅되지 않을 수 있습니다.
+
+
+ 이 명령은 휴대폰의 사용자 데이터(앱, 사진, 파일)를 지웁니다. 실행할까요?
+
+
+ {0} 플래시 전 점검
+
+
+ 이미지를 읽을 수 없습니다: {0}
+
+
+ 이 파일은 boot 이미지가 아니지만, {0}에는 boot 이미지가 들어가야 합니다. 여기에 플래시하면 휴대폰이 부팅되지 않을 가능성이 높습니다.
+
+
+ 이 이미지에는 커널이 없지만(init_boot 이미지이거나 그런 형태), {0}에는 커널이 있어야 합니다. 휴대폰이 부팅되지 않습니다.
+
+
+ 이 휴대폰에는 {0}이(가) 있습니다: 이 이미지는 그곳에 들어갑니다.
+
+
+ 이 이미지에는 커널이 있지만, {0}에는 램디스크만 들어갑니다. 커널이 있는 이미지는 boot용입니다.
+
+
+ 이 이미지는 {0}에 맞지 않습니다: vendor_boot 이미지는 vendor_boot에, boot 이미지는 절대 그곳에 들어가지 않습니다.
+
+
+ 커널은 {0}용으로 빌드되었지만 휴대폰은 {1}을(를) 쓰고 있습니다. 다른 KMI용 커널은 부팅되지 않아 부트루프에 빠집니다.
+
+
+ 커널 버전은 {0}이지만 휴대폰은 {1}을(를) 쓰고 있습니다. 부팅되지 않을 수 있습니다.
+
+
+ 이미지의 보안 패치({0})가 휴대폰({1})보다 오래되었습니다. 일부 휴대폰은 부팅을 거부하거나, 키스토어에 저장된 키(지문, 일부 앱 로그인)를 잃을 수 있습니다.
+
+
+ 커널: {0}
+
+
+ 루트: {0}
+
+
+ 루팅 안 됨 (순정 이미지).
+
+
+ 팁: Android가 실행 중일 때 백업 페이지에서 이 휴대폰을 한 번 열어 두면, 커널과 보안 패치도 여기서 함께 점검합니다.
+
+
+ {1}에 {0}이(가) adb로 보고한 정보와 비교했습니다.
+
+
+ 그래도 {0}에 플래시할까요?
+
+
+ 헤더
+
+
+ 버전 {0}, 페이지 {1}
+
+
+ Android
+
+
+ 보안 패치
+
+
+ 커널
+
+
+ KMI
+
+
+ GKI 아님
+
+
+ 커널 압축
+
+
+ {0} (읽을 수 없음)
+
+
+ 버전을 찾지 못함
+
+
+ 없음 (init_boot)
+
+
+ 램디스크
+
+
+ {0}, 파일 {1}개
+
+
+ 루트
+
+
+ 없음 (순정)
+
+
+ 커맨드 라인
+
+
+ 커널 (마지막으로 adb에서 확인)
+
+
+ 보안 패치 (adb 기준)
+
+
+ {0}이(가) Android 상태입니다: 커널 {1}.
+
+
+ {0}이(가) Android 상태입니다: 커널 {1}, Fastboot Studio Companion {2} ({3}).
+
+
+ 커널 정보를 기록해 두었으므로, 플래시 전에 boot 이미지를 이 커널과 대조합니다. 부트로더로 재시작하려면 USB 점검을 사용하세요.
+
+
+ Companion (adb 기준)
+
+
+ AVB (adb 기준)
+
+
+ 모듈 충돌 (adb 기준)
+
+
+ 숨김 모듈이 속성을 바꿉니다
+
+
+ 없음
+
+
+ 휴대폰이 마지막으로 Android 상태였을 때, Fastboot Studio Companion이 루트 모듈 간 충돌 {0}건을 발견했습니다.
+
+
+ 이 이미지는 {0}(으)로 루팅되었지만 휴대폰은 {1}을(를) 사용합니다. 플래시하면 {1}의 모듈과 설정이 작동하지 않습니다.
+
+
+ 루팅
+
+
+ Magisk, KernelSU 또는 APatch로 휴대폰을 단계별로 루팅합니다
+
+
+ 1 · 루팅 앱과 순정 이미지
+
+
+ 루팅에 쓸 앱을 고른 다음, 휴대폰에 현재 설치된 펌웨어의 순정 이미지를 선택하세요: boot.img 또는 init_boot.img, 아니면 OTA 전체(payload.bin 또는 zip)를 선택하면 알맞은 이미지를 꺼내 씁니다.
+
+
+ 이미지 또는 OTA 선택…
+
+
+ 읽는 중…
+
+
+ {0} · {1}
+
+
+ 순정, 루팅 안 됨
+
+
+ 이미 루팅됨: {0}
+
+
+ {0}은(는) init_boot가 있는 휴대폰(Android 13 이상)에서 init_boot를 패치합니다. 이 OTA에는 init_boot가 있으므로 그 이미지를 사용합니다.
+
+
+ 이 파일은 boot 또는 init_boot 이미지가 아닙니다.
+
+
+ 이 OTA에는 boot나 init_boot 이미지가 없습니다.
+
+
+ 이 이미지는 이미 패치되어 있습니다({0}). 휴대폰에 설치된 것과 같은 펌웨어의 순정 이미지를 패치하세요.
+
+
+ APatch는 boot에 있는 커널을 패치합니다: boot.img(또는 OTA)를 선택하세요.
+
+
+ 2 · 휴대폰으로 보내기
+
+
+ 휴대폰이 USB 디버깅을 켠 상태로 Android에서 실행 중이어야 합니다. 이미지는 Download 폴더에 {0}(으)로 저장됩니다.
+
+
+ 휴대폰으로 보내기
+
+
+ adb로 연결된 휴대폰을 찾지 못했습니다. Android를 실행한 상태에서 USB 디버깅을 허용하고 연결하세요.
+
+
+ {1}의 {0}(으)로 보냈습니다.
+
+
+ 이미지를 보내지 못했습니다: {0}
+
+
+ 3 · 휴대폰에서 패치하기
+
+
+ Magisk 열기 → 설치 → 파일 선택 및 패치 → Download → {0} → 시작하기. All done이 표시되면 아래 버튼을 누르세요.
+
+
+ KernelSU 열기 → 설치 → 파일 선택 → Download → {0} → 다음. 완료되면 아래 버튼을 누르세요.
+
+
+ APatch 열기 → 패치(설치 버튼) → boot 이미지 선택 → Download → {0}, 슈퍼 키 설정 → 시작. 완료되면 아래 버튼을 누르세요.
+
+
+ 패치된 이미지 가져오기
+
+
+ 순정 이미지를 보낸 이후 Download에서 패치된 이미지를 찾지 못했습니다. 먼저 루팅 앱에서 패치하세요.
+
+
+ {0} 가져옴: {1}.
+
+
+ 패치된 이미지에서 루트를 찾지 못했습니다.
+
+
+ 패치된 이미지가 순정 이미지와 종류가 다릅니다(한쪽은 커널이 있고 다른 쪽은 없음).
+
+
+ 패치된 이미지의 커널이 순정 이미지와 다릅니다: 다른 이미지를 패치했을 수 있습니다.
+
+
+ 이 패치된 이미지는 정상으로 보이지 않습니다:
+
+
+ 4 · 플래시하기
+
+
+ 휴대폰이 부트로더로 재시작하고, 패치된 이미지가 활성 슬롯의 {0}에 기록됩니다. 부트로더가 잠금 해제되어 있어야 합니다. 나중에 되돌릴 수 있도록 순정 이미지는 폴더에 남겨 둡니다.
+
+
+ 부트로더로 재시작 후 플래시
+
+
+ 먼저 한 번 시험해 보기
+
+
+ 패치된 boot 이미지를 기록하지 않고 한 번만 부팅합니다. 정상적으로 부팅되면 플래시하거나, 루팅 앱이 직접 설치(Direct install)하게 하세요.
+
+
+ 폴더 열기
+
+
+ {0}을(를) 부트로더로 재시작하고 {1}을(를) {2}에 기록할까요?
+
+부트로더가 잠금 해제되어 있어야 합니다. 이후 휴대폰이 부팅되지 않으면 같은 방법으로 폴더의 순정 이미지를 {2}에 플래시하세요.
+
+
+ 휴대폰이 부트로더로 들어오기를 기다리는 중…
+
+
+ 2분 안에 휴대폰이 fastboot에 나타나지 않았습니다. 드라이버를 확인한 뒤(기기 페이지 → USB 점검) 기기 페이지에서 {0}을(를) 플래시하세요.
+
+
+ {0} 플래시 중…
+
+
+ 플래시 실패: {0}
+
+
+ {0}에 패치된 이미지를 플래시했습니다. 지금 휴대폰을 재시작할까요?
+
+
+ 완료되었습니다. 휴대폰이 켜지면 루팅 앱을 여세요: 설정을 마치고 한 번 더 재시작하라고 할 수 있습니다.
+
+
+ 패치된 이미지로 휴대폰을 한 번 부팅하는 중…
+
+
+ 이미지를 실행하지 못했습니다: {0}
+
+
+ 휴대폰이 패치된 이미지로 부팅 중입니다. 루트가 작동하면 플래시하거나, 루팅 앱에서 직접 설치(Direct install)를 사용하세요.
+
+
+ {0}(으)로 패치됨
+
+
+ 휴대폰
+
+
+ Android 실행 중인 휴대폰의 사양, 보안, 저장된 백업을 보여 주며, Fastboot Studio Companion이 있으면 더 많은 정보를 표시합니다.
+
+
+ 리커버리
+
+
+ 부트로더로 재시작
+
+
+ 다시 읽기
+
+
+ Android 상태인 휴대폰 없음
+
+
+ USB 디버깅을 켠 상태로 휴대폰을 연결하고, 휴대폰에서 요청하면 이 컴퓨터를 허용하세요. 부트로더 상태인 휴대폰은 기기 페이지에 표시됩니다.
+
+
+ {0}이(가) 대기 중입니다: 휴대폰 화면에서 이 컴퓨터의 USB 디버깅을 허용하세요.
+
+
+ {0} 읽는 중…
+
+
+ 기기
+
+
+ 모델
+
+
+ 칩셋
+
+
+ Android
+
+
+ 보안 패치
+
+
+ 슬롯
+
+
+ 배터리
+
+
+ 저장공간
+
+
+ 커널 및 보안
+
+
+ 커널
+
+
+ 부트로더
+
+
+ 루트
+
+
+ 잠김
+
+
+ 잠금 해제됨
+
+
+ 찾지 못함
+
+
+ Companion으로 확인 가능
+
+
+ ROM이나 숨김 모듈이 부팅 속성(ro.boot.*)을 잠긴 것처럼 바꿔 두었습니다. 여기 표시된 상태가 실제 상태입니다: 루트는 부트로더가 잠금 해제된 상태에서만 작동합니다.
+
+
+ 휴대폰 속성에 따른 AVB 값입니다. 숨김 모듈이 바꿀 수 있습니다. Companion은 부트로더 자체의 값을 읽습니다.
+
+
+ 플래시 전에 boot 이미지를 이 커널과 대조합니다.
+
+
+ 수명 {0}%
+
+
+ 충전 횟수 {0}회
+
+
+ 충전량 {0}%
+
+
+ {0} · {1}–{2}% 마모
+
+
+ {0} · 정격 수명 초과
+
+
+ 예비 블록 부족
+
+
+ A/B 슬롯 없음
+
+
+ 동적
+
+
+ 베타
+
+
+ 루트 관리자에게 Companion 보고서를 요청하는 중… Shell 권한을 요청하면 허용하세요.
+
+
+ Companion은 Magisk, KernelSU, APatch용 루트 모듈인데, 이 휴대폰은 루팅되어 있지 않습니다. 여기 있는 정보는 모두 Companion 없이 읽은 것입니다.
+
+
+ 이 휴대폰에 설치되어 있지 않습니다. 설치하면 이 페이지에 부트로더 자체의 AVB 상태, 루트 관리자, 저장공간 마모도, 모듈 간 충돌도 표시됩니다.
+
+
+ Companion 받기
+
+
+ 루트 권한이 거부되었거나 응답이 없습니다. 루트 관리자에서 Shell을 허용한 뒤 다시 읽으세요.
+
+
+ 모듈 {0}개, 서로 충돌 없음
+
+
+ 모듈 간 충돌 {0}건
+
+
+ 같은 파일: {0}
+
+
+ 같은 파일 {1}개: {0}
+
+
+ {0}이(가) 폴더를 대체하여 {1}을(를) 가립니다
+
+
+ 같은 속성: {0}
+
+
+ 및
+
+
+ 휴대폰의 백업
+
+
+ 백업 {0}개 · {1}
+
+
+ 최근: {0}
+
+
+ PC에서 백업 폴더 열기
+
+
+ 휴대폰에 아직 백업이 없습니다. Companion의 백업 탭에서 /sdcard/FastbootStudio/Backups에 백업을 만듭니다.
+
+
+ 루트 없이 adb로 복사한 뒤, 모든 파일을 SHA256SUMS와 대조합니다. 기기 페이지에서 이 백업으로 파티션을 다시 플래시할 수 있습니다.
+
+
+ 백업
+
+
+ 유형
+
+
+ 파일
+
+
+ 크기
+
+
+ 날짜
+
+
+ PC에 있음
+
+
+ 전체
+
+
+ 중요
+
+
+ Boot
+
+
+ 아니요
+
+
+ 복사됨
+
+
+ 복사 중…
+
+
+ 검사 중…
+
+
+ ✓ 복사 완료, 일치함
+
+
+ ✗ 파일 {1}개 중 {0}개 불일치
+
+
+ 복사 실패: {0}
+
+
+ 복사 및 검증
+
+
+ 열기
+
+
+ {0}을(를) {1}(으)로 재시작할까요?
+
+
+ 휴대폰이 재시작하지 않았습니다: {0}
+
+
+ 렌더링
+
+
+ 소프트웨어 (안정적)
+
+
+ 그래픽 카드
+
+
+ 소프트웨어 렌더링을 쓰면 일부 그래픽 드라이버나 원격 데스크톱 앱 때문에 생기는 깜박임, 메뉴 항목 사라짐, 줄무늬 버튼 문제가 사라집니다.
+
+
+ 새 렌더링 방식은 다시 시작한 후 적용됩니다. 지금 Fastboot Studio를 다시 시작할까요?
+
+
+ 두 슬롯 모두 플래시 (a와 b)
+
+
+ modem, boot 같은 펌웨어 파티션을 다른 슬롯에도 기록합니다. super 안의 파티션은 제외합니다.
+
+
+ 사용 중인 슬롯 외에, 나중에 휴대폰이 그 슬롯에서 부팅하더라도 같은 펌웨어를 쓰도록 다음 파티션을 슬롯 {0}에도 기록합니다:
+
+{1}
+
+super 안의 파티션(system, vendor…)은 제외합니다. 계속할까요?
+
+
+ 다른 슬롯에도 기록함: {0}
+
+
+ 업데이트
+
+
+ 자동으로 업데이트 확인
+
+
+ 하루에 한 번 앱의 GitHub 페이지에서 확인합니다. 끄면 여기서 직접 확인하세요.
+
+
+ 지금 확인
+
+
+ 확인 중…
+
+
+ 최신 버전입니다 ✓
+
+
+ {0}을(를) 사용할 수 있습니다
+
+
+ 확인하지 못했습니다: {0}
+
+
+ 업데이트 {0} 사용 가능
+
+
+ 업데이트 사용 가능: {0}
+
+
+ 현재 v{0} · {1} 출시
+
+
+ 현재 v{0}
+
+
+ 새 기능 및 수정 사항
+
+
+ 변경 사항은 릴리스 페이지에 있습니다.
+
+
+ 앱의 GitHub 페이지에서 다운로드하며, 열기 전에 SHA-256을 검사합니다. winget으로 설치했다면: winget upgrade IFOKNR.FastbootStudio
+
+
+ 업데이트 다운로드
+
+
+ 나중에
+
+
+ 이 버전 건너뛰기
+
+
+ 릴리스 페이지 열기
+
+
+ {0} 다운로드 중…
+
+
+ 다운로드가 끝나면 SHA-256을 검사하고 폴더가 열립니다. 앱을 닫고 압축을 푼 뒤 새 버전을 실행하세요.
+
+
+ 다운로드 완료, SHA-256 일치 ✓
+
+
+ 다운로드 폴더: {0}
+
+
+ 앱을 닫고, 기존 폴더에 덮어쓰거나 원하는 폴더에 압축을 푼 뒤 FastbootStudio.exe를 실행하세요. 설정과 백업은 그대로 유지됩니다.
+
+
+ 폴더 열고 앱 닫기
+
+
+ 폴더 열기
+
+
+ 닫기
+
+
+ 업데이트를 다운로드하지 못했습니다
+
+
+ 다운로드한 파일이 SHA-256과 일치하지 않아 삭제했습니다. 다시 시도하거나 릴리스 페이지에서 다운로드하세요.
+
+
+ 릴리스에 zip의 SHA-256이 없어서 앱이 파일을 보관하지 않습니다. 릴리스 페이지에서 다운로드하세요.
+
+
+ 이 릴리스에는 앱이 다운로드할 수 있는 Windows zip이 없습니다. 릴리스 페이지를 열어 받으세요.
+
+
+ 다운로드하지 못했습니다: {0}
+
+
+ 앱이 플래시 또는 추출 중입니다. 작업이 끝나면 닫으세요.
+
+
+ 모든 파일
+
+
+ 삼성
+
+
+ 삼성 펌웨어를 열어 필요한 이미지를 꺼내고, 휴대폰에 맞는지 확인한 뒤 다운로드 모드에서 플래시합니다.
+
+
+ 삼성 펌웨어 열기
+
+
+ AP, BL, CP, CSC, HOME_CSC(.tar.md5), 이 파일들이 있는 폴더, 또는 함께 받은 zip. 여기에 끌어다 놓거나 선택하세요.
+
+
+ 펌웨어 열기…
+
+
+ 폴더 열기…
+
+
+ 펌웨어 읽는 중…
+
+
+ zip 압축 푸는 중 · {0}%
+
+
+ 삼성 펌웨어
+
+
+ 삼성 펌웨어 파일을 찾지 못했습니다. 파일 이름은 AP_, BL_, CP_, CSC_ 또는 HOME_CSC_로 시작하고 .tar.md5로 끝납니다.
+
+
+ 펌웨어 파일
+
+
+ 이 펌웨어 정보
+
+
+ 모델
+
+
+ 빌드 (PDA)
+
+
+ 부트로더 바이너리
+
+
+ 빌드 날짜
+
+
+ Android
+
+
+ CSC
+
+
+ 읽지 않음 (펌웨어 구성 파일 아님)
+
+
+ MD5 {0}%
+
+
+ MD5 ✓
+
+
+ MD5 없음
+
+
+ MD5 ✕ 손상됨
+
+
+ 읽을 수 없음
+
+
+ {0}의 MD5 검사 중
+
+
+ 각 파일의 MD5 검사 중
+
+
+ {0}이(가) 손상되었거나 불완전합니다: MD5가 일치하지 않습니다. 다시 다운로드하세요. 이 파일에서는 아무것도 꺼내지 않습니다.
+
+
+ 펌웨어와 휴대폰 비교
+
+
+ 휴대폰 확인
+
+
+ adb로 휴대폰을 찾는 중…
+
+
+ USB 디버깅을 켠 상태로 Android에서 휴대폰을 연결한 뒤 휴대폰 확인을 누르세요. 펌웨어 자체 검사는 그대로 진행됩니다.
+
+
+ adb로 {0}({1})과(와) 비교했습니다.
+
+
+ 이 펌웨어는 휴대폰에 맞습니다
+
+
+ Odin으로 플래시하세요: AP, BL, CP, 그리고 데이터를 유지하려면 HOME_CSC.
+
+
+ 플래시 전에 읽어 보세요
+
+
+ 플래시할 수는 있지만, 먼저 아래 내용을 확인하세요.
+
+
+ 이 펌웨어를 휴대폰에 플래시하지 마세요
+
+
+ Odin에서 휴대폰이 거부하거나, 다른 휴대폰용 펌웨어입니다.
+
+
+ 펌웨어 {0} · 휴대폰 {1}
+
+
+ 이 휴대폰은 삼성 휴대폰이 아닙니다
+
+
+ 같은 모델
+
+
+ 다른 모델용
+
+
+ 같은 부트로더 바이너리
+
+
+ 더 새로운 부트로더 바이너리
+
+
+ 펌웨어 {0} · 휴대폰 {1}. 이후에는 바이너리 {1}인 펌웨어를 더 이상 설치할 수 없습니다.
+
+
+ 부트로더 바이너리가 휴대폰보다 오래됨
+
+
+ 펌웨어 {0} · 휴대폰 {1}. 삼성은 이 다운그레이드를 막습니다. Odin이 SW REV CHECK FAIL로 멈춥니다.
+
+
+ Android 버전
+
+
+ 휴대폰보다 오래된 Android
+
+
+ 펌웨어 {0} · 휴대폰 {1}. 되돌리려면 전체 CSC가 필요하며, 휴대폰이 초기화됩니다.
+
+
+ 이 펌웨어에 내 지역이 포함되어 있습니다
+
+
+ 다른 CSC (지역)
+
+
+ 펌웨어 {0} · 휴대폰 {1}. 바꾸려면 전체 CSC가 필요하며, 휴대폰이 초기화됩니다.
+
+
+ CSC는 휴대폰을 초기화합니다
+
+
+ 데이터를 유지하려면 Odin의 CSC 칸에 HOME_CSC를 넣으세요.
+
+
+ 이 펌웨어에는 HOME_CSC가 없습니다: 플래시하면 휴대폰이 초기화됩니다.
+
+
+ 서로 다른 펌웨어의 파일
+
+
+ 구성 내용
+
+
+ boot 이미지
+
+
+ {0}개 선택 · {1}
+
+
+ 출처
+
+
+ 파일
+
+
+ 선택 항목 추출 (lz4 해제)
+
+
+ 파일 {0}개 추출 중
+
+
+ LZ4를 해제한 파일 {0}개를 다음 위치에 저장했습니다:
+{1}
+
+
+ 먼저 꺼낼 파일을 선택하세요.
+
+
+ 이미지 도구에서 super 열기
+
+
+ Magisk로 루팅…
+
+
+ Magisk용 파일 준비 중
+
+
+ 먼저 AP 파일을 여세요: Magisk는 그 안의 init_boot(또는 boot)와 vbmeta를 패치합니다.
+
+
+ {0}이(가) 휴대폰의 Download 폴더에 있습니다.
+
+Magisk에서: 설치 › 파일 선택 및 패치 › 이 파일 선택. Magisk가 완료를 알리면 확인을 누르세요. 패치된 파일을 가져와서 검사합니다.
+
+
+ {0}이(가) 다음 위치에 준비되었습니다:
+{1}
+
+adb로 연결된 휴대폰을 찾지 못했습니다. 파일을 휴대폰에 복사해서 Magisk로 패치한 뒤(설치 › 파일 선택 및 패치), Magisk 파일 검사로 결과를 확인하세요.
+
+
+ 패치된 파일 가져오는 중
+
+
+ 휴대폰의 Download 폴더에서 보낸 파일보다 새로운 magisk_patched tar를 찾지 못했습니다. Magisk로 패치한 뒤 다시 시도하세요.
+
+
+ Magisk 파일 검사…
+
+
+ 패치된 파일 검사 중
+
+
+ {0}은(는) Magisk로 패치되었습니다 ✓
+
+Odin에서 AP에 {1}을(를) 넣고, BL, CP, CSC는 같은 펌웨어의 것을 넣으세요. AP만 단독으로 플래시하지 마세요.
+• Magisk를 처음 설치할 때: HOME_CSC가 아닌 CSC. 휴대폰이 초기화되며, Magisk에는 이 초기화가 필요합니다.
+• 이미 루팅된 휴대폰을 업데이트할 때: 데이터를 유지하려면 HOME_CSC.
+
+부트로더 잠금 해제가 필요하며, Knox가 영구히 트립됩니다.
+
+
+ 이 파일의 {0}은(는) Magisk로 패치되지 않았습니다. 루팅용으로 플래시하지 마세요.
+
+
+ 이 tar에는 boot나 init_boot 이미지가 없습니다.
+
+
+ Odin용 tar…
+
+
+ 이미지
+
+
+ Odin용 tar 만드는 중
+
+
+ {0}이(가) Odin의 AP 칸용으로 준비되었습니다. 포함: {1}.
+
+
+ {0}: Odin은 파일 이름이 99자 이하여야 합니다.
+
+
+ 이미지는 LZ4를 해제한 일반 .img로 저장됩니다. super는 sparse 상태로 남으며 이미지 도구에서 풀 수 있습니다. 플래시는 Odin으로 합니다.
+
+
+ 도움말
+
+
+ 도움말 닫기 (Esc)
+
+
+ 이 페이지 도움말
+
+
+ Telegram에서 질문하기
+
+
+ 그래도 해결되지 않나요? 그룹에서 물어보세요.
+
+
+ 이 페이지의 도움말은 아직 작성되지 않았습니다.
+
+
+ 이 페이지의 용도
+
+
+ 단계별 안내
+
+
+ 알아 두면 좋은 점
+
+
+ 알아 둘 용어
+
+
+ 위험: 먼저 읽어 보세요
+
+
+ 둘러보기 및 새 기능
+
+
+ 둘러보기 다시 보기
+
+
+ {0}의 새 기능
+
+
+ 이 버전에는 내장된 릴리스 노트가 없습니다.
+
+
+ {0}의 새 기능
+
+
+ Fastboot Studio가 업데이트되었습니다. 변경 사항은 다음과 같습니다:
+
+
+ 확인
+
+
+ 둘러보기
+
+
+ 건너뛰기
+
+
+ 이전
+
+
+ 다음
+
+
+ 시작
+
+
+ Fastboot Studio에 오신 것을 환영합니다
+
+
+ 플래시, 루팅, 백업을 한 앱에서. 먼저 짧게 둘러보세요: 1분이면 되고, 건너뛸 수도 있습니다.
+
+
+ 사용 중
+
+
+ 각 페이지가 하는 일
+
+
+ 각 페이지는 한 가지 일을 맡고, 모든 페이지 구석에는 단계별로 설명해 주는 ? 버튼이 있습니다. 둘러보기가 끝나면 열 페이지를 선택하세요.
+
+
+ 둘러보기가 끝나면 이 페이지 열기
+
+
+ fastboot 상태인 휴대폰: 상태, 파티션, 빠른 재시작
+
+
+ Android 상태인 휴대폰: 사양, 보안, 백업
+
+
+ OTA 전체를 플래시, 모든 이미지를 먼저 검사
+
+
+ OTA 내부를 살펴보고 이미지 꺼내기
+
+
+ boot 이미지 검사, sparse 변환, super 풀기
+
+
+ 파티션 이미지로 super.img 하나 만들기
+
+
+ 삼성 펌웨어: MD5, 기종 일치 확인, Magisk, Odin용 tar
+
+
+ 파티션과 파일을 이 PC에 저장
+
+
+ Magisk, KernelSU, APatch로 단계별 루팅
+
+
+ adb와 fastboot 명령 직접 실행
+
+
+ 앱이 실행한 모든 기록, 도움을 요청할 때 복사
+
+
+ 버전, 언어, 테마, 업데이트
+
+
+ 빠른 점검
+
+
+ 휴대폰을 연결하기 전에 이 PC에 준비된 것들입니다.
+
+
+ 점검 중…
+
+
+ adb와 fastboot 준비됨
+
+
+ 앱에 포함되어 있습니다(platform-tools 37.0.1): 따로 설치할 것이 없습니다.
+
+
+ adb 또는 fastboot가 없습니다
+
+
+ FastbootStudio.exe와 같은 폴더에 있어야 합니다. exe만이 아니라 다운로드한 파일 전체를 다시 압축 해제하세요.
+
+
+ 삼성 USB 드라이버 설치됨
+
+
+ 다운로드 모드의 삼성 휴대폰용입니다.
+
+
+ 삼성 USB 드라이버가 설치되지 않음
+
+
+ 다운로드 모드의 삼성 휴대폰에만 필요합니다. 앱이 삼성에서 대신 받아 올 수 있습니다.
+
+
+ 설치…
+
+
+ USB 장치를 읽을 수 없습니다
+
+
+ 정상 작동하는 드라이버가 없는 휴대폰이 있습니다
+
+
+ 휴대폰이 fastboot로 연결되어 있습니다
+
+
+ 휴대폰이 Android 또는 리커버리(adb)로 연결되어 있습니다
+
+
+ 삼성 휴대폰이 다운로드 모드입니다
+
+
+ 휴대폰이 칩셋 다운로드 모드(EDL, BROM…)입니다
+
+
+ 연결된 휴대폰이 없습니다
+
+
+ 괜찮습니다: 나중에 연결하세요. Android에서는 개발자 옵션에서 USB 디버깅을 켜세요.
+
+
+ 플래시하기 전에
+
+
+ 대부분의 문제를 막아 주는 네 가지 규칙.
+
+
+ 먼저 백업하기
+
+
+ 백업 페이지에서 하세요. 문제가 생기면 휴대폰을 원래대로 되돌릴 수 있습니다.
+
+
+ 배터리 50% 이상
+
+
+ 플래시 도중 꺼진 휴대폰은 다시 켜지지 않을 수 있습니다.
+
+
+ 케이블을 뽑지 마세요
+
+
+ 좋은 데이터 케이블을 허브가 아닌 PC 본체 포트에 연결하고, 앱이 완료를 알릴 때까지 기다리세요.
+
+
+ 내 휴대폰 전용 파일
+
+
+ 같은 모델, 같은 소프트웨어 버전. 앱이 확인할 수 있는 것은 확인하고, 기록하기 전에 경고합니다.
+
+
+ 정보 페이지에서 이 둘러보기를 다시 볼 수 있습니다.
+
+
+ 삼성 USB 드라이버
+
+
+ developer.samsung.com에서 받음 · 약 37 MB
+
+
+ 이미 설치된 것 같습니다. 다시 설치해도 문제없습니다.
+
+
+ 다운로드 모드의 삼성 휴대폰에는 삼성 전용 드라이버가 필요합니다. Odin이 쓰는 것과 같은 드라이버입니다.
+
+앱이 삼성에서 드라이버를 다운로드하고, Windows가 삼성의 서명을 확인하는지 검사한 뒤 설치 프로그램을 엽니다. Windows가 권한을 요청할 텐데, 드라이버 설치에서는 정상입니다.
+
+
+ 다운로드 및 설치
+
+
+ 삼성 드라이버 다운로드 중
+
+
+ 삼성에서 직접 받습니다. 실행하기 전에 검사합니다.
+
+
+ 다운로드 실패: {0}
+
+
+ 삼성 링크가 보안(https) 주소로 끝나지 않아 파일을 사용하지 않았습니다.
+
+
+ 파일이 삼성 드라이버보다 훨씬 커서 보관하지 않았습니다.
+
+
+ Windows가 파일에서 Samsung Electronics의 유효한 서명을 찾지 못해, 파일을 삭제하고 실행하지 않았습니다.
+
+
+ 삼성 설치 프로그램이 열려 있습니다
+
+
+ 안내에 따라 진행하세요. 완료되면 이 창이 드라이버가 설치되었는지 확인합니다.
+
+
+ Windows에서 설치 프로그램 실행 권한을 받지 못했습니다.
+
+
+ 삼성 드라이버가 설치되었습니다
+
+
+ 삼성 휴대폰이 연결되어 있다면 뽑았다가 다시 꽂으세요.
+
+
+ 닫기
+
+
+ 아직 드라이버가 없습니다
+
+
+ 설치 프로그램이 아직 열려 있다면 먼저 완료한 뒤 다시 확인을 누르세요.
+
+
+ 다시 확인
+
+
+ 삼성 드라이버가 설치되지 않았습니다
+
+
+ 삼성 페이지에서 직접 다운로드할 수 있습니다.
+
+
+ 다시 시도
+
+
+ 삼성 페이지 열기
+
+
+ {0}에 플래시할까요?
+
+
+ 이 이미지는 {0}(으)로 루팅되어 있습니다. 루팅하려는 경우라면 맞습니다. 루트를 제거하려면 대신 같은 펌웨어의 순정 이미지를 플래시하세요.
+
+
+ 먼저 기기 페이지의 이미지로 한 번 부팅…으로 시험해 보세요: {0}에 기록하지 않고 리커버리를 실행하므로, 휴대폰에 맞지 않아도 아무것도 바뀌지 않습니다. 일부 휴대폰은 이 방식으로 이미지를 실행할 수 없습니다.
+
+
+ 이 PC에 삼성 USB 드라이버가 설치되어 있지 않은데, 이 휴대폰에는 필요합니다. 지금 삼성에서 다운로드해 설치할까요?
+
+
+ 삼성 USB 드라이버 설치됨: 다운로드 모드를 인식할 수 있습니다.
+
+
+ 삼성 USB 드라이버가 설치되어 있지 않습니다. 다운로드 모드에 필요합니다.
+
+
+ Knox: 정상 (0x0)
+
+
+ 휴대폰이 보고한 값입니다. 삼성 정식이 아닌 것(루팅, 커스텀 리커버리나 커널)을 플래시하면 영구히 트립됩니다.
+
+
+ Knox 트립됨 (0x1)
+
+
+ 이 휴대폰에서는 Samsung Wallet, 보안 폴더, Samsung Pass를 더 이상 쓸 수 없습니다. 공식 펌웨어를 플래시해도 Knox는 복구되지 않습니다.
+
+
+ Knox가 0x0으로 표시되지만 부트로더가 잠금 해제되어 있습니다
+
+
+ 잠금 해제만으로는 Knox가 트립되지 않습니다. 하지만 비공식적인 것(루팅, 커스텀 리커버리나 커널)을 한 번이라도 플래시했다면 Knox는 영구히 트립된 상태이며, 숨김 모듈이 0x0으로 보이게 하는 것입니다. Samsung Wallet, 보안 폴더, Samsung Pass는 실제 퓨즈 값을 따릅니다.
+
+
+ 다운로드 모드
+
+
+ 다운로드 모드의 휴대폰 읽기: 파티션 테이블(PIT), 모델, 지역
+
+
+ 다운로드 모드에서 휴대폰 읽기
+
+
+ 파티션 테이블(PIT), 모델, 지역을 읽은 뒤, 이와 대조하여 검사하고 플래시합니다.
+
+
+ 휴대폰을 끄고 케이블을 뽑으세요.
+
+
+ 볼륨 업과 볼륨 다운을 함께 누른 채 케이블을 컴퓨터에 꽂으세요. 홈 버튼이 있는 구형 휴대폰: 볼륨 다운 + 홈 + 전원.
+
+
+ 파란색 경고 화면에서 볼륨 업을 한 번 눌러 계속하세요. 그러면 화면에 Downloading이 표시됩니다.
+
+
+ One UI 8.5의 Galaxy S26과 Z Fold 7: 삼성이 먼저 유지 보수 모드를 요구할 수 있습니다(설정 › 디바이스 케어 › 유지 보수 모드).
+
+
+ 휴대폰을 찾는 중…
+
+
+ 아직 다운로드 모드인 휴대폰이 없습니다. 자동으로 갱신됩니다.
+
+
+ {0}에서 다운로드 모드인 휴대폰을 찾았습니다.
+
+
+ 다운로드 모드인 휴대폰이 {0}대입니다: 한 대만 연결해 두세요.
+
+
+ 다운로드 모드인 휴대폰이 있지만, Windows에 정상 작동하는 드라이버가 없습니다: 삼성 USB 드라이버를 설치하세요.
+
+
+ 삼성 USB 드라이버가 없습니다. 다운로드 모드에 필요합니다.
+
+
+ 읽은 후:
+
+
+ Android로 재시작
+
+
+ 다운로드 모드로 재시작
+
+
+ 휴대폰은 연결 한 번에 Odin 세션 하나만 받으므로, 읽은 후 재시작합니다.
+
+
+ 휴대폰 읽기
+
+
+ 휴대폰 읽는 중…
+
+
+ 케이블을 꽂아 두세요. 몇 초 걸립니다.
+
+
+ 읽기 실패
+
+
+ 다른 프로그램이 휴대폰 포트({0})를 쓰고 있습니다: Odin, Smart Switch 또는 다른 플래시 도구를 닫고 다시 시도하세요.
+
+
+ 휴대폰 포트가 사라졌습니다: 케이블이 빠졌거나 휴대폰이 다운로드 모드에서 나갔나요?
+
+
+ 휴대폰 포트를 열지 못했습니다: {0}
+
+
+ 휴대폰이 다운로드 모드의 휴대폰처럼 응답하지 않았습니다.
+
+
+ 휴대폰이 응답을 멈췄습니다: {0}
+
+
+ 다시 시도하기 전에 휴대폰을 다운로드 모드로 재시작하세요: 볼륨 다운 + 전원을 약 7초간 누르고, 화면이 꺼지는 순간 다운로드 모드 키를 누르세요.
+
+
+ 데이터 전송이 되는 케이블을 컴퓨터에 직접(허브 없이) 연결하세요.
+
+
+ 다시 시도
+
+
+ 휴대폰 읽기 완료
+
+
+ {0} 읽기 완료
+
+
+ 휴대폰에는 아무것도 기록하지 않았습니다.
+
+
+ 모델
+
+
+ 일련번호
+
+
+ 지역 (CSC)
+
+
+ 통신사
+
+
+ Odin 프로토콜
+
+
+ v{0}
+
+
+ v{0}, LZ4 펌웨어 지원
+
+
+ 파티션 테이블
+
+
+ 파티션 {0}개
+
+
+ 이 부트로더는 모델을 알려 주지 않습니다. 파티션 테이블은 읽었습니다.
+
+
+ 모델을 읽지 못했습니다. 파티션 테이블은 읽었습니다.
+
+
+ ID
+
+
+ 파티션
+
+
+ 파일
+
+
+ 블록
+
+
+ 휴대폰이 Android로 재시작하는 중입니다.
+
+
+ 휴대폰이 다운로드 모드로 재시작하는 중입니다.
+
+
+ 휴대폰이 세션 종료에 응답하지 않았습니다: 볼륨 다운 + 전원을 약 7초간 눌러 재시작하세요.
+
+
+ PIT 저장…
+
+
+ 저장됨: {0}
+
+
+ 세부 정보 복사
+
+
+ 복사됨
+
+
+ 이 휴대폰은 스스로 다운로드 모드로 재시작하지 않습니다: Android로 재시작하는 중입니다.
+
+
+ 설정
+
+
+ 언어, 화면, 업데이트.
+
+
+ 화면
+
+
+ 글자 크기
+
+
+ 모든 페이지에 바로 적용됩니다.
+
+
+ 작게
+
+
+ 기본
+
+
+ 크게
+
+
+ 더 크게
+
+
+ 글자가 이렇게 보입니다
+
+
+ 안전하게 플래시, 백업, 루팅.
+
+
+ Windows에서 Android 휴대폰을 안전하게 플래시, 백업, 루팅합니다.
+
+
+ 무료 오픈소스
+
+
+ 업데이트 확인
+
+
+ 기반
+
+
+ 구성 요소
+
+
+ 검사
+
+
+ 도구
+
+
+ Telegram 그룹
+
+
+ 내 모든 도구
+
+
+ 잠금 해제되었을 가능성 높음
+
+
+ 속성상으로는 잠겨 있지만, 이 휴대폰에는 {0}이(가) 있고 루트는 부트로더 잠금 해제가 필요합니다: ROM과 숨김 모듈이 잠긴 것처럼 보이게 합니다. 실제 상태를 읽으려면 루트 관리자에서 Shell에 루트를 허용하거나, 부트로더로 재시작한 뒤 기기 페이지를 여세요.
+
+
+ Companion의 백업
+
+
+ {0}, Shell에는 허용되지 않음
+
+
+ Google USB 드라이버
+
+
+ dl.google.com에서 받음 · 약 8 MB
+
+
+ Pixel 휴대폰과, Google USB ID를 쓰는 많은 휴대폰에서 fastboot와 adb를 쓰려면 Google 드라이버가 필요합니다. Android Studio가 설치하는 것과 같은 드라이버입니다.
+
+앱이 Google에서 드라이버를 다운로드하고, 크기와 체크섬을 Google 목록과 대조한 뒤 Windows에 추가를 요청합니다. 다른 드라이버와 마찬가지로 Windows가 권한을 요청합니다.
+
+
+ Google 드라이버 다운로드 중
+
+
+ Google에서 직접 받습니다. 사용하기 전에 검사합니다.
+
+
+ 파일이 Google 목록의 정보({0})와 일치하지 않아, 삭제하고 사용하지 않았습니다.
+
+
+ Google 드라이버 추가 중
+
+
+ Windows가 권한을 요청한 뒤 드라이버를 추가합니다. 몇 초 걸립니다.
+
+
+ Google 드라이버가 설치되었습니다
+
+
+ 휴대폰이 연결되어 있다면 뽑았다가 다시 꽂으세요. 다른 제조사 휴대폰은 여전히 해당 제조사 드라이버가 필요할 수 있습니다.
+
+
+ Google 드라이버가 설치되지 않았습니다
+
+
+ Windows가 드라이버를 추가하지 못했습니다(pnputil 종료 코드 {0}).
+
+
+ Google 페이지에서 직접 다운로드할 수 있습니다.
+
+
+ Google 페이지 열기
+
+
+ Google USB 드라이버 설치됨: Google USB ID의 fastboot와 adb를 인식할 수 있습니다.
+
+
+ Google USB 드라이버가 설치되어 있지 않습니다. Pixel과 Google USB ID를 쓰는 휴대폰에 필요합니다.
+
+
+ USB 드라이버
+
+
+ Windows가 fastboot, adb, 다운로드 모드의 휴대폰을 인식하려면 드라이버가 필요합니다.
+
+
+ 이 휴대폰에는 Google USB 드라이버가 맞습니다(Google USB ID). 지금 Google에서 다운로드해 설치할까요?
+
+
+ 플래시…
+
+
+ 휴대폰 플래시
+
+
+ 기록할 것을 선택하세요: 이미지 하나(boot.img, .lz4), Magisk tar, 또는 펌웨어의 BL, AP, CP, HOME_CSC 파일. 전송하기 전에 모든 파일을 이 휴대폰의 파티션 테이블 및 모델과 대조합니다.
+
+
+ 파일 선택…
+
+
+ 삼성 펌웨어 및 이미지
+
+
+ {0} 검사 중
+
+
+ {0}
+
+파일이 손상되었거나 불완전합니다. 다시 다운로드하세요.
+
+
+ 파일 {0}개 · {1}
+
+
+ {0}의 파티션:
+
+
+ 위 경고를 읽었으며 계속 진행하겠습니다
+
+
+ 완료되면 휴대폰 재시작
+
+
+ 휴대폰을 다운로드 모드로 전환하고 연결하세요. 휴대폰이 인식되면 플래시 버튼이 활성화됩니다.
+
+
+ 파일 {0}개({1})를 휴대폰에 기록할까요?
+
+끝날 때까지 휴대폰을 뽑거나 이 창을 닫지 마세요. 도중에 멈추면 휴대폰은 다운로드 모드에 그대로 있으며 다시 플래시할 수 있습니다.
+
+
+ {0} 기록 중
+
+
+ {1} 중 {0}
+
+
+ 휴대폰을 뽑거나 이 창을 닫지 마세요.
+
+
+ 플래시 완료
+
+
+ 휴대폰이 지금 재시작합니다. 펌웨어 설치 후 첫 부팅은 몇 분 걸릴 수 있습니다.
+
+
+ 휴대폰은 다운로드 모드에 그대로 있습니다. 재시작하려면 전원과 볼륨 다운을 7초간 누르세요.
+
+
+ 기록됨: {0}
+
+
+ 플래시가 중단되었습니다
+
+
+ {0}을(를) 기록하던 중 중단되었습니다: {1}
+
+
+ 아무것도 기록하기 전에 중단되었습니다: {0}
+
+
+ 이 휴대폰의 파티션 테이블이 파일을 검사할 때의 것과 다릅니다(다른 휴대폰을 연결했나요?). 아무것도 기록하지 않았습니다. 휴대폰을 다시 읽으세요.
+
+
+ 휴대폰은 다운로드 모드에 그대로 있습니다. 재시작하지 말고, 다시 연결해서 다시 플래시하세요. 화면에 오류가 표시되면 사진을 찍어 두세요.
+
+
+ 다시 플래시
+
+
+ 뒤로
+
+
+ 플래시할 것이 없습니다: 어떤 파일도 이 휴대폰의 파티션에 해당하지 않습니다.
+
+
+ {0}: 이 휴대폰에는 그런 이름의 파티션이 없습니다. 아래에서 선택하세요.
+
+
+ {0}: 이 휴대폰의 파티션이 아닙니다. Odin과 마찬가지로 제외합니다.
+
+
+ {0}: 파티션 테이블입니다. 플래시하지 않으며, 휴대폰의 파티션은 그대로 유지됩니다.
+
+
+ {0}이(가) {1}의 용량보다 큽니다({2}, 최대 {3}).
+
+
+ {0}에는 휴대폰 고유 정보(IMEI, 키)가 들어 있습니다. 여기서는 절대 플래시하지 않습니다.
+
+
+ {0}에 해당하는 파일이 두 개입니다. 하나만 남기세요.
+
+
+ CSC와 HOME_CSC를 둘 다 선택했습니다. 데이터를 유지하려면 HOME_CSC를, 휴대폰을 초기화하려면 CSC를 남기세요.
+
+
+ 펌웨어는 {0}용인데 이 휴대폰은 {1}입니다. 플래시할 수 없습니다.
+
+
+ 휴대폰이 모델을 알려 주지 않아 펌웨어({0})와 맞는지 확인할 수 없습니다. 이 휴대폰용인지 꼭 확인하세요.
+
+
+ 다음 파일은 다른 빌드의 것입니다: {0}. 한 펌웨어의 BL, AP, CP, CSC를 사용하세요.
+
+
+ {0}은(는) 부트로더의 일부입니다. 잘못된 것을 넣으면 휴대폰이 부팅되지 않을 수 있으며, 휴대폰은 더 오래된 것을 거부합니다.
+
+
+ {0}은(는) 모뎀입니다. 잘못된 것을 넣으면 휴대폰이 신호를 못 잡을 수 있습니다.
+
+
+ {0}은(는) 휴대폰의 모든 것을 지웁니다(공장 초기화). 데이터를 유지하려면 HOME_CSC를 사용하세요.
+
+
+ {0}이(가) 비어 있습니다: 플래시할 내용이 없습니다.
+
+
+ {0}은(는) 삼성 펌웨어 이름 형식이 아니어서 어떤 휴대폰용인지 확인할 수 없습니다. 이 휴대폰용이 확실할 때만 플래시하세요.
+
+
+ payload에 커맨드 라인에 넣을 수 없는 파티션 이름이 있습니다: {0}. 아무것도 플래시하지 않았습니다. 파일이 손상되었거나 변조되었을 수 있습니다.
+
+
+ {0}은(는) UFS 휴대폰에서는 {1}에 들어가지만 eMMC 휴대폰에서는 들어가지 않으며({2}; eMMC 파티션은 최대 {3}), PIT로는 이 휴대폰이 어느 쪽인지 알 수 없습니다. eMMC 휴대폰이라면 플래시 도중 부트로더가 거부합니다.
+
+
+ 이 명령은 활성 슬롯을 바꿉니다: 다음 부팅 때 휴대폰은 내용과 관계없이 다른 슬롯에서 시작합니다. 그 슬롯에 오래되었거나 손상된 시스템이 있으면 부팅되지 않을 수 있습니다. 실행할까요?
+
+
+ 읽었습니다
+
+
+ 플래시 확인
+
+
+ {0}: 파티션 {1}개, {2}. 모든 이미지를 추출하고 해시가 일치할 때까지는 아무것도 기록하지 않습니다.
+
+
+ 플래시
+
+
+ 휴대폰: {0} · {1} · 슬롯 {2} · {3}
+
+
+ 로그 폴더 열기
+
+
+ 모든 플래시는 로그 폴더에 파일로도 저장됩니다(최근 30개 보관).
+
+
+ 사용자가 중지했습니다. 파티션이 일부만 기록되었을 수 있으니, 재시작하기 전에 다시 플래시하세요.
+
+
+ 중지
+
+
+ 휴대폰
+
+
+ ADB로 연결되면 휴대폰에 루트 권한 요청
+
+
+ Companion 보고서(루트 상태, AVB, 모듈 충돌)를 읽습니다. 처음에는 휴대폰에 Magisk 요청 창이 뜹니다. 끄면 휴대폰 페이지에서 직접 읽을 때만 요청합니다.
+
+
+ 휴대폰
+
+
+ 파일
+
+
+ 기타 도구
+
+
+ 재시작 ▾
+
+
+ 연결된 휴대폰 없음
+
+
+ fastboot 상태의 휴대폰을 연결하세요. ADB로 연결된 Android 휴대폰은 휴대폰 페이지에서 읽습니다.
+
+
+ SN {0}
+
+
+ 슬롯 {0}
+
+
+ 잠금 해제됨
+
+
+ 잠김
+
+
+ 최근: fastboot {0} · {1}
+
+
+ {0}초
+
+
+ 파티션 {1}개 중 {0}개 기록됨
+
+
+ 로그 열기
+
+
+ 휴대폰 재시작
+
+
+ 중요
+
+
+ 여기에 파일을 끌어다 놓거나 선택하세요
+
+
+ 휴대폰 (다운로드 모드)
+
+
+ 아직 읽지 않음
+
+
+ 펌웨어 정보
+
+
+ 여기에 파티션 이미지를 끌어다 놓거나 가져오세요
+
+
+ system, vendor, product… raw 또는 sparse 이미지. 또는 fastbootd 상태의 휴대폰에서 레이아웃을 읽으세요.
+
+
+ 시작하기 전에
+
+
+ 부트로더 잠금 해제
+
+
+ USB 디버깅 켜짐, 휴대폰은 Android 상태
+
+
+ 휴대폰에 설치된 펌웨어의 순정 이미지
+
+
+ boot와 중요한 데이터 백업
+
+
+ 완료
+
+
+ 진행 중
+
+
+ 창 뒤 유리 배경 (Windows 11)
+
+
+ 창 너머로 바탕 화면이 흐리게 비칩니다. 끄면 창 자체의 그라데이션을 씁니다.
+
+
+ 키보드 단축키
+
+
+ 이 페이지에서 파일 열기
+
+
+ 로그
+
+
+ 이 페이지 도움말
+
+
+ 설정
+
+
+ 링크
+
+
diff --git a/Properties/Resources.resx b/Properties/Resources.resx
index 17e1b67..079b57a 100644
--- a/Properties/Resources.resx
+++ b/Properties/Resources.resx
@@ -3355,4 +3355,166 @@ Do not unplug the phone or close this window until it ends. If it stops half-way
{0} erases everything on the phone (a factory reset). Use HOME_CSC to keep your data.
+
+ {0} is empty: there is nothing in it to flash.
+
+
+ {0} is not named like Samsung firmware, so the phone it is for cannot be checked. Flash it only if you are sure it is for this phone.
+
+
+ The payload names partitions that cannot be put on a command line: {0}. Nothing was flashed. The file may be damaged or tampered with.
+
+
+ {0} fits {1} on a UFS phone but not on an eMMC one ({2}; an eMMC partition holds at most {3}), and the PIT does not say which this phone is. On an eMMC phone the bootloader refuses it mid-flash.
+
+
+ This command changes the active slot: the phone starts from the other slot next time, whatever is on it. If that slot holds an older or broken system, the phone may not boot. Run it?
+
+
+ I have read this
+
+
+ Confirm the flash
+
+
+ {0}: {1} partitions, {2}. Nothing is written until every image is extracted and its hash checks out.
+
+
+ Flash
+
+
+ Phone: {0} · {1} · slot {2} · {3}
+
+
+ Open log folder
+
+
+ Every flash is also saved as a file in the log folder (the newest 30 are kept).
+
+
+ Stopped by you. The phone may hold a half-written partition; flash it again before restarting.
+
+
+ Stop
+
+
+ Phone
+
+
+ Ask the phone for root when it connects over ADB
+
+
+ Reads the Companion's report (root state, AVB, module conflicts). Magisk shows a prompt on the phone the first time. Off, the Phone page asks only when you read the phone yourself.
+
+
+ Phone
+
+
+ Files
+
+
+ More tools
+
+
+ Restart ▾
+
+
+ No phone connected
+
+
+ Plug a phone in fastboot in; Android phones over ADB are read on the Phone page.
+
+
+ SN {0}
+
+
+ slot {0}
+
+
+ unlocked
+
+
+ locked
+
+
+ last: fastboot {0} · {1}
+
+
+ {0} s
+
+
+ {0} of {1} partitions written
+
+
+ Open the log
+
+
+ Restart the phone
+
+
+ critical
+
+
+ Drop a file here, or choose one
+
+
+ Phone (Download mode)
+
+
+ not read yet
+
+
+ About the firmware
+
+
+ Drop partition images here, or import them
+
+
+ system, vendor, product… as raw or sparse images; or read the layout from a phone in fastbootd.
+
+
+ Before you start
+
+
+ Bootloader unlocked
+
+
+ USB debugging on, phone in Android
+
+
+ The stock image of the firmware on the phone
+
+
+ A backup of boot and the data you care about
+
+
+ done
+
+
+ now
+
+
+ Glass backdrop behind the window (Windows 11)
+
+
+ The desktop shows through the window, blurred. Needs Graphics card drawing below; off, the window keeps its own colour.
+
+
+ Keyboard shortcuts
+
+
+ Open a file on this page
+
+
+ Log
+
+
+ Help for this page
+
+
+ Settings
+
+
+ Links
+
\ No newline at end of file
diff --git a/Properties/Resources.zh-CN.resx b/Properties/Resources.zh-CN.resx
index ddf94b0..4892fa4 100644
--- a/Properties/Resources.zh-CN.resx
+++ b/Properties/Resources.zh-CN.resx
@@ -120,6 +120,9 @@
关于
+
+ Fastboot Studio
+
作者:LibXZR @ akr-developers.com
@@ -163,7 +166,7 @@
当前选择的设备:
- 当前分区
+ 当前槽位
设备
@@ -319,7 +322,9 @@
要强行继续刷入吗?
- 要禁用 vbmeta 校验吗?
+ 要在此 vbmeta 中禁用 dm-verity 和 AVB 校验吗(--disable-verity --disable-verification)?
+
+自定义或修补过的系统需要这样做。仅在 bootloader 已解锁时有效,并且更改后通常需要清除手机数据(恢复出厂设置)。
禁用校验
@@ -477,4 +482,3039 @@
是
+
+ 设备
+
+
+ 刷机
+
+
+ 日志
+
+
+ 实时设备状态、分区和快捷操作
+
+
+ 已连接的设备
+
+
+ 双击设备,或选中后按 Enter。
+
+
+ 还没有处于 bootloader 或 fastbootd 的设备。连接后一秒内就会显示在这里。
+
+
+ 设备变量
+
+
+ 快捷操作
+
+
+ 刷写前检查
+
+
+ 分区操作
+
+
+ Bootloader 已解锁:可以写入镜像
+
+
+ Bootloader 已锁定:设备会拒绝刷写
+
+
+ 没有待处理的 Virtual A/B 更新
+
+
+ 有一个 Virtual A/B 更新处于“{0}”状态:刷写前请先取消
+
+
+ 发现残留的 COW 分区:刷写前请先删除
+
+
+ 处于 fastbootd:可以写入逻辑分区
+
+
+ 处于 bootloader:要写入逻辑分区请重启到 fastbootd
+
+
+ 当前槽位:{0}
+
+
+ {0} 台设备处于 fastboot 模式
+
+
+ 缺少 fastboot.exe
+
+
+ 所有镜像并行解包,并在写入前与清单逐一校验
+
+
+ 未选择 payload
+
+
+ 请先在“设备”页面选择一台设备。
+
+
+ 未选择设备
+
+
+ 目标:{0}
+
+
+ 每个镜像在写入前都会校验 SHA-256。
+
+
+ 所有镜像都成功解包之前,不会向设备写入任何内容。
+
+
+ 空闲
+
+
+ 正在解包
+
+
+ 正在刷写
+
+
+ 完成
+
+
+ 失败
+
+
+ 排队中
+
+
+ 正在解包
+
+
+ 已校验
+
+
+ 正在刷写
+
+
+ 已刷写
+
+
+ 失败
+
+
+ 稍后在 bootloader 中刷写
+
+
+ 正在从 bootloader 刷写
+
+
+ fastbootd 无法写入 {0},因此软件已将手机重启到 bootloader 并在那里完成写入。手机现在处于 bootloader。
+
+
+ 手机没有回到 bootloader。以下分区尚未写入:{0}
+
+
+ 未写入
+
+
+ 阶段
+
+
+ 已用时间
+
+
+ 已写入
+
+
+ 实时日志
+
+
+ 本次会话中的每条 fastboot 命令及其输出
+
+
+ 复制
+
+
+ 清空
+
+
+ 打开 payload.bin 或 OTA zip 以查看内容并导出镜像
+
+
+ 将 payload.bin 或 OTA zip 拖到这里
+
+
+ 压缩格式
+
+
+ 可导出
+
+
+ 进度
+
+
+ 状态
+
+
+ 分区
+
+
+ 大小
+
+
+ Payload 引擎:支持 zstd、xz 和 bzip2,多区段操作,并行解包并校验 SHA-256
+
+
+ 确定吗?
+
+
+ 要擦除分区“{0}”吗?其中的所有数据都将丢失。
+
+
+ 要从 super 中删除逻辑分区“{0}”吗?此操作无法撤销。
+
+
+ 正在刷写 payload。现在关闭会中途停止,可能导致设备无法启动。仍要关闭吗?
+
+
+ 部分镜像不完整:当前版本无法执行的操作已用零填充,这些镜像也未与清单校验。
+
+
+ 已跳过 {0} 个操作,未校验
+
+
+ 正在导出镜像。现在关闭会停止导出并删除未完成的文件。仍要关闭吗?
+
+
+ 以下分区在 payload 中没有 SHA-256,写入前无法校验其镜像:
+
+{0}
+
+仍要刷写吗?
+
+
+ 取消
+
+
+ 警告
+
+
+ 完成
+
+
+ 开发者
+
+
+ 原作者
+
+
+ 基于 LibXZR 的 Fastboot Enhance 开发,以 MIT 许可证发布。Copyright © 2021 LibXZR。
+
+
+ 原项目
+
+
+ 许可证
+
+
+ 备份
+
+
+ 通过 adb 将分区和手机上的任意文件保存到这台电脑
+
+
+ ADB 设备
+
+
+ 型号
+
+
+ 模式
+
+
+ 正在查找设备… 请开启 USB 调试并进入 Android,或进入第三方 Recovery(TWRP、OrangeFox)。
+
+
+ 没有通过 adb 连接的设备。请在开发者选项中开启 USB 调试并连接手机,或进入第三方 Recovery。
+
+
+ 请解锁手机屏幕,并允许这台电脑进行 USB 调试。
+
+
+ 设备处于“{0}”模式。读取分区和文件需要 Android 系统或第三方 Recovery。
+
+
+ 现在可以复制文件。备份分区需要 Root(Magisk、KernelSU)或第三方 Recovery;点击“读取分区表”进行检查。
+
+
+ 已获得 Root shell(Recovery 或 adb root):可以备份分区。
+
+
+ 已通过 su 获得 Root:可以备份分区。
+
+
+ 正在请求 Root 权限;如果手机上弹出提示,请允许。
+
+
+ 读取分区需要 Root。请用 Magisk 或 KernelSU 获取 Root 并允许授权提示,或进入 TWRP、OrangeFox 等第三方 Recovery。仍可在“文件”标签页中复制文件。
+
+
+ 无法从此设备读取分区表。
+
+
+ 分区
+
+
+ 文件
+
+
+ 读取分区表
+
+
+ 选择关键分区
+
+
+ 清除
+
+
+ 按名称筛选
+
+
+ 保存到
+
+
+ 更改…
+
+
+ 备份所选
+
+
+ 取消
+
+
+ 校验备份…
+
+
+ 备份校验
+
+
+ 打开文件夹
+
+
+ 每个镜像的 SHA-256 都会保存在 SHA256SUMS 中,与 backup-info.txt 放在一起。要恢复某个镜像,请在“设备 › 分区”中刷写它。
+
+
+ 正在读取
+
+
+ 已保存
+
+
+ 已跳过
+
+
+ 关键
+
+
+ 请先勾选要备份的分区,或点击“选择关键分区”。
+
+
+ 以下分区较大,备份需要较长时间并占用大量磁盘空间:
+
+{0}
+
+仍要备份吗?
+
+
+ 已读取 {0} / {1};设备停止发送数据(权限被拒绝或已断开连接)
+
+
+ 已保存 {0} 个分区,SHA-256 记录在:
+{1}
+
+
+ 已保存 {0} / {1} 个分区,位置:
+{2}
+
+
+ 已停止。未完成的文件已删除。
+
+
+ 此文件夹中没有 SHA256SUMS 文件,无法进行校验。
+
+
+ 全部 {0} 个文件的 SHA-256 均匹配。
+
+
+ {1} 个文件中有 {0} 个缺失或不匹配:
+
+
+ 上一级
+
+
+ 打开
+
+
+ 内部存储
+
+
+ 相机
+
+
+ 图片
+
+
+ 下载
+
+
+ 文档
+
+
+ 名称
+
+
+ 类型
+
+
+ 文件夹
+
+
+ 文件
+
+
+ 链接
+
+
+ 此文件夹为空,或 Android 不允许在没有 Root 的情况下读取。
+
+
+ {0} 个文件夹,{1} 个文件
+
+
+ 正在复制 {0}…
+
+
+ 复制到电脑
+
+
+ 选择文件或文件夹(按住 Ctrl 或 Shift 多选,Ctrl+A 全选)然后复制。文件夹会连同其中所有内容一起复制。双击文件夹可将其打开。
+
+
+ 请先选择要复制的文件或文件夹。
+
+
+ 已复制 {0} 项到:
+{1}
+
+
+ 已复制 {0} / {1} 项到:
+{2}
+
+
+ 封装格式
+
+
+ OTA zip(直接读取)
+
+
+ OTA zip(解压到临时目录)
+
+
+ 安全补丁
+
+
+ 部分更新
+
+
+ APEX 包
+
+
+ 操作数
+
+
+ {0} 个分区 · {1} · {2}
+
+
+ 已写入 {0} / {1} 个分区
+
+
+ {0},用时 {1} 秒
+
+
+ 最小化
+
+
+ 最大化
+
+
+ 还原
+
+
+ 关闭
+
+
+ 语言
+
+
+ 新语言将在重启后生效。现在重启 Fastboot Studio 吗?
+
+
+ 请等待当前的刷写或导出完成后再更改语言。
+
+
+ 镜像工具
+
+
+ 查看、转换和解包 Android 镜像:sparse、super、ext4、EROFS 等
+
+
+ 打开镜像…
+
+
+ 将镜像拖到这里
+
+
+ system.img、super.img、vendor.img… sparse 或 raw 均可。对于拆分成多个部分的镜像(system.img_sparsechunk.0、.1…),打开任意一部分即可,其余部分会自动找到。
+
+
+ 详情
+
+
+ super 中的分区
+
+
+ Sparse 数据块
+
+
+ 全选
+
+
+ 分组
+
+
+ 类型
+
+
+ 起始块
+
+
+ 块数
+
+
+ 导出分区 (lpunpack)
+
+
+ 转换为 raw (simg2img)
+
+
+ 转换为 sparse (img2simg)
+
+
+ 拆分为多个部分 (simg2simg)
+
+
+ 拆分为每部分最大
+
+
+ 空槽位
+
+
+ 选择了多个文件,但它们不是同一镜像的 sparse 分块。请一次打开一个镜像。
+
+
+ Super(动态分区)
+
+
+ ext4 文件系统
+
+
+ EROFS 文件系统
+
+
+ F2FS 文件系统
+
+
+ Boot 镜像
+
+
+ Vendor boot 镜像
+
+
+ vbmeta(Android 验证启动)
+
+
+ OTA payload(请在 Payload 解包中打开)
+
+
+ Zip 压缩包
+
+
+ 文件
+
+
+ {0} 个部分
+
+
+ 格式
+
+
+ Raw 镜像
+
+
+ 内容
+
+
+ 镜像大小
+
+
+ 占用空间
+
+
+ 块大小
+
+
+ 块数
+
+
+ {1} / {2} / {3}
+
+
+ 数据块
+
+
+ CRC-32
+
+
+ 未记录
+
+
+ 元数据
+
+
+ 版本 {0},{1} 个槽位
+
+
+ 从备份副本读取
+
+
+ Virtual A/B
+
+
+ 分区
+
+
+ {0} 个有数据,共 {1} 个
+
+
+ 分组
+
+
+ 无限制
+
+
+ Super 大小
+
+
+ 分区直接从镜像中读取(无论是否为 sparse),并校验每个元数据校验和。每个分区都以 name.img 保存在镜像旁的文件夹中。
+
+
+ 转换为 raw 会重建完整镜像(合并所有部分),并校验其中的 CRC-32。拆分后得到的各部分可以由 fastboot 逐个刷写。
+
+
+ 转换为 sparse 会将重复的块存为一条记录,这是 fastboot 和官方线刷包使用的格式。输出与 AOSP img2simg 逐字节一致。
+
+
+ 以下文件已存在,将被替换:
+
+{0}
+
+继续吗?
+
+
+ 完成,用时 {0} 秒
+
+
+ Raw 镜像已写入:
+{0}
+{1}
+
+
+ CRC-32 {0}
+
+
+ 已校验 {0} 个记录的校验和
+
+
+ 请输入每部分的最大大小(单位 MB),例如 512。
+
+
+ 请打开单个 sparse 镜像进行拆分。要合并各部分,请先将它们转换为 raw。
+
+
+ 已写入 {0} 个 sparse 文件({1}):
+{2}
+
+
+ 请先勾选要导出的分区。
+
+
+ 已导出 {0} 个分区到:
+{1}
+
+
+ 数据 / 填充 / 无关
+
+
+ {0} 处于 Fastboot 模式
+
+
+ Fastboot 可以写入分区,但无法读回:零售版手机的 Android 不允许这样做。备份通过 adb 进行,因此手机需要先退出 Fastboot,可选以下方式之一:
+
+
+ 启动 Android
+
+
+ 可以立即复制文件。必须开启 USB 调试;备份分区还需要 Root(Magisk 或 KernelSU)。
+
+
+ 启动 Recovery
+
+
+ 适用于已安装的第三方 Recovery(TWRP、OrangeFox):可备份分区和文件,无需 Root。官方 Recovery 不支持 adb。
+
+
+ 临时启动 Recovery 镜像(不安装)
+
+
+ 发送适配此手机的 TWRP 或 OrangeFox 镜像并启动;不会改动手机上的任何内容。需要已解锁的 bootloader。
+
+
+ 选择 Recovery 镜像…
+
+
+ 正在重启 {0}… 手机在 adb 上响应后,此页面会自动切换。
+
+
+ 正在发送 {0} 到手机…
+
+
+ Recovery 镜像已发送并启动。加载完成后,手机会通过 adb 显示在这里,然后即可开始备份。
+
+
+ 手机没有启动该镜像。
+
+{0}
+
+请确认 bootloader 已解锁,且镜像是为此手机制作的。部分手机(三星及少数其他品牌)不支持不刷入直接启动镜像。
+
+
+ 此文件不是 boot 或 recovery 镜像。请选择为此手机制作的 TWRP 或 OrangeFox 的 .img 文件。
+
+
+ 手机处于 fastbootd,无法启动镜像。现在重启到 bootloader 吗?返回后请重新选择镜像。
+
+
+ fastboot 未完成:{0}
+
+
+ 构建 Super
+
+
+ 将多个分区镜像合并为一个可由 fastboot 刷写的 super.img
+
+
+ 从 super.img 导入…
+
+
+ 从手机读取大小
+
+
+ 布局
+
+
+ Virtual A/B
+
+
+ A/B
+
+
+ 单槽位
+
+
+ 与导入的 super 相同
+
+
+ Android 11 及以后的大多数手机。分区带 _a 和 _b 后缀;与官方线刷包一样,槽位 b 留空。
+
+
+ 没有 Virtual A/B 的 A/B 手机(主要是 Android 10)。每个槽位占 super 的一半。
+
+
+ 没有 A/B 槽位的手机:分区保留原名。
+
+
+ 分组、槽位和分区顺序均复制自 {0}。镜像会替换同名分区。
+
+
+ SUPER 大小(字节)
+
+
+ 例如 9126805504
+
+
+ 分组大小(字节)
+
+
+ 分组名称
+
+
+ 自动
+
+
+ 自动:{0}
+
+
+ 已用 {0} / {1} · 剩余 {2}
+
+
+ 输入 super 的大小,即可查看分区占用了多少空间。
+
+
+ 添加镜像…
+
+
+ 添加文件夹…
+
+
+ 移除
+
+
+ 清空
+
+
+ 添加分区镜像(system.img、vendor.img、product.img…)或导入现有 super.img 的布局。由“镜像工具”解包出的镜像会被自动找到。
+
+
+ 镜像
+
+
+ 空
+
+
+ 输出
+
+
+ Sparse
+
+
+ Raw
+
+
+ Sparse 体积更小,也是官方线刷包采用的格式;raw 则是 super 的完整大小。
+
+
+ 构建后校验镜像
+
+
+ 构建 super.img…
+
+
+ 正在构建 super.img
+
+
+ 正在校验 super.img
+
+
+ 刷写命令:fastboot flash super super.img。刷写前请先备份手机当前的 super。
+
+
+ super.img 已构建并通过校验:每个分区都已读回并与其镜像一致。
+
+{0}
+{1} · {2} 个分区
+
+
+ super.img 已构建完成。
+
+{0}
+{1} · {2} 个分区
+
+
+ super.img 已写入但未通过校验,请不要刷写:
+
+{0}
+
+
+ 请输入 super 的大小:从手机读取,或导入一个 super.img。
+
+
+ super 的大小必须是 4096 字节的整数倍。
+
+
+ 此布局的元数据设置无法使用。
+
+
+ 分区过多,元数据区域放不下。
+
+
+ 请至少添加一个分区镜像。
+
+
+ “{0}”不是有效的名称(只能包含字母、数字、_ . -,最多 36 个字符)。
+
+
+ “{0}”出现了两次。
+
+
+ 分组“{0}”不存在。
+
+
+ 分组 {0} 太小:其中的分区需要 {1},而它只允许 {2}。
+
+
+ 分区需要 {0},但 super 只有 {1}。
+
+
+ {0} 的布局 · {1} · {2} 个元数据槽位 · 分组 {3}
+
+
+ 在 {1} 中找到 {0} 个分区镜像。
+
+
+ 此文件不是 super 镜像。
+
+
+ 以下文件不是文件系统镜像,可能不属于 super(boot、vbmeta 等需要单独刷写):
+
+{0}
+
+仍要添加吗?
+
+
+ 已跳过 {0} 个非文件系统镜像的文件:{1}
+
+
+ 此文件夹中没有找到分区镜像。
+
+
+ 要从列表中移除所有分区镜像吗?
+
+
+ 没有处于 fastboot 模式的手机。请在 bootloader 或 fastbootd 下连接后重试。
+
+
+ 已从 {0} 读取:super 为 {1}({2} 字节)。布局:{3}。
+
+
+ 无法从手机读取 super 的大小:
+
+{0}
+
+
+ 正在从手机读取…
+
+
+ 为 {0} 选择镜像
+
+
+ 输出文件是要放入 super 的镜像之一。请换一个文件名。
+
+
+ 高通线刷包的分片({0})
+
+
+ 这 {0} 个文件是同一个 {1} 镜像的分片,由 {2} 定位。可将它们合并为一个镜像,或直接从分片中导出分区。
+
+
+ 合并为 sparse
+
+
+ 合并为 raw
+
+
+ 已将 {0} 个分片合并为一个镜像:
+
+{1}
+{2}
+
+{3}
+
+
+ 刷写命令:fastboot flash super super.img
+
+
+ Raw 镜像是分区的完整大小;用于 fastboot 时 sparse 镜像体积更小。
+
+
+ 输入 {0} 以确认:
+
+
+ 关键分区
+
+
+ {0} 属于启动链,或保存着手机的身份信息(IMEI、校准数据、密钥)。在这里刷入错误的镜像,可能导致手机连 bootloader 都进不去,或丢失任何固件都无法恢复的数据。
+
+只能刷入为这台手机专门制作的镜像,并先备份当前镜像。
+
+
+ 擦除 {0} 可能导致手机无法启动,或永久清除其 IMEI、校准数据或密钥。此操作无法撤销。
+
+
+ 切换槽位
+
+
+ 槽位 {0} 当前无法启动,因此未将其激活。
+
+
+ 槽位 {0} 很可能无法启动。仍要切换吗?
+
+
+ 要切换到槽位 {0} 吗?
+
+
+ 槽位 {0} 尚未完成过一次启动。如果刚刚刷写过它,这是正常的;否则手机可能会回退到另一个槽位或无法启动。
+
+
+ Bootloader 将槽位 {0} 标记为不可启动。
+
+
+ 槽位 {0} 已没有剩余的启动尝试次数,且从未成功启动过。
+
+
+ 槽位 {0} 的以下分区缺失或为空:{1}。请先刷写该槽位(或完整固件)。
+
+
+ 临时启动镜像…
+
+
+ 临时启动
+
+
+ 临时启动一次 boot 或 recovery 镜像而不刷入;重启手机后会回到已安装的系统。
+
+
+ 此镜像没有内核(init_boot 镜像或同类的 boot 镜像),手机无法单独启动它。请启动完整的 boot.img,或改为刷写 init_boot。
+
+
+ 这是 vendor_boot 镜像:只包含 ramdisk 和设备树,不能单独启动。
+
+
+ 此文件不是 boot 或 recovery 镜像。
+
+
+ 手机处于 fastbootd,无法启动镜像。现在重启到 bootloader 吗?之后请重新选择镜像。
+
+
+ 镜像已发送,手机正在启动它。正常重启手机即可回到已安装的系统。
+
+
+ Super
+
+
+ 在 fastbootd 中显示:bootloader 不会列出 super 内的分区。
+
+
+ 手机没有报告 super 的大小。
+
+
+ 共 {0},约剩余 {1}
+
+
+ 槽位 {0}:{1}
+
+
+ (使用中)
+
+
+ 更新副本 (COW):{0}
+
+
+ 无槽位:{0}
+
+
+ super 空间不足
+
+
+ 这些镜像在 super 中还需要约 {0} 的空间({1}),但只剩约 {2}。fastbootd 会以“Not enough space to resize partition”报错停止。
+
+腾出空间的方法:
+
+
+ 删除槽位 {0} 的分区:{1}。在重新刷写之前,槽位 {0} 将无法启动。
+
+
+ 清除之前更新留下的内容:取消待处理的更新(取消更新),或删除 COW 分区。
+
+
+ super 没有被其他内容占用;这些镜像比这台手机的 super 还大。
+
+
+ 以上数字为估算值。仍要刷写吗?
+
+
+ 缺少分区
+
+
+ 手机上没有 {0}。这些是此更新放在 super 内的分区,可以现在在 super 中创建(空分区),然后再写入。
+
+fastbootd 会将新分区放在“default”分组,而不是手机自己的分组(例如 main_a)。手机可以正常启动;下一次完整更新或刷写官方 super 时,它们会回到原来的分组。
+
+创建并继续吗?
+
+
+ fastbootd 会将新分区放在“default”分组,而不是手机自己的分组(例如 main_a)。这不影响使用;下一次完整更新会将其放回原来的分组。
+
+
+ USB 检查
+
+
+ USB 检查
+
+
+ {0}:Windows 没有它的驱动,因此 fastboot 和 adb 无法识别。
+
+
+ {0}:驱动已安装但无法正常工作(代码 {1})。请拔下后重新插入,或重新安装驱动。
+
+
+ {0}:手机处于高通紧急下载模式(EDL,9008),供 QFIL 使用。fastboot 无法访问此模式;长按电源键 10 到 15 秒即可退出。
+
+
+ {0}:手机处于联发科 BROM 或 preloader 模式,供 SP Flash Tool 使用。fastboot 无法访问;请拔下手机,并用手机的组合键进入 fastboot。
+
+
+ {0}:手机处于紫光展锐(Spreadtrum)下载模式。fastboot 无法访问;请拔下手机,并用手机的组合键进入 fastboot。
+
+
+ {0}:手机处于三星 Download(Odin)模式。三星手机没有 fastboot;此模式需要使用 Odin。
+
+
+ {0}:fastboot 接口,驱动工作正常。如果列表中没有手机,请拔下后重新插入。
+
+
+ {0}:手机以 Android 或 recovery(adb)方式连接,而不是 fastboot。
+
+
+ Windows 在 USB 上没有检测到手机。
+
+• 请使用数据线;很多线只能充电。
+• 换一个 USB 接口,尽量使用电脑主机上的 USB 2.0 接口。
+• 确认手机处于 fastboot(bootloader 或 fastbootd),或者使用 adb 时已开启 USB 调试。
+
+
+ 安装驱动:下载 Google USB Driver(developer.android.com/studio/run/win-usb)或手机厂商的驱动。如果 Windows 仍显示手机没有驱动,请在设备管理器中右键点击它 → 更新驱动程序 → 浏览我的电脑以查找驱动程序 → 让我从计算机上的可用驱动程序列表中选取 → Android Device → fastboot 选“Android Bootloader Interface”,adb 选“Android ADB Interface”。
+
+
+ 现在打开设备管理器吗?
+
+
+ 现在将其重启到 bootloader,让它显示在这里吗?
+
+
+ 有多台手机通过 adb 连接({0})。请拔下其他手机后重试,以确保重启的是正确的手机。
+
+
+ 没有通过 adb 就绪的手机。请在手机上允许 USB 调试后重试。
+
+
+ 外观
+
+
+ 深色
+
+
+ 浅色
+
+
+ 跟随 Windows
+
+
+ 新外观将在重启后生效。现在重启 Fastboot Studio 吗?
+
+
+ 请等待当前的刷写或导出完成后再更改外观。
+
+
+ 终端
+
+
+ 使用软件自带的工具,自己运行 adb 和 fastboot 命令
+
+
+ 文件夹…
+
+
+ 文件夹:{0} · 未带路径的文件名会在此处查找;将文件拖到输入行即可添加其路径
+
+
+ 运行
+
+
+ 停止
+
+
+ 输入 adb 或 fastboot 命令并按 Enter,例如:fastboot getvar all
+按上下方向键可调出之前的命令。输入 help 查看更多。
+
+
+ 命令以 adb 或 fastboot 开头,并使用软件自带的工具运行。
+ cd FOLDER 更改读取文件的文件夹
+ clear 清空此窗口
+可能导致手机变砖的命令(关键分区、锁定 bootloader、用 dd 写入分区)会先要求你输入一个词进行确认;清除数据的命令也会要求确认。
+adb shell 后面需要跟一条命令,例如 adb shell getprop;“停止”会结束仍在运行的命令,例如 logcat。
+
+
+ 这里只能运行 adb 和 fastboot 命令。请以 adb 或 fastboot 开头。
+
+
+ 在这里 adb shell 后面需要跟一条命令,例如:adb shell getprop ro.product.model
+
+
+ 引号没有闭合。
+
+
+ 正在刷写;请等待完成,避免两者同时与手机通信。
+
+
+ 未运行。
+
+
+ [退出代码 {0}]
+
+
+ [已停止]
+
+
+ 文件夹不存在:{0}
+
+
+ 无法启动命令:{0}
+
+
+ 此命令会写入或擦除 {0},它属于启动链或手机身份信息(IMEI、校准数据、密钥)的一部分。在这里写入错误的镜像,可能导致手机连 bootloader 都进不去,或丢失任何固件都无法恢复的数据。
+
+
+ 此操作会锁定 bootloader。如果手机运行的不是原厂系统(第三方 ROM、Root、修补过的 boot、GSI),锁定的 bootloader 会拒绝启动:手机可能无法再开机,直到重新解锁,而解锁会清除所有数据。
+
+
+ 此操作会用 dd 直接写入手机的分区。不会检查镜像或分区;一旦出错,手机可能无法启动。
+
+
+ 此命令会清除手机上的用户数据(应用、照片、文件)。确定运行吗?
+
+
+ 刷写 {0} 前检查
+
+
+ 无法读取镜像:{0}
+
+
+ 此文件不是 boot 镜像,但 {0} 存放的是 boot 镜像。刷到这里很可能导致手机无法启动。
+
+
+ 此镜像没有内核(它是 init_boot 镜像,或者结构与之相同),但 {0} 必须包含内核。手机将无法启动。
+
+
+ 这台手机有 {0}:此镜像应该刷到那里。
+
+
+ 此镜像包含内核,但 {0} 只存放 ramdisk。带内核的镜像应刷到 boot。
+
+
+ 此镜像不属于 {0}:vendor_boot 镜像应刷到 vendor_boot,boot 镜像则绝不应刷到那里。
+
+
+ 此内核是为 {0} 构建的,但手机运行的是 {1}。为其他 KMI 构建的内核无法启动:手机会无限重启。
+
+
+ 内核版本为 {0},但手机运行的是 {1}。可能无法启动。
+
+
+ 镜像的安全补丁({0})比手机的({1})旧。部分手机会拒绝启动,或丢失 keystore 中保存的密钥(指纹、部分应用的登录信息)。
+
+
+ 内核:{0}
+
+
+ Root:{0}
+
+
+ 未 Root(原厂镜像)。
+
+
+ 提示:在 Android 运行时,在“备份”页面打开这台手机一次,这里就会同时检查它的内核和安全补丁。
+
+
+ 已与 {0} 于 {1} 通过 adb 报告的信息进行比较。
+
+
+ 仍要将其刷写到 {0} 吗?
+
+
+ 头部
+
+
+ 版本 {0},页大小 {1}
+
+
+ Android
+
+
+ 安全补丁
+
+
+ 内核
+
+
+ KMI
+
+
+ 非 GKI
+
+
+ 内核压缩
+
+
+ {0}(无法读取)
+
+
+ 未找到版本
+
+
+ 无(init_boot)
+
+
+ Ramdisk
+
+
+ {0},{1} 个文件
+
+
+ Root
+
+
+ 无(原厂)
+
+
+ 命令行
+
+
+ 内核(上次通过 adb 获取)
+
+
+ 安全补丁(通过 adb)
+
+
+ {0} 处于 Android:内核 {1}。
+
+
+ {0} 处于 Android:内核 {1},Fastboot Studio Companion {2}({3})。
+
+
+ 已记录其内核,刷写前会用它来检查 boot 镜像。使用“USB 检查”可将其重启到 bootloader。
+
+
+ Companion(通过 adb)
+
+
+ AVB(通过 adb)
+
+
+ 模块冲突(通过 adb)
+
+
+ 有隐藏模块修改了该属性
+
+
+ 无
+
+
+ 上次手机处于 Android 时,Fastboot Studio Companion 发现 Root 模块之间有 {0} 处冲突。
+
+
+ 此镜像使用 {0} Root,但手机使用的是 {1}。刷入后,{1} 的模块和设置将无法使用。
+
+
+ Root
+
+
+ 使用 Magisk、KernelSU 或 APatch 一步步 Root 手机
+
+
+ 1 · Root 应用和原厂镜像
+
+
+ 选择要使用的 Root 应用,然后选择手机当前所运行固件的原厂镜像:boot.img 或 init_boot.img,也可以选择整个 OTA(payload.bin 或 zip),软件会从中取出正确的镜像。
+
+
+ 选择镜像或 OTA…
+
+
+ 正在读取…
+
+
+ {0} · {1}
+
+
+ 原厂,未 Root
+
+
+ 已 Root:{0}
+
+
+ 在有 init_boot 的手机上(Android 13 及以后),{0} 修补的是 init_boot。此 OTA 包含 init_boot,因此将使用该镜像。
+
+
+ 此文件不是 boot 或 init_boot 镜像。
+
+
+ 此 OTA 中没有 boot 或 init_boot 镜像。
+
+
+ 此镜像已经修补过({0})。请改为修补与手机当前固件相同的原厂镜像。
+
+
+ APatch 修补的是内核,而内核位于 boot 中:请选择 boot.img(或 OTA)。
+
+
+ 2 · 发送到手机
+
+
+ 手机必须处于 Android 系统并已开启 USB 调试。镜像会以 {0} 的名称保存到 Download 文件夹。
+
+
+ 发送到手机
+
+
+ 没有通过 adb 找到手机。请在 Android 运行时连接手机,并允许 USB 调试。
+
+
+ 已发送到 {1} 上的 {0}。
+
+
+ 无法发送镜像:{0}
+
+
+ 3 · 在手机上修补
+
+
+ 打开 Magisk → 安装 → 选择并修补一个文件 → Download → {0} → 开始。显示 All done 后,点击下方按钮。
+
+
+ 打开 KernelSU → 安装 → 选择一个文件 → Download → {0} → 下一步。完成后,点击下方按钮。
+
+
+ 打开 APatch → 修补(安装按钮)→ 选择 boot 镜像 → Download → {0},设置超级密钥 → 开始。完成后,点击下方按钮。
+
+
+ 获取修补后的镜像
+
+
+ 自发送原厂镜像以来,Download 中没有找到修补后的镜像。请先在 Root 应用中进行修补。
+
+
+ 已获取 {0}:{1}。
+
+
+ 修补后的镜像中没有找到 Root。
+
+
+ 修补后的镜像与原厂镜像类型不同(一个有内核,另一个没有)。
+
+
+ 修补后的镜像内核与原厂镜像不同:可能修补了另一个镜像。
+
+
+ 这个修补后的镜像看起来不对:
+
+
+ 4 · 刷写
+
+
+ 手机会重启到 bootloader,修补后的镜像将写入当前槽位的 {0}。Bootloader 必须已解锁。原厂镜像会保留在文件夹中,方便以后还原。
+
+
+ 重启到 bootloader 并刷写
+
+
+ 先临时启动试试
+
+
+ 用修补后的 boot 镜像临时启动一次手机,不写入。如果能正常启动,再刷写它,或让 Root 应用自行安装(直接安装)。
+
+
+ 打开文件夹
+
+
+ 将 {0} 重启到 bootloader 并把 {1} 写入 {2} 吗?
+
+Bootloader 必须已解锁。如果之后手机无法启动,请用同样的方式把文件夹中的原厂镜像刷到 {2}。
+
+
+ 正在等待手机进入 bootloader…
+
+
+ 两分钟内手机没有出现在 fastboot 中。请检查驱动(设备页面 → USB 检查),然后在设备页面刷写 {0}。
+
+
+ 正在刷写 {0}…
+
+
+ 刷写失败:{0}
+
+
+ {0} 已刷入修补后的镜像。现在重启手机吗?
+
+
+ 完成。手机启动后,打开 Root 应用:它可能会要求完成设置并再重启一次。
+
+
+ 正在用修补后的镜像临时启动手机…
+
+
+ 无法启动镜像:{0}
+
+
+ 手机正在用修补后的镜像启动。如果 Root 正常,再刷写它,或在 Root 应用中使用“直接安装”。
+
+
+ 已用 {0} 修补
+
+
+ 手机
+
+
+ 运行 Android 时的手机:配置、安全状态和其中的备份,Fastboot Studio Companion 还能提供更多信息。
+
+
+ Recovery
+
+
+ 重启到 bootloader
+
+
+ 重新读取
+
+
+ 没有处于 Android 的手机
+
+
+ 开启 USB 调试后连接手机,并在手机询问时允许这台电脑。处于 bootloader 的手机会显示在“设备”页面。
+
+
+ {0} 正在等待:请在手机屏幕上允许这台电脑进行 USB 调试。
+
+
+ 正在读取 {0}…
+
+
+ 设备
+
+
+ 型号
+
+
+ 芯片
+
+
+ Android
+
+
+ 安全补丁
+
+
+ 槽位
+
+
+ 电池
+
+
+ 存储
+
+
+ 内核与安全
+
+
+ 内核
+
+
+ Bootloader
+
+
+ Root
+
+
+ 已锁定
+
+
+ 已解锁
+
+
+ 未发现
+
+
+ 安装 Companion 后可知
+
+
+ ROM 或隐藏模块修改了启动属性(ro.boot.*),使其看起来像已锁定。这里显示的是真实状态:只有解锁的 bootloader 才能 Root。
+
+
+ AVB 状态来自手机的属性;隐藏模块可能会修改它们。Companion 读取的是 bootloader 自身的状态。
+
+
+ 刷写前会用这个内核检查 boot 镜像。
+
+
+ 健康度 {0}%
+
+
+ {0} 次循环
+
+
+ 电量 {0}%
+
+
+ {0} · 磨损 {1}–{2}%
+
+
+ {0} · 已超出额定寿命
+
+
+ 备用块即将耗尽
+
+
+ 无 A/B 槽位
+
+
+ 动态分区
+
+
+ Beta
+
+
+ 正在向 Root 管理器请求 Companion 的报告… 如有提示请允许 Shell。
+
+
+ Companion 是适用于 Magisk、KernelSU 或 APatch 的 Root 模块,而这台手机没有 Root。这里的所有信息都是在没有它的情况下读取的。
+
+
+ 这台手机未安装。安装后,此页面还会显示 bootloader 自身的 AVB 状态、Root 管理器、存储磨损以及模块之间的冲突。
+
+
+ 获取 Companion
+
+
+ Root 请求被拒绝或没有响应。请在 Root 管理器中允许 Shell,然后重新读取。
+
+
+ {0} 个模块,彼此没有冲突
+
+
+ 模块之间有 {0} 处冲突
+
+
+ 相同文件:{0}
+
+
+ {1} 个相同文件:{0}
+
+
+ {0} 替换了文件夹,隐藏了 {1}
+
+
+ 相同属性:{0}
+
+
+ 和
+
+
+ 手机上的备份
+
+
+ {0} 个备份 · {1}
+
+
+ 最近:{0}
+
+
+ 在电脑上打开备份文件夹
+
+
+ 手机上还没有备份。Companion 可以在其“备份”标签页中创建备份,保存到 /sdcard/FastbootStudio/Backups。
+
+
+ 通过 adb 复制(无需 Root),然后逐个文件与 SHA256SUMS 校验。可以在“设备”页面用它们刷回分区。
+
+
+ 备份
+
+
+ 类型
+
+
+ 文件
+
+
+ 大小
+
+
+ 日期
+
+
+ 电脑上
+
+
+ 完整
+
+
+ 关键
+
+
+ Boot
+
+
+ 否
+
+
+ 已复制
+
+
+ 正在复制…
+
+
+ 正在校验…
+
+
+ ✓ 已复制且一致
+
+
+ ✗ {1} 个文件中有 {0} 个不一致
+
+
+ 复制失败:{0}
+
+
+ 复制并校验
+
+
+ 打开
+
+
+ 要将 {0} 重启到 {1} 吗?
+
+
+ 手机没有重启:{0}
+
+
+ 绘制方式
+
+
+ 软件(稳定)
+
+
+ 显卡
+
+
+ 软件绘制可以消除某些显卡驱动和远程桌面软件造成的闪烁、菜单项消失和按钮条纹等问题。
+
+
+ 新的绘制方式将在重启后生效。现在重启 Fastboot Studio 吗?
+
+
+ 刷写两个槽位(a 和 b)
+
+
+ modem、boot 等固件分区也会写入另一个槽位。super 中的分区不包括在内。
+
+
+ 除当前使用的槽位外,以下分区也会写入槽位 {0},这样手机从该槽位启动时也能找到相同的固件:
+
+{1}
+
+super 中的分区(system、vendor…)不包括在内。继续吗?
+
+
+ 也已写入另一个槽位:{0}
+
+
+ 更新
+
+
+ 自动检查更新
+
+
+ 每天一次,从软件的 GitHub 页面检查。关闭后,可以在这里手动检查。
+
+
+ 立即检查
+
+
+ 正在检查…
+
+
+ 已是最新版本 ✓
+
+
+ {0} 可用
+
+
+ 无法检查:{0}
+
+
+ 有可用更新 {0}
+
+
+ 有可用更新:{0}
+
+
+ 当前版本 v{0} · 发布于 {1}
+
+
+ 当前版本 v{0}
+
+
+ 新功能与修复
+
+
+ 更改内容请查看发布页面。
+
+
+ 从软件的 GitHub 页面下载;打开前会校验其 SHA-256。用 winget 安装的?winget upgrade IFOKNR.FastbootStudio
+
+
+ 下载更新
+
+
+ 稍后
+
+
+ 跳过此版本
+
+
+ 打开发布页面
+
+
+ 正在下载 {0}…
+
+
+ 下载完成后会校验 SHA-256 并打开所在文件夹。关闭软件,解压后运行新版本。
+
+
+ 已下载,SHA-256 一致 ✓
+
+
+ 位于“下载”文件夹:{0}
+
+
+ 关闭软件,将其解压覆盖旧版本(或解压到任意文件夹),然后运行 FastbootStudio.exe。你的设置和备份会保持不变。
+
+
+ 打开文件夹并关闭软件
+
+
+ 打开文件夹
+
+
+ 关闭
+
+
+ 更新未下载
+
+
+ 下载的文件与其 SHA-256 不一致,已被删除。请重试,或从发布页面下载。
+
+
+ 该版本没有提供 zip 的 SHA-256,因此软件不会保留它。请从发布页面下载。
+
+
+ 该版本没有软件可以下载的 Windows zip。请打开发布页面获取。
+
+
+ 无法下载:{0}
+
+
+ 软件正在刷写或导出。完成后再关闭。
+
+
+ 所有文件
+
+
+ 三星
+
+
+ 打开三星固件,取出所需的镜像,检查是否适合你的手机,并在 Download 模式下刷写。
+
+
+ 打开三星固件
+
+
+ AP、BL、CP、CSC 和 HOME_CSC(.tar.md5),或它们所在的文件夹,或它们所在的 zip。拖到这里或手动选择。
+
+
+ 打开固件…
+
+
+ 打开文件夹…
+
+
+ 正在读取固件…
+
+
+ 正在解压 zip · {0}%
+
+
+ 三星固件
+
+
+ 没有找到三星固件文件。它们的文件名以 AP_、BL_、CP_、CSC_ 或 HOME_CSC_ 开头,以 .tar.md5 结尾。
+
+
+ 固件文件
+
+
+ 关于此固件
+
+
+ 型号
+
+
+ 版本号 (PDA)
+
+
+ Bootloader 版本 (Binary)
+
+
+ 构建日期
+
+
+ Android
+
+
+ CSC
+
+
+ 未读取(不是固件组成部分)
+
+
+ MD5 {0}%
+
+
+ MD5 ✓
+
+
+ 无 MD5
+
+
+ MD5 ✕ 已损坏
+
+
+ 无法读取
+
+
+ 正在校验 {0} 的 MD5
+
+
+ 正在校验每个文件的 MD5
+
+
+ {0} 已损坏或不完整:其 MD5 不一致。请重新下载;不会从中取出任何内容。
+
+
+ 固件与手机比对
+
+
+ 检查手机
+
+
+ 正在通过 adb 查找手机…
+
+
+ 在 Android 下开启 USB 调试并连接手机,然后点击“检查手机”。固件本身仍会单独检查。
+
+
+ 已通过 adb 与 {0}({1})进行比较。
+
+
+ 此固件适合你的手机
+
+
+ 用 Odin 刷写:AP、BL 和 CP,加上 HOME_CSC 以保留数据。
+
+
+ 刷写前请先阅读
+
+
+ 此固件可以刷写,但请先查看下面几点。
+
+
+ 不要在你的手机上刷写此固件
+
+
+ 手机会在 Odin 中拒绝它,或者它是为其他手机制作的。
+
+
+ 固件 {0} · 手机 {1}
+
+
+ 这台手机不是三星
+
+
+ 型号相同
+
+
+ 为其他型号制作
+
+
+ Bootloader 版本 (Binary) 相同
+
+
+ Bootloader 版本 (Binary) 更新
+
+
+ 固件 {0} · 手机 {1}。刷入后,将无法再安装 Binary 为 {1} 的固件。
+
+
+ Bootloader 版本 (Binary) 比手机的旧
+
+
+ 固件 {0} · 手机 {1}。三星禁止这种降级;Odin 会以 SW REV CHECK FAIL 停止。
+
+
+ Android 版本
+
+
+ Android 版本比手机的旧
+
+
+ 固件 {0} · 手机 {1}。降级需要完整的 CSC,会清除手机数据。
+
+
+ 此固件包含你的地区
+
+
+ 其他 CSC(地区)
+
+
+ 固件 {0} · 手机 {1}。更改地区需要完整的 CSC,会清除手机数据。
+
+
+ CSC 会清除手机数据
+
+
+ 在 Odin 的 CSC 栏中放入 HOME_CSC 可保留数据。
+
+
+ 此固件没有 HOME_CSC:刷写会清除手机数据。
+
+
+ 文件来自不同的固件
+
+
+ 包含内容
+
+
+ Boot 镜像
+
+
+ 已选择 {0} 个 · {1}
+
+
+ 来源
+
+
+ 文件
+
+
+ 导出所选(解开 lz4)
+
+
+ 正在导出 {0} 个文件
+
+
+ 已保存 {0} 个文件(已解开 LZ4),位置:
+{1}
+
+
+ 请先选择要取出的文件。
+
+
+ 在镜像工具中打开 super
+
+
+ 用 Magisk Root…
+
+
+ 正在为 Magisk 准备文件
+
+
+ 请先打开 AP 文件:Magisk 会修补其中的 init_boot(或 boot)和 vbmeta。
+
+
+ {0} 已在手机的 Download 文件夹中。
+
+在 Magisk 中:安装 › 选择并修补一个文件 › 选中它。Magisk 显示完成后,点击“确定”,软件会取回修补后的文件并进行检查。
+
+
+ {0} 已准备好,位置:
+{1}
+
+没有通过 adb 找到手机。请将它复制到手机,在 Magisk 中修补(安装 › 选择并修补一个文件),然后用“检查 Magisk 文件”检查结果。
+
+
+ 正在取回修补后的文件
+
+
+ 在手机的 Download 文件夹中没有找到比发送的文件更新的 magisk_patched tar。请在 Magisk 中修补后重试。
+
+
+ 检查 Magisk 文件…
+
+
+ 正在检查修补后的文件
+
+
+ {0} 已用 Magisk 修补 ✓
+
+在 Odin 中,将 {1} 放入 AP,BL、CP 和 CSC 使用同一固件中的文件。切勿只刷 AP。
+• 首次安装 Magisk:使用 CSC 而不是 HOME_CSC。这会清除手机数据,而 Magisk 需要这次清除。
+• 已经 Root 的手机进行更新:使用 HOME_CSC 以保留数据。
+
+这需要已解锁的 bootloader,并且会永久熔断 Knox。
+
+
+ 此文件中的 {0} 没有用 Magisk 修补。不要刷写它来 Root 手机。
+
+
+ 此 tar 中没有 boot 或 init_boot 镜像。
+
+
+ 制作 Odin 用 tar…
+
+
+ 镜像
+
+
+ 正在制作 Odin 用 tar
+
+
+ {0} 已可放入 Odin 的 AP 栏,包含 {1}。
+
+
+ {0}:Odin 要求文件名不超过 99 个字符。
+
+
+ 解开 LZ4 后,镜像保存为普通 .img;super 保持 sparse 格式,可用镜像工具解包。刷写仍需使用 Odin。
+
+
+ 帮助
+
+
+ 关闭帮助 (Esc)
+
+
+ 此页面的帮助
+
+
+ 在 Telegram 提问
+
+
+ 仍然没解决?到群里提问。
+
+
+ 此页面暂无帮助内容。
+
+
+ 此页面的用途
+
+
+ 操作步骤
+
+
+ 注意事项
+
+
+ 术语解释
+
+
+ 危险:请先阅读
+
+
+ 导览与新功能
+
+
+ 再次显示导览
+
+
+ {0} 的新功能
+
+
+ 此版本没有内置更新说明。
+
+
+ {0} 的新功能
+
+
+ Fastboot Studio 已更新。以下是更改内容:
+
+
+ 确定
+
+
+ 开始导览
+
+
+ 跳过
+
+
+ 上一步
+
+
+ 下一步
+
+
+ 开始
+
+
+ 欢迎使用 Fastboot Studio
+
+
+ 一个软件搞定刷机、Root 和备份。先来个简短导览:只需一分钟,也可以跳过。
+
+
+ 使用中
+
+
+ 各页面的功能
+
+
+ 每个页面只负责一项工作,并且每个页面角落都有一个 ?,会一步步说明用法。选择一个页面,导览结束后将打开它。
+
+
+ 导览结束后打开此页面
+
+
+ fastboot 下的手机:状态、分区和快捷重启
+
+
+ Android 下的手机:配置、安全状态和备份
+
+
+ 刷写完整 OTA,每个镜像都先经过校验
+
+
+ 查看 OTA 内容并取出其中的镜像
+
+
+ 查看 boot 镜像、转换 sparse、解包 super
+
+
+ 用分区镜像构建一个 super.img
+
+
+ 三星固件:MD5、匹配检查、Magisk、Odin 用 tar
+
+
+ 将分区和文件保存到这台电脑
+
+
+ 使用 Magisk、KernelSU 或 APatch 一步步 Root
+
+
+ 自己运行 adb 和 fastboot 命令
+
+
+ 软件运行过的所有内容,求助时可以复制
+
+
+ 版本、语言、主题和更新
+
+
+ 快速检查
+
+
+ 在插入手机之前,看看这台电脑已经准备好了什么。
+
+
+ 正在检查…
+
+
+ adb 和 fastboot 已就绪
+
+
+ 它们随软件附带(platform-tools 37.0.1):无需安装。
+
+
+ 缺少 adb 或 fastboot
+
+
+ 它们应位于 FastbootStudio.exe 旁边。请重新完整解压下载的文件,而不只是 exe。
+
+
+ 已安装三星 USB 驱动
+
+
+ 用于 Download 模式下的三星手机。
+
+
+ 未安装三星 USB 驱动
+
+
+ 只有 Download 模式下的三星手机需要它。软件可以帮你从三星获取。
+
+
+ 安装…
+
+
+ 无法读取 USB 设备
+
+
+ 有手机的驱动无法正常工作
+
+
+ 有手机以 fastboot 连接
+
+
+ 有手机以 Android 或 recovery(adb)连接
+
+
+ 有三星手机处于 Download 模式
+
+
+ 有手机处于芯片的下载模式(EDL、BROM…)
+
+
+ 没有连接手机
+
+
+ 没关系:稍后再插入。在 Android 中,请在开发者选项里开启 USB 调试。
+
+
+ 刷机之前
+
+
+ 四条规则,可以避免大多数问题。
+
+
+ 先备份
+
+
+ 在“备份”页面进行。万一出了问题,可以把手机恢复原样。
+
+
+ 电量高于 50%
+
+
+ 刷机过程中关机的手机可能无法再启动。
+
+
+ 不要拔数据线
+
+
+ 使用质量好的数据线,插在电脑主机的接口上,不要用 USB 集线器,并等到软件提示完成。
+
+
+ 使用与你的手机完全对应的文件
+
+
+ 型号相同,软件版本也相同。软件会尽可能检查,并在写入前提醒你。
+
+
+ 可以在“关于”中再次查看此导览。
+
+
+ 三星 USB 驱动
+
+
+ 来自 developer.samsung.com · 约 37 MB
+
+
+ 看起来已经安装了;重新安装也没有坏处。
+
+
+ Download 模式下的三星手机需要三星自己的驱动;与 Odin 使用的驱动相同。
+
+软件会从三星下载驱动,确认 Windows 能在其上找到三星的签名,然后打开安装程序。Windows 会请求权限:这对驱动来说是正常的。
+
+
+ 下载并安装
+
+
+ 正在下载三星驱动
+
+
+ 直接从三星下载。运行前会进行检查。
+
+
+ 下载失败:{0}
+
+
+ 三星的链接最终没有指向安全(https)地址,因此未使用该文件。
+
+
+ 该文件远大于三星驱动的大小,因此未保留。
+
+
+ Windows 没有在该文件上找到 Samsung Electronics 的有效签名,因此已将其删除且未运行。
+
+
+ 三星安装程序已打开
+
+
+ 按照其步骤操作。完成后,此窗口会检查驱动是否已安装。
+
+
+ Windows 没有获得运行安装程序的权限。
+
+
+ 三星驱动已安装
+
+
+ 如果已插入三星手机,请拔下后重新插入。
+
+
+ 关闭
+
+
+ 驱动尚未安装
+
+
+ 如果安装程序仍在运行,请先完成安装,然后点击“重新检查”。
+
+
+ 重新检查
+
+
+ 三星驱动未安装
+
+
+ 你可以自己从三星的页面下载。
+
+
+ 重试
+
+
+ 打开三星页面
+
+
+ 要将其刷写到 {0} 吗?
+
+
+ 此镜像已用 {0} Root。用于 Root 手机是正确的;如果要移除 Root,请改为刷写同一固件中的原厂镜像。
+
+
+ 可以先在“设备”页面用“临时启动镜像…”试一下:它会启动该 Recovery 而不写入 {0},如果不适合这台手机也不会有任何改动。部分手机无法以这种方式启动镜像。
+
+
+ 这台电脑没有安装三星 USB 驱动,而这台手机需要它。现在从三星下载并安装吗?
+
+
+ 已安装三星 USB 驱动:可以识别 Download 模式。
+
+
+ 未安装三星 USB 驱动。Download 模式需要它。
+
+
+ Knox:完好 (0x0)
+
+
+ 根据手机自身报告。刷入任何非三星官方的内容(Root、第三方 Recovery 或内核)都会永久熔断 Knox。
+
+
+ Knox 已熔断 (0x1)
+
+
+ Samsung Wallet、安全文件夹和 Samsung Pass 在这台手机上已无法使用。刷回官方固件也无法恢复 Knox。
+
+
+ Knox 显示 0x0,但 bootloader 已解锁
+
+
+ 仅解锁不会熔断 Knox。但如果曾经刷入过任何非官方内容(Root、第三方 Recovery 或内核),Knox 就已永久熔断,是隐藏模块让它显示为 0x0。Samsung Wallet、安全文件夹和 Samsung Pass 以真实的熔丝状态为准。
+
+
+ Download 模式
+
+
+ 读取 Download 模式下的手机:分区表 (PIT)、型号和地区
+
+
+ 在 Download 模式下读取手机
+
+
+ 读取分区表 (PIT)、型号和地区;然后根据这些信息检查并刷写。
+
+
+ 关闭手机并拔下数据线。
+
+
+ 同时按住音量加和音量减,然后将数据线插入电脑。带 Home 键的旧款手机:音量减 + Home + 电源。
+
+
+ 在蓝色警告界面,按一次音量加继续。屏幕随后会显示 Downloading。
+
+
+ One UI 8.5 的 Galaxy S26 和 Z Fold 7:三星可能会要求先开启维修模式(设置 › 设备维护 › 维修模式)。
+
+
+ 正在查找手机…
+
+
+ 还没有处于 Download 模式的手机。此处会自动更新。
+
+
+ 已在 {0} 上找到处于 Download 模式的手机。
+
+
+ 有 {0} 台手机处于 Download 模式:请只保留一台连接。
+
+
+ 有手机处于 Download 模式,但 Windows 没有可用的驱动:请安装三星 USB 驱动。
+
+
+ 缺少三星 USB 驱动;Download 模式需要它。
+
+
+ 读取之后:
+
+
+ 重启到 Android
+
+
+ 重启到 Download 模式
+
+
+ 手机每次连接只接受一个 Odin 会话,因此读取后会重启。
+
+
+ 读取手机
+
+
+ 正在读取手机…
+
+
+ 请保持数据线连接。这需要几秒钟。
+
+
+ 读取失败
+
+
+ 其他程序占用了手机的端口({0}):请关闭 Odin、Smart Switch 或其他刷机工具,然后重试。
+
+
+ 手机的端口消失了:是拔掉了数据线,还是手机退出了 Download 模式?
+
+
+ 无法打开手机的端口:{0}
+
+
+ 手机的响应不像处于 Download 模式的手机。
+
+
+ 手机停止响应:{0}
+
+
+ 重试之前,请将手机重启到 Download 模式:按住音量减 + 电源约 7 秒,在屏幕变黑时按住进入 Download 模式的组合键。
+
+
+ 请使用能传输数据的数据线,并直接插在电脑上(不要用集线器)。
+
+
+ 重试
+
+
+ 已读取手机
+
+
+ 已读取 {0}
+
+
+ 没有向手机写入任何内容。
+
+
+ 型号
+
+
+ 序列号
+
+
+ 地区 (CSC)
+
+
+ 运营商
+
+
+ Odin 协议
+
+
+ v{0}
+
+
+ v{0},支持 LZ4 固件
+
+
+ 分区表
+
+
+ {0} 个分区
+
+
+ 此 bootloader 不提供型号信息;分区表已读取。
+
+
+ 无法读取型号;分区表已读取。
+
+
+ ID
+
+
+ 分区
+
+
+ 文件
+
+
+ 块数
+
+
+ 手机正在重启到 Android。
+
+
+ 手机正在重启到 Download 模式。
+
+
+ 手机没有响应会话结束指令:请按住音量减 + 电源约 7 秒来重启。
+
+
+ 保存 PIT…
+
+
+ 已保存:{0}
+
+
+ 复制详情
+
+
+ 已复制
+
+
+ 这台手机无法自行重启到 Download 模式:它正在重启到 Android。
+
+
+ 设置
+
+
+ 语言、外观和更新。
+
+
+ 外观
+
+
+ 文字大小
+
+
+ 所有页面会立即应用。
+
+
+ 小
+
+
+ 默认
+
+
+ 大
+
+
+ 更大
+
+
+ 文字显示效果如下
+
+
+ 安全地刷机、备份和 Root。
+
+
+ 在 Windows 上安全地为 Android 手机刷机、备份和 Root。
+
+
+ 免费开源
+
+
+ 检查更新
+
+
+ 基于
+
+
+ 内置
+
+
+ 检查
+
+
+ 工具
+
+
+ Telegram 群组
+
+
+ 我的所有工具
+
+
+ 可能已解锁
+
+
+ 属性显示为已锁定,但这台手机有 {0},而 Root 需要已解锁的 bootloader:ROM 和隐藏模块会让它看起来像已锁定。要读取真实状态,请在 Root 管理器中为 Shell 授予 Root,或重启到 bootloader 并打开“设备”页面。
+
+
+ Companion 的备份
+
+
+ {0},未授权给 Shell
+
+
+ Google USB 驱动
+
+
+ 来自 dl.google.com · 约 8 MB
+
+
+ Pixel 以及许多使用 Google USB ID 的手机,在 fastboot 和 adb 下需要 Google 的驱动。它与 Android Studio 安装的驱动相同。
+
+软件会从 Google 下载驱动,按照 Google 的列表检查其大小和校验值,然后请 Windows 添加它。与安装任何驱动一样,Windows 会请求权限。
+
+
+ 正在下载 Google 驱动
+
+
+ 直接从 Google 下载。使用前会进行检查。
+
+
+ 该文件与 Google 列出的信息不一致({0}),因此已将其删除且未使用。
+
+
+ 正在添加 Google 驱动
+
+
+ Windows 会请求权限,然后添加驱动。需要几秒钟。
+
+
+ Google 驱动已安装
+
+
+ 如果已插入手机,请拔下后重新插入。其他品牌的手机可能仍需要其厂商自己的驱动。
+
+
+ Google 驱动未安装
+
+
+ Windows 无法添加驱动(pnputil 以代码 {0} 结束)。
+
+
+ 你可以自己从 Google 的页面下载。
+
+
+ 打开 Google 页面
+
+
+ 已安装 Google USB 驱动:可以识别使用 Google USB ID 的 fastboot 和 adb 设备。
+
+
+ 未安装 Google USB 驱动。Pixel 和使用 Google USB ID 的手机需要它。
+
+
+ USB 驱动
+
+
+ Windows 需要驱动才能识别处于 fastboot、adb 或 Download 模式的手机。
+
+
+ Google USB 驱动适用于这台手机(Google 的 USB ID)。现在从 Google 下载并安装吗?
+
+
+ 刷写…
+
+
+ 刷写手机
+
+
+ 选择要写入的内容:单个镜像(boot.img、.lz4)、Magisk tar,或固件的 BL、AP、CP 和 HOME_CSC 文件。发送任何内容之前,每个文件都会与这台手机的分区表和型号进行核对。
+
+
+ 选择文件…
+
+
+ 三星固件和镜像
+
+
+ 正在检查 {0}
+
+
+ {0}
+
+文件已损坏或不完整。请重新下载。
+
+
+ {0} 个文件 · {1}
+
+
+ {0} 的分区:
+
+
+ 我已阅读上述警告,确定继续
+
+
+ 完成后重启手机
+
+
+ 将手机置于 Download 模式并连接。找到手机后,“刷写”按钮会启用。
+
+
+ 要将 {0} 个文件({1})写入手机吗?
+
+完成之前不要拔下手机或关闭此窗口。如果中途停止,手机会停留在 Download 模式,可以重新刷写。
+
+
+ 正在写入 {0}
+
+
+ {0} / {1}
+
+
+ 不要拔下手机或关闭此窗口。
+
+
+ 刷写完成
+
+
+ 手机现在会重启。刷固件后的首次启动可能需要几分钟。
+
+
+ 手机停留在 Download 模式。要重启,请按住电源和音量减 7 秒。
+
+
+ 已写入:{0}
+
+
+ 刷写已停止
+
+
+ 在写入 {0} 时停止:{1}
+
+
+ 在写入任何内容之前停止:{0}
+
+
+ 这台手机的分区表与文件核对时的不同(是否插入了另一台手机?)。没有写入任何内容。请重新读取手机。
+
+
+ 手机停留在 Download 模式。不要重启:重新连接后再次刷写。如果屏幕上显示错误,请拍照留存。
+
+
+ 重新刷写
+
+
+ 返回
+
+
+ 没有可刷写的内容:所有文件在这台手机上都没有对应的分区。
+
+
+ {0}:这台手机上没有该名称的分区。请在下方选择一个。
+
+
+ {0}:不是这台手机上的分区;已跳过,与 Odin 的处理方式相同。
+
+
+ {0}:这是分区表。不会刷写;手机的分区保持不变。
+
+
+ {0} 超出了 {1} 的容量({2},最多 {3})。
+
+
+ {0} 保存着手机的身份信息(IMEI、密钥)。这里绝不会刷写它。
+
+
+ {0} 有两个文件。请保留一个。
+
+
+ 同时选择了 CSC 和 HOME_CSC。保留 HOME_CSC 可保留数据,保留 CSC 则会清除手机数据。
+
+
+ 此固件适用于 {0},但这台手机是 {1}。无法刷写。
+
+
+ 手机没有报告型号,因此无法将固件({0})与其匹配。请确认它适用于这台手机。
+
+
+ 以下文件来自其他版本:{0}。请使用同一固件的 BL、AP、CP 和 CSC。
+
+
+ {0} 是 bootloader 的一部分。刷入错误的版本可能导致手机无法启动,且手机会拒绝较旧的版本。
+
+
+ {0} 是基带。刷入错误的版本可能导致手机没有信号。
+
+
+ {0} 会清除手机上的所有内容(恢复出厂设置)。使用 HOME_CSC 可保留数据。
+
+
+ {0} 是空的:没有可刷写的内容。
+
+
+ {0} 的命名不像三星固件,因此无法检查它适用于哪台手机。只有在确定它适用于这台手机时才刷写。
+
+
+ payload 中的分区名称无法用于命令行:{0}。没有刷写任何内容。文件可能已损坏或被篡改。
+
+
+ {0} 在 UFS 手机上可以放入 {1},但在 eMMC 手机上放不下({2};eMMC 分区最多容纳 {3}),而 PIT 没有说明这台手机是哪一种。在 eMMC 手机上,bootloader 会在刷写中途拒绝它。
+
+
+ 此命令会更改当前槽位:手机下次将从另一个槽位启动,无论其中是什么。如果该槽位中是较旧或损坏的系统,手机可能无法启动。确定运行吗?
+
+
+ 我已阅读
+
+
+ 确认刷写
+
+
+ {0}:{1} 个分区,{2}。在所有镜像都解包并通过哈希校验之前,不会写入任何内容。
+
+
+ 刷写
+
+
+ 手机:{0} · {1} · 槽位 {2} · {3}
+
+
+ 打开日志文件夹
+
+
+ 每次刷写也会以文件形式保存在日志文件夹中(保留最新的 30 个)。
+
+
+ 已由你停止。手机上可能有写入一半的分区;重启前请重新刷写。
+
+
+ 停止
+
+
+ 手机
+
+
+ 手机通过 ADB 连接时请求 Root
+
+
+ 读取 Companion 的报告(Root 状态、AVB、模块冲突)。Magisk 第一次会在手机上弹出提示。关闭后,只有在你手动读取手机时,“手机”页面才会请求。
+
+
+ 手机
+
+
+ 文件
+
+
+ 更多工具
+
+
+ 重启 ▾
+
+
+ 未连接手机
+
+
+ 插入处于 fastboot 的手机;通过 ADB 连接的 Android 手机会在“手机”页面读取。
+
+
+ SN {0}
+
+
+ 槽位 {0}
+
+
+ 已解锁
+
+
+ 已锁定
+
+
+ 上次:fastboot {0} · {1}
+
+
+ {0} 秒
+
+
+ 已写入 {0} / {1} 个分区
+
+
+ 打开日志
+
+
+ 重启手机
+
+
+ 关键
+
+
+ 将文件拖到这里,或选择一个文件
+
+
+ 手机(Download 模式)
+
+
+ 尚未读取
+
+
+ 关于此固件
+
+
+ 将分区镜像拖到这里,或导入
+
+
+ system、vendor、product… raw 或 sparse 镜像均可;也可以从处于 fastbootd 的手机读取布局。
+
+
+ 开始之前
+
+
+ Bootloader 已解锁
+
+
+ 已开启 USB 调试,手机处于 Android
+
+
+ 手机当前固件的原厂镜像
+
+
+ 已备份 boot 和重要数据
+
+
+ 完成
+
+
+ 当前
+
+
+ 窗口背后的毛玻璃效果(Windows 11)
+
+
+ 透过窗口可以看到模糊的桌面。关闭后,窗口使用自身的渐变背景。
+
+
+ 键盘快捷键
+
+
+ 在此页面打开文件
+
+
+ 日志
+
+
+ 此页面的帮助
+
+
+ 设置
+
+
+ 链接
+
\ No newline at end of file
diff --git a/README.ar.md b/README.ar.md
index a223970..93bda97 100644
--- a/README.ar.md
+++ b/README.ar.md
@@ -25,6 +25,8 @@
> - **فلاش سامسونج** في وضع التحميل من التطبيق نفسه: صورة وحدة، أو tar من Magisk، أو الروم كامل (BL و AP و CP و HOME_CSC). كل ملف ينفحص أول (MD5 و lz4 وجدول PIT حق الجوال وموديله)، وينرفض EFS وروم الموديل الثاني، ولو وقف الفلاش يبقى الجوال في وضع التحميل.
> - **تعريف قوقل USB** بضغطة، من الإعدادات أو فحص USB: ينحمّل من قوقل وينفحص.
>
+> **الجديد في 3.0:** شكل زجاجي جديد (رمادي زجاجي بالليلي وثلجي بالنهاري، وأيقونة جديدة)، والصفحات بمجموعات مع شريط للجوال فوق وشريط حالة تحت، وملخص واحد قبل الفلاش والنتيجة على الصفحة، وسجل لكل فلاش، وزر إيقاف للأمر المعلّق، واختصارات كيبورد.
+>
> **الجديد في 2.8:**
> - زر **؟** في زاوية كل صفحة يفتح شرحها على الجنب: وش فايدتها، الخطوات، الأشياء الخطيرة، والكلمات اللي تحتاج تعرفها. بالعربي والإنجليزي.
> - **جولة ترحيب** قصيرة أول مرة (اللغة، الصفحات، فحص سريع للكمبيوتر، قواعد الأمان)، و**الجديد** يطلع لك أول مرة بعد كل تحديث.
@@ -45,8 +47,6 @@
> - **فلّش على السلوتين**: أقسام الفيرموير مثل modem و boot تنكتب على سلوت a و b.
> - لو fastbootd رفض قسم (مثل modem في OnePlus)، يكمل الباقي ويكتبه من البوت لودر.
>
-> 🔜 **قريباً: Odin.** تفليش جوالات سامسونج مباشرة من وضع Download وبنفس الفحوصات، فيصير الروم من التحميل للجوال في برنامج واحد.
->
> **الجديد في 2.5:**
> - صفحة **الجوال** للجوال وهو شغّال على أندرويد: المواصفات والكيرنل والحماية والبطارية، ومع إضافة
> Companion حالة AVB من البوت لودر نفسه وتعارض المودات ونسخها الاحتياطية.
@@ -84,7 +84,7 @@
3. شغّل `FastbootStudio.exe`.
**لا يحتاج تثبيت أي شيء:** .NET و adb و fastboot (platform-tools 37.0.1) كلها مدمجة.
-فقط تأكد أن تعريف USB الخاص بجوالك مثبت في ويندوز، مثل [Google USB Driver](https://developer.android.com/studio/run/win-usb). ولجوالات سامسونج، البرنامج يقدر يحمّل تعريف سامسونج ويثبّته لك.
+فقط تأكد أن تعريف USB الخاص بجوالك مثبت في ويندوز؛ والبرنامج يقدر يحمّل لك [تعريف قوقل](https://developer.android.com/studio/run/win-usb) (بكسل والجوالات اللي على معرّفات قوقل) وتعريف سامسونج ويثبّتهم، من الإعدادات أو فحص USB.
**فتح ملف مباشرة:** اسحب ملف التحديث أو الصورة وأفلته على البرنامج، أو شغّل `FastbootStudio.exe ota.zip`.
@@ -114,7 +114,7 @@
| Infinix و Tecno و itel وجوالات ميدياتك | ✅ في أغلب الموديلات | خيارات المطور ← فتح قفل OEM، وبعدها `fastboot flashing unlock` (يختلف حسب الموديل) | SP Flash Tool بس لإنعاش جوال في وضع BROM |
| Nothing و Fairphone و ASUS والجوالات القريبة من أندرويد الأصلي | ✅ غالباً | الأمر القياسي | |
| Oppo و Realme و vivo | ⚠️ حسب الموديل | موديلات كثيرة ما ينفتح لها أبداً | ميزات adb تشتغل عليها كلها |
-| سامسونج | ⚠️ ما فيها fastboot | فتح قفل OEM، وبعدها ضغطة طويلة على رفع الصوت في وضع التحميل | **صفحة سامسونج** تفحص الروم، وتروّت بـ Magisk، وتسوي ملفات tar لـ Odin، والبرنامج يثبّت تعريف سامسونج. التفليش الحين بـ Odin، والتفليش من البرنامج قادم |
+| سامسونج | ⚠️ ما فيها fastboot | فتح قفل OEM، وبعدها ضغطة طويلة على رفع الصوت في وضع التحميل | **صفحة سامسونج** تفحص الروم، وتروّت بـ Magisk، وتسوي ملفات tar لـ Odin، وتفلّش من وضع التحميل داخل البرنامج، والبرنامج يثبّت تعريف سامسونج |
| Huawei و Honor | ❌ للتفليش | الأكواد وقفت من 2018 | ميزات adb (صفحة الجوال، ونسخ الملفات) تشتغل |
**بدون فتح البوت لودر**، هذي تشتغل على أي جوال، أو بدون جوال أصلاً:
@@ -301,7 +301,7 @@
- **وضع التحميل:** يقرا الجوال وهو في وضع التحميل عن طريق المنفذ اللي يسويه تعريف سامسونج، مثل ما يسوي Odin: الموديل والرقم التسلسلي والمنطقة (CSC) ونسخة بروتوكول أودين وجدول التقسيم (PIT) وتقدر تحفظه كملف `.pit`. ما يرسل أي شي يكتب على الجوال، وبعدها يعيد تشغيله (للأندرويد أو لوضع التحميل مرة ثانية).
- **tar لـ Odin:** أي صور (recovery حق TWRP، boot معدّل…) في ملف `.tar.md5`.
-**الفائدة:** الروم الغلط، ونزول البوت لودر، ومسح الجوال بالغلط، كلها تنكشف قبل ما تفتح Odin أصلاً. **قريباً:** التفليش من وضع Download، و Odin داخل البرنامج.
+**الفائدة:** الروم الغلط، ونزول البوت لودر، ومسح الجوال بالغلط، كلها تنكشف قبل ما تفتح Odin أصلاً، والروم يتفلش من وضع التحميل داخل البرنامج بنفس الفحوصات.
### 💾 النسخ الاحتياطي
@@ -354,12 +354,16 @@
### 📝 السجل و ℹ️ حول
- **السجل:** كل أمر ينفذه البرنامج وكل رد من fastboot و adb، مع نسخ ومسح.
-- **حول:**
- - الإصدار والحقوق والرخصة.
- - **تبديل اللغة:** العربية بواجهة كاملة من اليمين لليسار، الإنجليزية، الصينية، اليابانية، الكورية.
- - **المظهر:** داكن أو فاتح أو مثل ويندوز.
- - **التحديثات:** مرة باليوم (أو بزر «تحقق الحين») يشوف إذا فيه إصدار جديد ويعرض لك التغييرات، وما يحمّل إلا إذا وافقت. الملف ما ينحفظ إلا إذا طابقت بصمته SHA-256.
- - **الشرح والجولة والجديد:** كل صفحة فيها زر **؟** في زاويتها يشرحها، ومن «حول» تفتح جولة الترحيب مرة ثانية، والجديد في هالإصدار.
+- **حول:** الإصدار والحقوق والرخصة.
+- **الشرح والجولة والجديد:** كل صفحة فيها زر **؟** في زاويتها يشرحها، ومن «الإعدادات» تفتح جولة الترحيب مرة ثانية، والجديد في هالإصدار.
+
+### ⚙️ الإعدادات
+
+- **اللغة** (العربية بواجهة كاملة من اليمين لليسار، والإنجليزية، والصينية، واليابانية، والكورية)، و**المظهر** (داكن أو فاتح أو مثل ويندوز)، و**حجم الخط**، و**الخلفية الزجاجية** على Windows 11.
+- **الجوال:** إذا الجوال المتصل بـ ADB ينسأل عن الروت (مطفأ افتراضياً).
+- **الاختصارات:** Ctrl+O يفتح ملف في الصفحة، وCtrl+L السجل، وF1 مساعدة الصفحة، وCtrl+, الإعدادات.
+- **التحديثات:** مرة باليوم (أو بزر «تحقق الحين») يشوف إذا فيه إصدار جديد ويعرض لك التغييرات، وما يحمّل إلا إذا وافقت. الملف ما ينحفظ إلا إذا طابقت بصمته SHA-256.
+- **تعريفات USB:** تعريف قوقل (بكسل والجوالات اللي على معرّفات قوقل) وتعريف سامسونج، ينحمّلون وينفحصون ويتثبّتون بضغطة.
---
diff --git a/README.md b/README.md
index b2aef40..6036d2e 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,10 @@ nothing to install.
> 🆕 **A new version.** Fastboot Studio is the new generation of Fastboot Enhance: a new
> interface from top to bottom, new pages, and more protection for the phone.
>
+> **New in 3.0:** a new glass look (grey glass in dark, frosted in light, a new icon), the pages in
+> groups with a device bar above and a status bar below, one summary before a flash and the result on the
+> page, a log file per flash, a Stop for a hung command, and keyboard shortcuts.
+>
> **New in 2.9:**
> - **Samsung flashing** in Download mode, from the app: one image, a Magisk tar, or the whole firmware
> (BL, AP, CP, HOME_CSC). Every file is checked first (MD5, lz4, the phone's PIT and model); EFS and
@@ -55,9 +59,6 @@ nothing to install.
> - **Flash both slots**: firmware partitions such as modem and boot are written to slot a and b.
> - A partition fastbootd refuses (a OnePlus modem) is written from the bootloader after the rest.
>
-> 🔜 **Coming soon: Odin.** Flashing Samsung phones straight from Download mode, with the same
-> checks, so Samsung firmware goes from download to phone in one app.
->
> **New in 2.5:**
> - A **Phone** page for the phone in Android: specs, kernel, security and battery; with the
> Companion module, the bootloader's own AVB state, module conflicts and its backups.
@@ -97,9 +98,9 @@ nothing to install.
3. Run `FastbootStudio.exe`.
The build is self-contained: .NET, `adb` and `fastboot` (platform-tools 37.0.1) are
-included. You only need the phone's USB driver installed in Windows
-(e.g. the [Google USB Driver](https://developer.android.com/studio/run/win-usb)); for a Samsung,
-the app can download and install Samsung's own driver for you.
+included. You only need the phone's USB driver installed in Windows; the app can download and
+install [Google's driver](https://developer.android.com/studio/run/win-usb) (Pixels and phones on
+Google's USB ids) and Samsung's own driver for you, from Settings or the USB check.
An OTA or image can be opened straight away: `FastbootStudio.exe ota.zip`, or drop the
file onto the exe.
@@ -132,7 +133,7 @@ you first that it wipes the phone.
| Infinix, Tecno, itel and other MediaTek phones | ✅ On most models | Developer options → OEM unlocking, then `fastboot flashing unlock` (varies by model) | SP Flash Tool is only for reviving a phone in BROM mode |
| Nothing, Fairphone, ASUS, and phones close to stock Android | ✅ Usually | The standard command | |
| Oppo, Realme, vivo | ⚠️ Depends on the model | Many models cannot be unlocked at all | adb features work on all of them |
-| Samsung | ⚠️ No fastboot | OEM unlocking, then a long press on Volume up in Download mode | The **Samsung page** checks firmware, roots with Magisk and makes tars for Odin, and the app installs Samsung's driver. Flashing is in Odin for now; built-in flashing is coming |
+| Samsung | ⚠️ No fastboot | OEM unlocking, then a long press on Volume up in Download mode | The **Samsung page** checks firmware, roots with Magisk, makes tars for Odin and flashes from Download mode in the app; the app installs Samsung's driver |
| Huawei, Honor | ❌ For flashing | Unlock codes stopped in 2018 | adb features (Phone page, copying files) still work |
**Without unlocking**, these work on any phone, or on no phone at all:
@@ -338,7 +339,7 @@ HOME_CSC) for Odin. This page does everything around Odin, and nothing is writte
- **Tar for Odin**: any images (TWRP's recovery.img, a patched boot…) packed as a `.tar.md5`.
**Why it helps:** the wrong firmware, a bootloader downgrade or a wiped phone are caught before
-Odin is even open. **Coming soon:** flashing from Download mode, Odin built in.
+Odin is even open, and the firmware can be flashed from Download mode in the app, with the same checks.
### 💾 Backup
@@ -397,12 +398,20 @@ Type adb and fastboot commands and run them with the tools that come with the ap
### 📝 Logs and ℹ️ About
- **Logs**: everything the app runs and every fastboot / adb answer, to copy or clear.
-- **About**: version, credits, license, the **language switch** and the **appearance** (dark, light, or as Windows)
- (English, العربية with a full right-to-left layout, 中文, 日本語, 한국어).
+- **About**: version, credits and license.
+- **Help, tour and What's new**: every page has a **?** in its corner with its help; Settings opens the
+ welcome tour again, and What's new for this version.
+
+### ⚙️ Settings
+
+- **Language** (English, العربية with a full right-to-left layout, 中文, 日本語, 한국어), **appearance** (dark, light, or as
+ Windows), **text size**, and the **glass backdrop** on Windows 11.
+- **Phone**: whether a phone connected over ADB is asked for root (off by default).
+- **Shortcuts**: Ctrl+O opens a file on the page, Ctrl+L the log, F1 the page's help, Ctrl+, Settings.
- **Updates**: once a day (or with *Check now*) the app looks for a new release, shows what
changed, and downloads it only if you say so; the zip is kept only when its SHA-256 matches.
-- **Help, tour and What's new**: every page has a **?** in its corner with its help; About opens the
- welcome tour again, and What's new for this version.
+- **USB drivers**: Google's (Pixels and phones on Google's USB ids) and Samsung's, downloaded,
+ checked and installed in one click.
---
diff --git a/Rail.cs b/Rail.cs
new file mode 100644
index 0000000..f9049b9
--- /dev/null
+++ b/Rail.cs
@@ -0,0 +1,31 @@
+using System.Windows;
+
+namespace FastbootEnhance
+{
+ ///
+ /// Attached slots of the navigation rail (Themes/Styles.xaml, NavRail): the device bar
+ /// above the page, the status bar below it, and the pages at the foot of the rail
+ /// (Settings, About). They are set in MainWindow.xaml, outside the template, so their
+ /// parts can carry names the code reaches.
+ ///
+ public static class Rail
+ {
+ public static readonly DependencyProperty TopBarProperty = DependencyProperty.RegisterAttached(
+ "TopBar", typeof(object), typeof(Rail), new PropertyMetadata(null));
+
+ public static readonly DependencyProperty BottomBarProperty = DependencyProperty.RegisterAttached(
+ "BottomBar", typeof(object), typeof(Rail), new PropertyMetadata(null));
+
+ public static readonly DependencyProperty FootProperty = DependencyProperty.RegisterAttached(
+ "Foot", typeof(object), typeof(Rail), new PropertyMetadata(null));
+
+ public static object GetTopBar(DependencyObject element) => element.GetValue(TopBarProperty);
+ public static void SetTopBar(DependencyObject element, object value) => element.SetValue(TopBarProperty, value);
+
+ public static object GetBottomBar(DependencyObject element) => element.GetValue(BottomBarProperty);
+ public static void SetBottomBar(DependencyObject element, object value) => element.SetValue(BottomBarProperty, value);
+
+ public static object GetFoot(DependencyObject element) => element.GetValue(FootProperty);
+ public static void SetFoot(DependencyObject element, object value) => element.SetValue(FootProperty, value);
+ }
+}
diff --git a/RootUI.cs b/RootUI.cs
index 693c1b9..239b939 100644
--- a/RootUI.cs
+++ b/RootUI.cs
@@ -5,6 +5,7 @@
using System.Linq;
using System.Threading;
using System.Windows;
+using System.Windows.Controls;
using FastbootEnhance.Core.Adb;
using FastbootEnhance.Core.Fastboot;
using FastbootEnhance.Core.Images;
@@ -86,13 +87,39 @@ static void refresh()
W.root_boot_once.Visibility = partition == "boot" ? Visibility.Visible : Visibility.Collapsed;
W.root_boot_once.IsEnabled = !busy && patchedPath != null && partition == "boot";
W.root_open_folder.IsEnabled = folder != null;
+
+ // The current step is lit, the ones done carry a tick, the ones ahead are dimmed.
+ int current = patchedPath != null ? 4 : adbSerial != null ? 3 : stockPath != null ? 2 : 1;
+ paintStep(W.root_step1, W.root_step1_no, W.root_step1_num, W.root_step1_tick, W.root_step1_state, 1, current);
+ paintStep(W.root_step2, W.root_step2_no, W.root_step2_num, W.root_step2_tick, W.root_step2_state, 2, current);
+ paintStep(W.root_step3, W.root_step3_no, W.root_step3_num, W.root_step3_tick, W.root_step3_state, 3, current);
+ paintStep(W.root_step4, W.root_step4_no, W.root_step4_num, W.root_step4_tick, W.root_step4_state, 4, current);
+ }
+
+ static void paintStep(Border card, Border circle, TextBlock number, System.Windows.Shapes.Path tick, TextBlock state, int step, int current)
+ {
+ bool done = step < current, now = step == current;
+ card.Opacity = done || now ? 1 : 0.6;
+ card.BorderBrush = Palette.Get(now ? "AccentLine" : "GlassLine");
+ circle.Background = Palette.Get(done ? "OkSoft" : now ? "Accent" : "Glass2");
+ circle.BorderBrush = Palette.Get(done ? "OkLine" : now ? "Accent" : "GlassLine2");
+ number.Foreground = Palette.Get(now ? "AccentInk" : "Dim");
+ number.Visibility = done ? Visibility.Collapsed : Visibility.Visible;
+ tick.Visibility = done ? Visibility.Visible : Visibility.Collapsed;
+ state.Text = done ? Properties.Resources.root_step_done : now ? Properties.Resources.root_step_current : "";
+ state.Foreground = Palette.Get(done ? "Ok" : "Accent");
}
- /// Runs work in the background with the page locked, then done on the UI thread.
+ ///
+ /// Runs work in the background with the page locked, then done on the UI thread. When
+ /// the work throws, done is not run: the error is shown instead, so a failed step is
+ /// never reported as a finished one.
+ ///
static void run(Action work, Action done)
{
busy = true;
refresh();
+ Exception failure = null;
Helper.offloadAndRun(delegate
{
try
@@ -101,12 +128,16 @@ static void run(Action work, Action done)
}
catch (Exception e)
{
+ failure = e;
log("failed: " + e);
}
}, delegate
{
busy = false;
- done();
+ if (failure != null)
+ ThemedDialog.Show(failure.Message, Properties.Resources.error, MessageBoxButton.OK, MessageBoxImage.Error);
+ else
+ done();
refresh();
});
}
diff --git a/SamsungUI.cs b/SamsungUI.cs
index 4fed9fd..66786c9 100644
--- a/SamsungUI.cs
+++ b/SamsungUI.cs
@@ -7,6 +7,7 @@
using System.Linq;
using System.Threading;
using System.Windows;
+using System.Windows.Media;
using FastbootEnhance.Core.Adb;
using FastbootEnhance.Core.Fastboot;
using FastbootEnhance.Core.Samsung;
@@ -104,11 +105,13 @@ public static void init()
W.samsung_build_tar.Click += delegate { buildTar(); };
W.samsung_cancel.Click += delegate { cancel?.Cancel(); };
W.samsung_driver_install.Click += delegate { DriverUI.InstallSamsung(showDriver); };
- W.samsung_odin.Click += delegate
+ RoutedEventHandler odin = delegate
{
OdinWindow.Show(W);
showDriver();
};
+ W.samsung_odin.Click += odin;
+ W.samsung_odin_main.Click += odin;
showDriver();
}
@@ -316,6 +319,7 @@ static void show(FirmwareSet set, Dictionary> liste
if (set.Unknown.Count > 0)
info.Add(new InfoRow(Properties.Resources.samsung_info_other, string.Join(", ", set.Unknown.Select(Path.GetFileName))));
W.samsung_info.ItemsSource = info;
+ W.samsung_match_fw.Text = set.Model ?? (build?.Text ?? "—");
// Next to the firmware, in a folder named after its build.
outputFolder = Path.Combine(Path.GetDirectoryName(set.Files[0].Path), (build?.Text ?? "firmware") + "_files");
@@ -432,10 +436,12 @@ static void showMatch(string phoneProblem = null)
{
W.samsung_verdict.Visibility = Visibility.Collapsed;
W.samsung_phone_note.Text = phoneProblem ?? Properties.Resources.samsung_phone_none;
+ showMatchRow(null, null);
return;
}
MatchLevel overall = FirmwareMatch.Overall(findings);
string brush = overall == MatchLevel.Block ? "Danger" : overall == MatchLevel.Warn ? "Warn" : "Ok";
+ showMatchRow(phone.Model, brush);
W.samsung_verdict.Visibility = Visibility.Visible;
W.samsung_verdict.Background = Palette.Get(brush == "Ok" ? "AccentSoft" : brush + "Soft");
W.samsung_verdict.BorderBrush = Palette.Get(brush == "Ok" ? "AccentLine" : brush + "Line");
@@ -450,6 +456,28 @@ static void showMatch(string phoneProblem = null)
Helper.ltr(phone.Serial));
}
+ /// The row at the top: the firmware's model, a mark, the phone's model (or "not read yet").
+ static void showMatchRow(string phoneModel, string brush)
+ {
+ if (phoneModel == null)
+ {
+ W.samsung_match_phone.Text = Properties.Resources.samsung_match_unknown;
+ W.samsung_match_phone.Foreground = Palette.Get("Dim");
+ W.samsung_match_glyph.Data = Geometry.Parse("M6,12 H18");
+ W.samsung_match_glyph.Stroke = Palette.Get("Faint");
+ W.samsung_match_mark.Background = Palette.Get("Glass2");
+ W.samsung_match_mark.BorderBrush = Palette.Get("GlassLine2");
+ return;
+ }
+ W.samsung_match_phone.Text = phoneModel;
+ W.samsung_match_phone.Foreground = Palette.Get("Text");
+ W.samsung_match_glyph.Data = Geometry.Parse(brush == "Ok" ? "M5,12.5 L10,17.5 L19.5,7"
+ : brush == "Warn" ? "M12,4 V14 M12,18 V18.5" : "M7,7 L17,17 M17,7 L7,17");
+ W.samsung_match_glyph.Stroke = Palette.Get(brush);
+ W.samsung_match_mark.Background = Palette.Get(brush + "Soft");
+ W.samsung_match_mark.BorderBrush = Palette.Get(brush + "Line");
+ }
+
static void describe(MatchFinding f, out string title, out string detail)
{
string fw = Helper.ltr(f.Firmware ?? ""), ph = Helper.ltr(f.Phone ?? "");
diff --git a/Settings.cs b/Settings.cs
index 5528fef..5015638 100644
--- a/Settings.cs
+++ b/Settings.cs
@@ -11,8 +11,14 @@ namespace FastbootEnhance
///
static class Settings
{
- static readonly string FilePath = Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Fastboot Studio", "settings.json");
+ /// The app's folder under %APPDATA%: the settings and the flash logs.
+ public static readonly string Folder = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Fastboot Studio");
+
+ static readonly string FilePath = Path.Combine(Folder, "settings.json");
+
+ /// Set is read-modify-write from several threads (device facts, the UI): one at a time.
+ static readonly object gate = new object();
static Dictionary Load()
{
@@ -21,7 +27,10 @@ static Dictionary Load()
{
if (!File.Exists(FilePath))
return values;
- using (JsonDocument json = JsonDocument.Parse(File.ReadAllText(FilePath)))
+ string text;
+ lock (gate)
+ text = File.ReadAllText(FilePath);
+ using (JsonDocument json = JsonDocument.Parse(text))
{
if (json.RootElement.ValueKind != JsonValueKind.Object)
return values;
@@ -56,10 +65,16 @@ public static bool Set(string key, string value)
{
try
{
- Dictionary values = Load();
- values[key] = value;
- Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
- File.WriteAllText(FilePath, JsonSerializer.Serialize(values));
+ lock (gate)
+ {
+ Dictionary values = Load();
+ values[key] = value;
+ Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
+ // Written beside, then moved over: a crash mid-write leaves the old file, not a torn one.
+ string temp = FilePath + ".tmp";
+ File.WriteAllText(temp, JsonSerializer.Serialize(values));
+ File.Move(temp, FilePath, true);
+ }
return true;
}
catch (IOException)
diff --git a/TerminalUI.cs b/TerminalUI.cs
index 42e3f66..4ad64ac 100644
--- a/TerminalUI.cs
+++ b/TerminalUI.cs
@@ -66,7 +66,7 @@ public static void init()
FontSize = 12,
MinHeight = 30,
Padding = new Thickness(10, 2, 10, 2),
- Margin = new Thickness(0, 0, 8, 8),
+ Margin = new Thickness(0, 0, 8, 6),
Style = (Style)W.FindResource("GhostButton"),
};
// Fills the line rather than running it, so nothing happens by a stray click.
@@ -218,6 +218,8 @@ static bool confirm(TerminalCommand command)
return ThemedDialog.ConfirmTyped(Properties.Resources.terminal_dd, Properties.Resources.critical_title, "dd");
case TerminalRisk.WipesData:
return Helper.confirm(Properties.Resources.terminal_wipe, Properties.Resources.confirm_title, true);
+ case TerminalRisk.ChangesSlot:
+ return Helper.confirm(Properties.Resources.terminal_slot, Properties.Resources.confirm_title, false);
default:
return true;
}
diff --git a/ThemedDialog.xaml b/ThemedDialog.xaml
index 55220fb..8d05ff1 100644
--- a/ThemedDialog.xaml
+++ b/ThemedDialog.xaml
@@ -5,8 +5,8 @@
SizeToContent="WidthAndHeight" ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
Foreground="{StaticResource Text}" FontFamily="{StaticResource UiFont}" FontSize="13" UseLayoutRounding="True">
-
+
@@ -18,7 +18,7 @@
-
+
-
+
+
+
+
+
-
+
+
+
+
+
+
@@ -43,7 +52,7 @@
+ BorderBrush="{StaticResource Line}" BorderThickness="0,1,0,0" CornerRadius="0,0,15,15">
diff --git a/ThemedDialog.xaml.cs b/ThemedDialog.xaml.cs
index 592d595..9d7d0aa 100644
--- a/ThemedDialog.xaml.cs
+++ b/ThemedDialog.xaml.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
@@ -31,8 +32,15 @@ enum Kind
MessageBoxResult result;
+ /// One point of a : what will happen, and whether it can cost data or a phone.
+ public sealed class SummaryItem
+ {
+ public string Text { get; set; }
+ public bool Destructive { get; set; }
+ }
+
ThemedDialog(string text, string title, MessageBoxButton choice, Kind kind, MessageBoxResult defaultResult,
- string requiredWord = null)
+ string requiredWord = null, string mainLabel = null, string deviceLine = null, IList points = null)
{
InitializeComponent();
FlowDirection = Languages.Flow;
@@ -42,6 +50,21 @@ enum Kind
Title = heading.Text;
if (message.Text.Length == 0)
message.Visibility = Visibility.Collapsed;
+ if (!string.IsNullOrEmpty(deviceLine))
+ {
+ device_line.Text = deviceLine;
+ device_line.Visibility = Visibility.Visible;
+ }
+ bool needsAck = false;
+ if (points != null && points.Count > 0)
+ {
+ items.Visibility = Visibility.Visible;
+ foreach (SummaryItem point in points)
+ {
+ items.Children.Add(summaryRow(point));
+ needsAck |= point.Destructive;
+ }
+ }
string color = kind == Kind.Error ? "Danger" : kind == Kind.Warning ? "Warn" : kind == Kind.Done ? "Ok" : "Accent";
string soft = kind == Kind.Error ? "DangerSoft" : kind == Kind.Warning ? "WarnSoft" : "AccentSoft";
@@ -61,23 +84,34 @@ enum Kind
switch (choice)
{
case MessageBoxButton.YesNo:
- addButtons(defaultResult, MessageBoxResult.No, MessageBoxResult.No, risky,
+ addButtons(defaultResult, MessageBoxResult.No, MessageBoxResult.No, risky, mainLabel,
MessageBoxResult.No, MessageBoxResult.Yes);
break;
case MessageBoxButton.YesNoCancel:
- addButtons(defaultResult, MessageBoxResult.Yes, MessageBoxResult.Cancel, risky,
+ addButtons(defaultResult, MessageBoxResult.Yes, MessageBoxResult.Cancel, risky, mainLabel,
MessageBoxResult.Cancel, MessageBoxResult.No, MessageBoxResult.Yes);
break;
case MessageBoxButton.OKCancel:
- addButtons(defaultResult, MessageBoxResult.OK, MessageBoxResult.Cancel, risky,
+ addButtons(defaultResult, MessageBoxResult.OK, MessageBoxResult.Cancel, risky, mainLabel,
MessageBoxResult.Cancel, MessageBoxResult.OK);
break;
default:
- addButtons(defaultResult, MessageBoxResult.OK, MessageBoxResult.OK, false,
+ addButtons(defaultResult, MessageBoxResult.OK, MessageBoxResult.OK, false, mainLabel,
MessageBoxResult.OK);
break;
}
+ // A summary with a point that can cost data: the main button waits for "I have read this".
+ if (needsAck)
+ {
+ ack.Content = Properties.Resources.summary_ack;
+ ack.Visibility = Visibility.Visible;
+ Button main = buttons.Children.OfType
void addButtons(MessageBoxResult requestedDefault, MessageBoxResult fallbackDefault,
- MessageBoxResult cancelResult, bool risky, params MessageBoxResult[] order)
+ MessageBoxResult cancelResult, bool risky, string mainLabel, params MessageBoxResult[] order)
{
MessageBoxResult chosenDefault = order.Contains(requestedDefault) ? requestedDefault : fallbackDefault;
@@ -125,7 +159,7 @@ void addButtons(MessageBoxResult requestedDefault, MessageBoxResult fallbackDefa
Button button = new Button
{
- Content = label(value),
+ Content = main && mainLabel != null ? mainLabel : label(value),
MinWidth = 96,
Margin = new Thickness(i == 0 ? 0 : 10, 0, 0, 0),
IsDefault = value == chosenDefault,
@@ -143,6 +177,48 @@ void addButtons(MessageBoxResult requestedDefault, MessageBoxResult fallbackDefa
}
}
+ /// One point of a summary: a small glyph (amber for a destructive one) and the text.
+ UIElement summaryRow(SummaryItem point)
+ {
+ string color = point.Destructive ? "Warn" : "Accent";
+ Border row = new Border
+ {
+ Margin = new Thickness(0, 0, 0, 8),
+ Padding = new Thickness(12, 9, 12, 9),
+ CornerRadius = new CornerRadius(10),
+ BorderThickness = new Thickness(1),
+ Background = Palette.Get(point.Destructive ? "WarnSoft" : "Raised"),
+ BorderBrush = Palette.Get(point.Destructive ? "WarnLine" : "Line"),
+ };
+ DockPanel panel = new DockPanel();
+ System.Windows.Shapes.Path mark = new System.Windows.Shapes.Path
+ {
+ Width = 15,
+ Height = 15,
+ Stretch = Stretch.Uniform,
+ StrokeThickness = 2,
+ StrokeStartLineCap = PenLineCap.Round,
+ StrokeEndLineCap = PenLineCap.Round,
+ StrokeLineJoin = PenLineJoin.Round,
+ Stroke = Palette.Get(color),
+ Data = Geometry.Parse(point.Destructive ? GlyphWarning : GlyphInfo),
+ VerticalAlignment = VerticalAlignment.Top,
+ Margin = new Thickness(0, 2, 10, 0),
+ FlowDirection = FlowDirection.LeftToRight,
+ };
+ DockPanel.SetDock(mark, Dock.Left);
+ panel.Children.Add(mark);
+ panel.Children.Add(new TextBlock
+ {
+ Text = point.Text,
+ TextWrapping = TextWrapping.Wrap,
+ FontSize = 12.5,
+ LineHeight = 18,
+ });
+ row.Child = panel;
+ return row;
+ }
+
void onKey(object sender, KeyEventArgs e)
{
// Ctrl+C copies the message, as a Windows message box does; handy for error reports.
@@ -230,8 +306,21 @@ public static void Done(string text)
show(text, null, MessageBoxButton.OK, Kind.Done, MessageBoxResult.None);
}
+ ///
+ /// One question before a flash instead of several: what is written and to which phone
+ /// (), then every point worth knowing. When a point can cost
+ /// data, the main button waits for the "I have read this" box. True to go ahead.
+ ///
+ public static bool Summary(string title, string text, string deviceLine, IList points, string goLabel)
+ {
+ bool destructive = points != null && points.Any(p => p.Destructive);
+ return show(text, title, MessageBoxButton.OKCancel, destructive ? Kind.Warning : Kind.Question,
+ MessageBoxResult.Cancel, null, goLabel, deviceLine, points) == MessageBoxResult.OK;
+ }
+
static MessageBoxResult show(string text, string title, MessageBoxButton choice, Kind kind,
- MessageBoxResult defaultResult, string requiredWord = null)
+ MessageBoxResult defaultResult, string requiredWord = null, string mainLabel = null, string deviceLine = null,
+ IList points = null)
{
Application app = Application.Current;
if (app == null)
@@ -239,9 +328,9 @@ static MessageBoxResult show(string text, string title, MessageBoxButton choice,
// Like MessageBox, callable from any thread; the window itself lives on the UI thread.
if (!app.Dispatcher.CheckAccess())
- return app.Dispatcher.Invoke(() => show(text, title, choice, kind, defaultResult, requiredWord));
+ return app.Dispatcher.Invoke(() => show(text, title, choice, kind, defaultResult, requiredWord, mainLabel, deviceLine, points));
- ThemedDialog dialog = new ThemedDialog(text, title, choice, kind, defaultResult, requiredWord);
+ ThemedDialog dialog = new ThemedDialog(text, title, choice, kind, defaultResult, requiredWord, mainLabel, deviceLine, points);
Window owner = app.Windows.OfType()
.FirstOrDefault(window => window != dialog && window.IsActive && window.IsVisible)
?? (MainWindow.THIS != null && MainWindow.THIS.IsVisible ? MainWindow.THIS : null);
diff --git a/Themes/Palette.Dark.xaml b/Themes/Palette.Dark.xaml
index 2560799..549c701 100644
--- a/Themes/Palette.Dark.xaml
+++ b/Themes/Palette.Dark.xaml
@@ -2,42 +2,61 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:props="clr-namespace:FastbootEnhance.Properties">
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
diff --git a/Themes/Palette.Light.xaml b/Themes/Palette.Light.xaml
index dc68e79..8e350df 100644
--- a/Themes/Palette.Light.xaml
+++ b/Themes/Palette.Light.xaml
@@ -2,39 +2,54 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:props="clr-namespace:FastbootEnhance.Properties">
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
diff --git a/Themes/Styles.xaml b/Themes/Styles.xaml
index 224a267..fae0ca1 100644
--- a/Themes/Styles.xaml
+++ b/Themes/Styles.xaml
@@ -1,6 +1,7 @@
+ xmlns:props="clr-namespace:FastbootEnhance.Properties"
+ xmlns:local="clr-namespace:FastbootEnhance">
@@ -81,11 +82,13 @@
+
@@ -103,29 +106,30 @@
+
+
+
@@ -198,9 +230,9 @@
-
+
-
+
@@ -234,7 +266,7 @@
-
@@ -254,8 +286,8 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+