mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 11:01:07 +00:00
60 lines
2.5 KiB
Python
Executable File
60 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Extract only pinned Windows GDK modules; Linux Wine stays ARM64."""
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import shutil
|
|
import sys
|
|
import tarfile
|
|
import urllib.request
|
|
|
|
recipe = Path(__file__).resolve().parent
|
|
lock = json.loads((recipe / 'runtime.lock.json').read_text())
|
|
cache = Path(sys.argv[1]); output = Path(sys.argv[2])
|
|
cache.mkdir(parents=True, exist_ok=True)
|
|
output.mkdir(parents=True, exist_ok=True)
|
|
url = 'https://github.com/' + lock['repository'] + '/releases/download/' + lock['tag'] + '/'
|
|
|
|
def download(name, expected, algorithm):
|
|
target = cache / name
|
|
def matches():
|
|
if not target.is_file():
|
|
return False
|
|
digest = hashlib.new(algorithm)
|
|
with target.open('rb') as file:
|
|
for block in iter(lambda: file.read(1024 * 1024), b''):
|
|
digest.update(block)
|
|
return digest.hexdigest() == expected
|
|
if not matches():
|
|
part = target.with_suffix(target.suffix + '.part')
|
|
with urllib.request.urlopen(url + name, timeout=90) as response, part.open('wb') as file:
|
|
shutil.copyfileobj(response, file)
|
|
part.replace(target)
|
|
if not matches():
|
|
raise RuntimeError('Xbox runtime checksum mismatch: ' + name)
|
|
return target
|
|
|
|
archive = download(lock['archive'], lock['sha512'], 'sha512')
|
|
# Keep corresponding source available beside the build cache for redistribution.
|
|
source = lock['source']
|
|
download(source['name'], source['sha256'], 'sha256')
|
|
remaining = set(lock['dlls'])
|
|
with tarfile.open(archive) as tar:
|
|
for member in tar:
|
|
name = Path(member.name).name
|
|
if '/files/lib/wine/x86_64-windows/' not in member.name or name not in remaining:
|
|
continue
|
|
if not member.isfile() or member.size > 32 * 1024 * 1024:
|
|
raise RuntimeError('Invalid Xbox Windows runtime module')
|
|
data = tar.extractfile(member).read()
|
|
if hashlib.sha256(data).hexdigest() != lock['dlls'][name] or data[:2] != b'MZ':
|
|
raise RuntimeError('Xbox Windows runtime module checksum mismatch')
|
|
# Wine rejects builtin-tagged PE files when WINEDLLOVERRIDES selects native.
|
|
# These standalone Windows modules must use the native x64 loader on ARM64EC.
|
|
if data[64:80] == b'Wine builtin DLL':
|
|
data = data[:64] + b'DroidDeck native' + data[80:]
|
|
(output / name).write_bytes(data)
|
|
remaining.remove(name)
|
|
if remaining:
|
|
raise RuntimeError('Missing Xbox runtime modules')
|