Skip to content

Commit 6d22219

Browse files
committed
fix: Add nullability checks and fix TcpTransport ctor
Refactor TcpTransport to a normal class with a constructor for host/port, make TcpClient readonly and NetworkStream nullable, and call InitializeProtocol from the ctor. Add null-check guards that throw InvalidOperationException if the stream isn't initialized. Improve handshake parsing by extracting the version substring to a variable for clearer errors. Add null-forgiving operators where required when reading/setting image paths and update Win32 DeviceIoControl signature to accept nullable in/out buffers. Overall this tightens nullability handling and small protocol/initialization fixes.
1 parent 6fc19d5 commit 6d22219

5 files changed

Lines changed: 116 additions & 12 deletions

File tree

FirmwareKit.Comm.Fastboot/SuperFlashHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ private static SuperImageBuilder InitializeBuilder(FastbootUtil fastboot, string
1818
try
1919
{
2020
var metadataReader = new MetadataReader();
21-
var metadata = metadataReader.ReadFromImageFile(emptyImagePath);
21+
var metadata = metadataReader.ReadFromImageFile(emptyImagePath!);
2222
var builder = MetadataBuilder.FromMetadata(metadata);
2323
return new SuperImageBuilder(builder);
2424
}

FirmwareKit.Comm.Fastboot/SuperImageBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void UpdatePartitionImage(string name, ulong size, string? imagePath = nu
3939

4040
if (!string.IsNullOrEmpty(imagePath))
4141
{
42-
_partitionImages[name] = imagePath;
42+
_partitionImages[name] = imagePath!;
4343
}
4444
}
4545

FirmwareKit.Comm.Fastboot/TcpTransport.cs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,25 @@
44

55
namespace FirmwareKit.Comm.Fastboot;
66

7-
public class TcpTransport(string host, int port = 5554) : IFastbootTransport
7+
public class TcpTransport : IFastbootTransport
88
{
9-
private TcpClient _client = new();
10-
private NetworkStream _stream;
9+
private readonly TcpClient _client = new();
10+
private NetworkStream? _stream;
1111
private long _messageBytesLeft = 0;
1212

13-
public string Host { get; } = host;
14-
public int Port { get; } = port;
13+
public string Host { get; }
14+
public int Port { get; }
15+
16+
public TcpTransport(string host, int port = 5554)
17+
{
18+
Host = host;
19+
Port = port;
20+
InitializeProtocol();
21+
}
1522

1623
private void InitializeProtocol()
1724
{
18-
_client.Connect(host, port);
25+
_client.Connect(Host, Port);
1926
_stream = _client.GetStream();
2027
byte[] handshake = Encoding.ASCII.GetBytes("FB01");
2128
_stream.Write(handshake, 0, handshake.Length);
@@ -33,14 +40,16 @@ private void InitializeProtocol()
3340
throw new Exception("Handshake failed: unrecognized initialization message.");
3441
}
3542

36-
if (!int.TryParse(responseText.Substring(2, 2), out int version) || version < 1)
43+
string versionStr = responseText.Substring(2, 2);
44+
if (!int.TryParse(versionStr, out int version) || version < 1)
3745
{
38-
throw new Exception($"Handshake failed: unknown TCP protocol version {responseText.Substring(2, 2)} (host version 01).");
46+
throw new Exception($"Handshake failed: unknown TCP protocol version {versionStr} (host version 01).");
3947
}
4048
}
4149

4250
private int ReadFully(byte[] buffer, int offset, int length)
4351
{
52+
if (_stream == null) throw new InvalidOperationException("Stream not initialized");
4453
int totalRead = 0;
4554
while (totalRead < length)
4655
{
@@ -76,6 +85,7 @@ public byte[] Read(int length)
7685

7786
public long Write(byte[] data, int length)
7887
{
88+
if (_stream == null) throw new InvalidOperationException("Stream not initialized");
7989
byte[] header = new byte[8];
8090
BinaryPrimitives.WriteInt64BigEndian(header, length);
8191

FirmwareKit.Comm.Fastboot/Usb/Windows/Win32API.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ public static extern IntPtr CreateFileW([MarshalAs(UnmanagedType.LPWStr)] string
2929

3030
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
3131
public static extern bool DeviceIoControl(IntPtr device, uint code,
32-
byte[] inBuffer, int inBufferSize,
33-
byte[] outBuffer, int outBufferSize,
32+
byte[]? inBuffer, int inBufferSize,
33+
byte[]? outBuffer, int outBufferSize,
3434
out int bytesReturned, IntPtr overlapped);
3535

3636
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]

test_fastboot.bat

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
@echo off
2+
setlocal enabledelayedexpansion
3+
4+
:: 设置可执行文件路径
5+
set FASTBOOT_EXE=.\FastbootCLI\bin\Release\net10.0\win-x86\publish\fastboot.exe
6+
7+
:: 检查文件是否存在
8+
if not exist "%FASTBOOT_EXE%" (
9+
echo [ERROR] Fastboot executable not found at %FASTBOOT_EXE%
10+
echo Please run 'dotnet publish FastbootCLI\FastbootCLI.csproj -c Release -r win-x86' first.
11+
exit /b 1
12+
)
13+
14+
echo ============================================================
15+
echo Fastboot CLI Read-Only Command Test Script
16+
echo ============================================================
17+
echo.
18+
19+
:: 1. 测试 devices 命令
20+
echo [TEST] Testing 'devices' command...
21+
"%FASTBOOT_EXE%" devices
22+
if %ERRORLEVEL% neq 0 (
23+
echo [FAIL] 'devices' command failed.
24+
exit /b 1
25+
)
26+
echo [PASS] 'devices' command executed.
27+
echo.
28+
29+
:: 获取第一个设备的序列号(可选测试)
30+
:: 这里我们假设后续命令会自动选择唯一连接的设备
31+
32+
:: 2. 测试 getvar all
33+
echo [TEST] Testing 'getvar all'...
34+
"%FASTBOOT_EXE%" getvar all --debug
35+
if %ERRORLEVEL% neq 0 (
36+
echo [FAIL] 'getvar all' command failed.
37+
exit /b 1
38+
)
39+
echo [PASS] 'getvar all' command executed.
40+
echo.
41+
42+
:: 3. 测试 getvar 特定变量 (如 product, version)
43+
echo [TEST] Testing 'getvar product'...
44+
"%FASTBOOT_EXE%" getvar product
45+
if %ERRORLEVEL% neq 0 (
46+
echo [FAIL] 'getvar product' command failed.
47+
) else (
48+
echo [PASS] 'getvar product' command executed.
49+
)
50+
echo.
51+
52+
echo [TEST] Testing 'getvar version-bootloader'...
53+
"%FASTBOOT_EXE%" getvar version-bootloader
54+
if %ERRORLEVEL% neq 0 (
55+
echo [FAIL] 'getvar version-bootloader' command failed.
56+
) else (
57+
echo [PASS] 'getvar version-bootloader' command executed.
58+
)
59+
echo.
60+
61+
echo [TEST] Testing 'getvar has-slot:boot'...
62+
"%FASTBOOT_EXE%" getvar has-slot:boot
63+
if %ERRORLEVEL% neq 0 (
64+
echo [FAIL] 'getvar has-slot:boot' command failed.
65+
) else (
66+
echo [PASS] 'getvar has-slot:boot' command executed.
67+
)
68+
echo.
69+
70+
:: 4. 测试未实现或无效命令的优雅报错
71+
echo [TEST] Testing invalid command handling...
72+
"%FASTBOOT_EXE%" invalid_command_test
73+
if %ERRORLEVEL% equ 0 (
74+
echo [FAIL] Tool should have failed for invalid command.
75+
) else (
76+
echo [PASS] Tool correctly reported error for invalid command.
77+
)
78+
echo.
79+
80+
:: 5. 最后执行重启命令 (非写入性但具有破坏性的流程性指令)
81+
echo [TEST] Finalizing with 'reboot bootloader'...
82+
echo [INFO] Device will reboot now if connected.
83+
"%FASTBOOT_EXE%" reboot bootloader --debug
84+
if %ERRORLEVEL% neq 0 (
85+
echo [FAIL] 'reboot bootloader' command failed.
86+
exit /b 1
87+
)
88+
echo [PASS] 'reboot bootloader' command sent successfully.
89+
echo.
90+
91+
echo ============================================================
92+
echo All read-only tests completed successfully.
93+
echo ============================================================
94+
pause

0 commit comments

Comments
 (0)