226 lines
6.7 KiB
Python
226 lines
6.7 KiB
Python
# Wizard Kit PE: Functions - Windows Setup
|
|
|
|
from functions.data import *
|
|
from functions.disk import *
|
|
|
|
# STATIC VARIABLES
|
|
WINDOWS_VERSIONS = [
|
|
{'Name': 'Windows 7 Home Basic',
|
|
'Image File': 'Win7',
|
|
'Image Name': 'Windows 7 HOMEBASIC'},
|
|
{'Name': 'Windows 7 Home Premium',
|
|
'Image File': 'Win7',
|
|
'Image Name': 'Windows 7 HOMEPREMIUM'},
|
|
{'Name': 'Windows 7 Professional',
|
|
'Image File': 'Win7',
|
|
'Image Name': 'Windows 7 PROFESSIONAL'},
|
|
{'Name': 'Windows 7 Ultimate',
|
|
'Image File': 'Win7',
|
|
'Image Name': 'Windows 7 ULTIMATE'},
|
|
|
|
{'Name': 'Windows 8.1',
|
|
'Image File': 'Win8',
|
|
'Image Name': 'Windows 8.1',
|
|
'CRLF': True},
|
|
{'Name': 'Windows 8.1 Pro',
|
|
'Image File': 'Win8',
|
|
'Image Name': 'Windows 8.1 Pro'},
|
|
|
|
{'Name': 'Windows 10 Home',
|
|
'Image File': 'Win10',
|
|
'Image Name': 'Windows 10 Home',
|
|
'CRLF': True},
|
|
{'Name': 'Windows 10 Pro',
|
|
'Image File': 'Win10',
|
|
'Image Name': 'Windows 10 Pro'},
|
|
]
|
|
|
|
def find_windows_image(windows_version):
|
|
"""Search for a Windows source image file, returns dict.
|
|
|
|
Searches on local disks and then the WINDOWS_SERVER share."""
|
|
image = {}
|
|
imagefile = windows_version['Image File']
|
|
imagename = windows_version['Image Name']
|
|
|
|
# Search local source
|
|
for d in psutil.disk_partitions():
|
|
for ext in ['esd', 'wim', 'swm']:
|
|
path = '{}images\{}.{}'.format(d.mountpoint, imagefile, ext)
|
|
if os.path.isfile(path) and wim_contains_image(path, imagename):
|
|
image['Path'] = path
|
|
image['Source'] = letter
|
|
if ext == 'swm':
|
|
image['Glob'] = '--ref="{}*.swm"'.format(image['Path'][:-4])
|
|
break
|
|
|
|
# Check for network source
|
|
if not image:
|
|
mount_windows_share()
|
|
if WINDOWS_SERVER['Mounted']:
|
|
for ext in ['esd', 'wim', 'swm']:
|
|
path = r'\\{}\{}\images\{}.{}'.format(
|
|
WINDOWS_SERVER['IP'],
|
|
WINDOWS_SERVER['Share'],
|
|
imagefile,
|
|
ext)
|
|
if os.path.isfile(path) and wim_contains_image(path, imagename):
|
|
image['Path'] = path
|
|
image['Source'] = None
|
|
if ext == 'swm':
|
|
image['Glob'] = '--ref="{}*.swm"'.format(
|
|
image['Path'][:-4])
|
|
break
|
|
|
|
# Display image to be used (if any) and return
|
|
if image:
|
|
print_info('Using image: {}'.format(image['Path']))
|
|
return image
|
|
else:
|
|
print_error('Failed to find Windows source image for {}'.format(
|
|
windows_version['Name']))
|
|
raise GenericAbort
|
|
|
|
def format_disk(disk, use_gpt):
|
|
"""Format disk for use as a Windows OS disk."""
|
|
if use_gpt:
|
|
format_gpt(disk)
|
|
else:
|
|
format_mbr(disk)
|
|
|
|
def format_gpt(disk):
|
|
"""Format disk for use as a Windows OS disk using the GPT layout."""
|
|
script = [
|
|
# Partition table
|
|
'select disk {}'.format(disk['Number']),
|
|
'clean',
|
|
'convert gpt',
|
|
|
|
# System partition
|
|
# NOTE: ESP needs to be >= 260 for Advanced Format 4K disks
|
|
'create partition efi size=500',
|
|
'format quick fs=fat32 label="System"',
|
|
'assign letter="S"',
|
|
|
|
# Microsoft Reserved (MSR) partition
|
|
'create partition msr size=128',
|
|
|
|
# Windows partition
|
|
'create partition primary',
|
|
'format quick fs=ntfs label="Windows"',
|
|
'assign letter="W"',
|
|
|
|
# Recovery Tools partition
|
|
'shrink minimum=500',
|
|
'create partition primary',
|
|
'format quick fs=ntfs label="Recovery Tools"',
|
|
'assign letter="T"',
|
|
'set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"',
|
|
'gpt attributes=0x8000000000000001',
|
|
]
|
|
|
|
# Run
|
|
run_diskpart(script)
|
|
|
|
def format_mbr(disk):
|
|
"""Format disk for use as a Windows OS disk using the MBR layout."""
|
|
script = [
|
|
# Partition table
|
|
'select disk {}'.format(disk['Number']),
|
|
'clean',
|
|
|
|
# System partition
|
|
'create partition primary size=100',
|
|
'format fs=ntfs quick label="System Reserved"',
|
|
'active',
|
|
'assign letter="S"',
|
|
|
|
# Windows partition
|
|
'create partition primary',
|
|
'format fs=ntfs quick label="Windows"',
|
|
'assign letter="W"',
|
|
|
|
# Recovery Tools partition
|
|
'shrink minimum=500',
|
|
'create partition primary',
|
|
'format quick fs=ntfs label="Recovery"',
|
|
'assign letter="T"',
|
|
'set id=27',
|
|
]
|
|
|
|
# Run
|
|
run_diskpart(script)
|
|
|
|
def mount_windows_share():
|
|
"""Mount the Windows images share unless labeled as already mounted."""
|
|
if not WINDOWS_SERVER['Mounted']:
|
|
mount_network_share(WINDOWS_SERVER)
|
|
|
|
def select_windows_version():
|
|
actions = [
|
|
{'Name': 'Main Menu', 'Letter': 'M'},
|
|
]
|
|
|
|
# Menu loop
|
|
selection = menu_select(
|
|
title = 'Which version of Windows are we installing?',
|
|
main_entries = WINDOWS_VERSIONS,
|
|
action_entries = actions)
|
|
|
|
if selection.isnumeric():
|
|
return WINDOWS_VERSIONS[int(selection)-1]
|
|
elif selection == 'M':
|
|
raise GenericAbort
|
|
|
|
def setup_windows(windows_image, windows_version):
|
|
cmd = [
|
|
global_vars['Tools']['wimlib-imagex'],
|
|
'apply',
|
|
windows_image['Path'],
|
|
windows_version['Image Name'],
|
|
'W:\\']
|
|
if 'Glob' in windows_image:
|
|
cmd.extend(windows_image['Glob'])
|
|
run_program(cmd)
|
|
|
|
def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'):
|
|
win = r'{}:\Windows'.format(windows_letter)
|
|
winre = r'{}\System32\Recovery\WinRE.wim'.format(win)
|
|
dest = r'{}:\Recovery\WindowsRE'.format(tools_letter)
|
|
|
|
# Copy WinRE.wim
|
|
os.makedirs(dest, exist_ok=True)
|
|
shutil.copy(winre, r'{}\WinRE.wim'.format(dest))
|
|
|
|
# Set location
|
|
cmd = [
|
|
r'{}\System32\ReAgentc.exe'.format(win),
|
|
'/setreimage',
|
|
'/path', dest,
|
|
'/target', win]
|
|
run_program(cmd)
|
|
|
|
def update_boot_partition(system_letter='S', windows_letter='W', mode='ALL'):
|
|
cmd = [
|
|
r'{}\Windows\System32\bcdboot.exe'.format(
|
|
global_vars['Env']['SYSTEMDRIVE']),
|
|
r'{}:\Windows'.format(windows_letter),
|
|
'/s', '{}:'.format(system_letter),
|
|
'/f', mode]
|
|
run_program(cmd)
|
|
|
|
def wim_contains_image(filename, imagename):
|
|
cmd = [
|
|
global_vars['Tools']['wimlib-imagex'],
|
|
'info',
|
|
filename,
|
|
imagename]
|
|
try:
|
|
run_program(cmd)
|
|
except subprocess.CalledProcessError:
|
|
return False
|
|
|
|
return True
|
|
|
|
if __name__ == '__main__':
|
|
print("This file is not meant to be called directly.")
|