Skip to content

Instantly share code, notes, and snippets.

@ids1024
Created August 21, 2020 20:14
Show Gist options
  • Save ids1024/facefabfb5b6c2987c6c83660c662447 to your computer and use it in GitHub Desktop.
Save ids1024/facefabfb5b6c2987c6c83660c662447 to your computer and use it in GitHub Desktop.
Create Windows Bootable USB from ISO using UDisks Dbus API
import dbus
import shutil
import sys
# TODO: Timeouts
# {'options': 'sync'}
bus = dbus.SystemBus()
iso = sys.argv[1]
drive = sys.argv[2]
EMPTY_OPTS = dbus.Dictionary(signature = "sv")
# Loopback mount the .iso
manager_obj = bus.get_object("org.freedesktop.UDisks2", "/org/freedesktop/UDisks2/Manager")
manager = dbus.Interface(manager_obj, "org.freedesktop.UDisks2.Manager")
with open(iso, 'rb') as f:
path = manager.LoopSetup(f.raw.fileno(), {})
loop_obj = bus.get_object("org.freedesktop.UDisks2", path)
loop_filesystem = dbus.Interface(loop_obj, "org.freedesktop.UDisks2.Filesystem")
try:
loop_filesystem.Mount({})
except dbus.exceptions.DBusException as e:
if e.get_dbus_name() != "org.freedesktop.UDisks2.Error.AlreadyMounted":
raise e
properties = dbus.Interface(loop_obj, 'org.freedesktop.DBus.Properties')
mount_points = properties.Get("org.freedesktop.UDisks2.Filesystem", "MountPoints")
iso_mount_path = bytes(mount_points[0])[:-1]
# Remove loop device when unmounted
loop = dbus.Interface(loop_obj, "org.freedesktop.UDisks2.Loop")
loop.SetAutoclear(True, {})
# Unmount any partitions
udisks_obj = bus.get_object("org.freedesktop.UDisks2", "/org/freedesktop/UDisks2")
obj_manager = dbus.Interface(udisks_obj, "org.freedesktop.DBus.ObjectManager")
for k in obj_manager.GetManagedObjects():
if k.startswith("/org/freedesktop/UDisks2/block_devices/" + drive) and not k.endswith(drive):
obj = bus.get_object("org.freedesktop.UDisks2", k)
try:
filesystem = dbus.Interface(obj, "org.freedesktop.UDisks2.Filesystem")
filesystem.Unmount({"force": True})
except dbus.exceptions.DBusException as e:
if e.get_dbus_name() == "org.freedesktop.DBus.Error.UnknownMethod":
pass
elif e.get_dbus_name() == "org.freedesktop.UDisks2.Error.NotMounted":
pass
else:
raise e
# Create dos partition table
drive_obj = bus.get_object("org.freedesktop.UDisks2", "/org/freedesktop/UDisks2/block_devices/" + drive)
block = dbus.Interface(drive_obj, "org.freedesktop.UDisks2.Block")
block.Format("gpt", {})
partition_table = dbus.Interface(drive_obj, "org.freedesktop.UDisks2.PartitionTable")
offset = 1024 ** 2
# UEFI system partition
partition = partition_table.CreatePartitionAndFormat(offset, 1024 ** 3, "0xef", "", {}, "vfat", {}, timeout=30*60)
part_obj = bus.get_object("org.freedesktop.UDisks2", partition)
fat_filesystem = dbus.Interface(part_obj, "org.freedesktop.UDisks2.Filesystem")
fat_path = fat_filesystem.Mount({})
offset += 1024**3
# Ntfs partition
partition = partition_table.CreatePartitionAndFormat(offset, 0, "0xb", "", {}, "ntfs", {}, timeout=30*60)
part_obj = bus.get_object("org.freedesktop.UDisks2", partition)
ntfs_filesystem = dbus.Interface(part_obj, "org.freedesktop.UDisks2.Filesystem")
ntfs_path = ntfs_filesystem.Mount({})
# Copy the files
def f(src, files):
if src.endswith(b'/sources'):
return [i for i in files if i != b'boot.wim']
return []
shutil.copytree(iso_mount_path, fat_path.encode('utf-8'), ignore=f, dirs_exist_ok=True)
shutil.copytree(iso_mount_path + b'/sources', (ntfs_path + '/sources').encode('utf-8'))
# Unmount filesystems
loop_filesystem.Unmount({})
#ntfs_filesystem.Unmount({}, timeout=30*60)
#fat_filesystem.Unmount({}, timeout=30*60)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment