mirror of
https://github.com/AeThex-Corporation/AeThex-OS.git
synced 2026-04-18 06:17:21 +00:00
- ModuleManager: Central tracking for installed marketplace modules - DataAnalyzerWidget: Real-time CPU/RAM/Battery/Storage widget (unlocked by Data Analyzer module) - BottomNavBar: Navigation bar for Projects/Chat/Marketplace/Settings - RootShell: Real root command execution utility - TerminalActivity: Full root shell with neofetch, sysinfo, real Linux commands - Terminal Pro module: Adds aliases (ll, la, h), command history - ArcadeActivity + SnakeGame: Pixel Arcade module unlocks retro games - fade_in/fade_out animations for smooth transitions
210 lines
7.2 KiB
Python
210 lines
7.2 KiB
Python
"""
|
|
Direct USB fastboot flash using PyUSB
|
|
Bypasses fastboot.exe which can't find MediaTek devices
|
|
"""
|
|
import os
|
|
import sys
|
|
import struct
|
|
import time
|
|
|
|
# Set libusb DLL path before importing pyusb
|
|
os.environ['PATH'] = r'C:\Users\PCOEM\AppData\Local\Programs\Python\Python312\Lib\site-packages\libusb\_platform\windows\x86_64' + os.pathsep + os.environ.get('PATH', '')
|
|
|
|
import usb.core
|
|
import usb.util
|
|
import usb.backend.libusb1 as libusb1
|
|
|
|
# Find the backend explicitly
|
|
backend = libusb1.get_backend(find_library=lambda x: r'C:\Users\PCOEM\AppData\Local\Programs\Python\Python312\Lib\site-packages\libusb\_platform\windows\x86_64\libusb-1.0.dll')
|
|
|
|
# MediaTek Fastboot
|
|
VID = 0x0E8D
|
|
PID = 0x201C
|
|
|
|
BOOT_IMG = r"C:\Users\PCOEM\AeThexOS\magisk_patched_boot.img"
|
|
|
|
def find_device():
|
|
"""Find the MediaTek device"""
|
|
print(f"Looking for USB device VID={VID:04X} PID={PID:04X}...")
|
|
dev = usb.core.find(idVendor=VID, idProduct=PID, backend=backend)
|
|
if dev is None:
|
|
print("Device not found!")
|
|
# List all USB devices
|
|
print("\nAll USB devices:")
|
|
for d in usb.core.find(find_all=True, backend=backend):
|
|
print(f" VID={d.idVendor:04X} PID={d.idProduct:04X} - {d.manufacturer or '?'} {d.product or '?'}")
|
|
return None
|
|
print(f"Found: {dev.manufacturer or '?'} {dev.product or '?'}")
|
|
return dev
|
|
|
|
def fastboot_command(dev, ep_out, ep_in, cmd):
|
|
"""Send a fastboot command and get response"""
|
|
print(f" >> {cmd}")
|
|
dev.write(ep_out, cmd.encode('utf-8'))
|
|
|
|
responses = []
|
|
while True:
|
|
try:
|
|
data = dev.read(ep_in, 64, timeout=5000)
|
|
resp = bytes(data).decode('utf-8', errors='replace')
|
|
print(f" << {resp}")
|
|
|
|
if resp.startswith('OKAY'):
|
|
return ('OKAY', resp[4:])
|
|
elif resp.startswith('FAIL'):
|
|
return ('FAIL', resp[4:])
|
|
elif resp.startswith('DATA'):
|
|
size = int(resp[4:], 16)
|
|
return ('DATA', size)
|
|
elif resp.startswith('INFO'):
|
|
responses.append(resp[4:])
|
|
continue
|
|
else:
|
|
return ('UNKNOWN', resp)
|
|
except usb.core.USBError as e:
|
|
if e.errno == 110: # timeout
|
|
return ('TIMEOUT', '')
|
|
raise
|
|
|
|
def fastboot_flash(dev, ep_out, ep_in, partition, img_path):
|
|
"""Flash an image to a partition"""
|
|
img_size = os.path.getsize(img_path)
|
|
print(f"\nFlashing {partition} ({img_size} bytes)...")
|
|
|
|
# Step 1: Get max download size
|
|
status, val = fastboot_command(dev, ep_out, ep_in, "getvar:max-download-size")
|
|
if status == 'OKAY':
|
|
max_size = int(val, 16)
|
|
print(f" Max download size: {max_size}")
|
|
else:
|
|
max_size = img_size # assume it fits
|
|
|
|
# Step 2: Download command
|
|
status, val = fastboot_command(dev, ep_out, ep_in, f"download:{img_size:08x}")
|
|
if status != 'DATA':
|
|
print(f" Download command failed: {status} {val}")
|
|
return False
|
|
|
|
# Step 3: Send image data in chunks
|
|
CHUNK_SIZE = 512 * 1024 # 512KB chunks
|
|
sent = 0
|
|
with open(img_path, 'rb') as f:
|
|
while sent < img_size:
|
|
chunk = f.read(CHUNK_SIZE)
|
|
if not chunk:
|
|
break
|
|
dev.write(ep_out, chunk, timeout=30000)
|
|
sent += len(chunk)
|
|
pct = sent * 100 // img_size
|
|
print(f"\r Sending: {pct}% ({sent}/{img_size})", end='', flush=True)
|
|
print()
|
|
|
|
# Step 4: Wait for OKAY after data transfer
|
|
status, val = fastboot_command(dev, ep_out, ep_in, "")
|
|
# Actually, the device should respond OKAY after receiving all data
|
|
try:
|
|
data = dev.read(ep_in, 64, timeout=10000)
|
|
resp = bytes(data).decode('utf-8', errors='replace')
|
|
print(f" << {resp}")
|
|
if not resp.startswith('OKAY'):
|
|
print(f" Data transfer response: {resp}")
|
|
except:
|
|
pass
|
|
|
|
# Step 5: Flash command
|
|
status, val = fastboot_command(dev, ep_out, ep_in, f"flash:{partition}")
|
|
if status == 'OKAY':
|
|
print(f" Flash {partition} SUCCESS!")
|
|
return True
|
|
else:
|
|
print(f" Flash failed: {status} {val}")
|
|
return False
|
|
|
|
def main():
|
|
print("=== Direct USB Fastboot Flash ===")
|
|
print()
|
|
|
|
if not os.path.exists(BOOT_IMG):
|
|
print(f"ERROR: {BOOT_IMG} not found")
|
|
return 1
|
|
|
|
dev = find_device()
|
|
if dev is None:
|
|
return 1
|
|
|
|
# Print device config
|
|
print(f"\nDevice configuration:")
|
|
for cfg in dev:
|
|
print(f" Config {cfg.bConfigurationValue}: {cfg.bNumInterfaces} interface(s)")
|
|
for intf in cfg:
|
|
print(f" Interface {intf.bInterfaceNumber}: Class={intf.bInterfaceClass:02X} SubClass={intf.bInterfaceSubClass:02X} Protocol={intf.bInterfaceProtocol:02X}")
|
|
for ep in intf:
|
|
direction = "IN" if usb.util.endpoint_direction(ep.bEndpointAddress) == usb.util.ENDPOINT_IN else "OUT"
|
|
print(f" EP {ep.bEndpointAddress:02X} ({direction}): MaxPacket={ep.wMaxPacketSize}")
|
|
|
|
# Claim the interface
|
|
try:
|
|
if dev.is_kernel_driver_active(0):
|
|
dev.detach_kernel_driver(0)
|
|
except:
|
|
pass
|
|
|
|
# Set configuration
|
|
try:
|
|
dev.set_configuration()
|
|
except usb.core.USBError:
|
|
pass
|
|
|
|
# Get the interface
|
|
cfg = dev.get_active_configuration()
|
|
intf = cfg[(0, 0)]
|
|
|
|
# Find endpoints
|
|
ep_out = usb.util.find_descriptor(intf, custom_match=lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT)
|
|
ep_in = usb.util.find_descriptor(intf, custom_match=lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN)
|
|
|
|
if ep_out is None or ep_in is None:
|
|
print("ERROR: Could not find USB endpoints")
|
|
return 1
|
|
|
|
print(f"\nEndpoints: OUT={ep_out.bEndpointAddress:02X} IN={ep_in.bEndpointAddress:02X}")
|
|
|
|
# Test connection with getvar
|
|
print("\nTesting fastboot protocol...")
|
|
status, val = fastboot_command(dev, ep_out, ep_in, "getvar:product")
|
|
if status == 'TIMEOUT':
|
|
print("No response - device may not support fastboot protocol on this interface")
|
|
print("Trying ADB protocol instead...")
|
|
# Try ADB handshake
|
|
ADB_CNXN = b'CNXN'
|
|
ADB_VERSION = 0x01000001
|
|
ADB_MAXDATA = 256 * 1024
|
|
msg = struct.pack('<4sIII', ADB_CNXN, ADB_VERSION, ADB_MAXDATA, len(b'host::\0'))
|
|
# ... this would be complex, skip for now
|
|
return 1
|
|
|
|
print(f"\nProduct: {val}")
|
|
|
|
# Get more info
|
|
for var in ['serialno', 'product', 'secure', 'unlocked', 'slot-count', 'current-slot']:
|
|
status, val = fastboot_command(dev, ep_out, ep_in, f"getvar:{var}")
|
|
|
|
# Flash boot_b
|
|
success = fastboot_flash(dev, ep_out, ep_in, "boot_b", BOOT_IMG)
|
|
|
|
if success:
|
|
print("\n=== Rebooting ===")
|
|
fastboot_command(dev, ep_out, ep_in, "reboot")
|
|
print("\nDone! Magisk root should be active after boot.")
|
|
else:
|
|
# Try just "boot" without slot suffix
|
|
print("\nRetrying with partition name 'boot'...")
|
|
success = fastboot_flash(dev, ep_out, ep_in, "boot", BOOT_IMG)
|
|
if success:
|
|
print("\n=== Rebooting ===")
|
|
fastboot_command(dev, ep_out, ep_in, "reboot")
|
|
|
|
return 0 if success else 1
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|