diff --git a/scripts/Launch.cmd b/scripts/Launch.cmd index 1afddb2b..ade2f35a 100644 --- a/scripts/Launch.cmd +++ b/scripts/Launch.cmd @@ -19,7 +19,7 @@ call :DeQuote L_TYPE :SetVariables rem Set variables using settings\main.py file -set "SETTINGS=%bin%\Scripts\settings\main.py" +set "SETTINGS=%bin%\Scripts\wk\cfg\main.py" for %%v in (ARCHIVE_PASSWORD KIT_NAME_FULL OFFICE_SERVER_IP QUICKBOOKS_SERVER_IP) do ( set "var=%%v" for /f "tokens=* usebackq" %%f in (`findstr "!var!=" "%SETTINGS%"`) do ( diff --git a/scripts/auto_repairs.py b/scripts/auto_repairs.py index 2de242ec..a16b9600 100644 --- a/scripts/auto_repairs.py +++ b/scripts/auto_repairs.py @@ -1,4 +1,4 @@ -"""Wizard Kit: Auto-Repair Tool""" +"""Wizard Kit: Auto Repair Tool""" # vim: sts=2 sw=2 ts=2 import os diff --git a/scripts/auto_setup.py b/scripts/auto_setup.py new file mode 100644 index 00000000..fa4cd114 --- /dev/null +++ b/scripts/auto_setup.py @@ -0,0 +1,168 @@ +"""Wizard Kit: Auto System Setup Tool""" +# vim: sts=2 sw=2 ts=2 + +import os +import sys + +os.chdir(os.path.dirname(os.path.realpath(__file__))) +sys.path.append(os.getcwd()) +import wk # pylint: disable=wrong-import-position + + +# STATIC VARIABLES +PRESETS = { + 'Default': {}, # Will be built at runtime using BASE_MENUS + 'Additional User': { + 'Configure System': ( + 'Chrome Notifications', + 'Open Shell', + 'uBlock Origin', + 'Enable BSoD MiniDumps', + 'Enable RegBack', + 'Enable System Restore', + 'Set System Restore Size', + 'Enable Windows Updates', + 'Windows Explorer', + ), + 'Install Software': ( + 'Firefox', # Needed to handle profile upgrade nonsense + ), + 'System Summary': ( + 'Operating System', + 'Windows Activation', + 'Secure Boot', + 'Installed RAM', + 'Storage Status', + 'Virus Protection', + 'Partitions 4K Aligned', + ), + }, + 'Hardware': { + 'Configure System': ( + 'Enable BSoD MiniDumps', + 'Enable RegBack', + 'Enable System Restore', + 'Set System Restore Size', + 'Enable Windows Updates', + ), + 'System Information': ( + 'Backup Registry', + ), + 'System Summary': ( + 'Operating System', + 'Windows Activation', + 'Secure Boot', + 'Installed RAM', + 'Storage Status', + 'Virus Protection', + 'Partitions 4K Aligned', + ), + 'Run Programs': ( + 'Device Manager', + 'HWiNFO Sensors', + 'XMPlay', + ), + }, + 'Verify': { + 'Configure System': ( + 'Enable BSoD MiniDumps', + 'Enable RegBack', + 'Enable System Restore', + 'Set System Restore Size', + 'Enable Windows Updates', + 'Windows Explorer', + ), + 'System Summary': ( + 'Operating System', + 'Windows Activation', + 'Secure Boot', + 'Installed RAM', + 'Storage Status', + 'Virus Protection', + 'Installed Office', + 'Partitions 4K Aligned', + ), + }, + } + +# Classes +class MenuEntry(): + # pylint: disable=too-few-public-methods + """Simple class to allow cleaner code below.""" + def __init__(self, name, function=None, selected=True, **kwargs): + self.name = name + self.details = { + 'Function': function, + 'Selected': selected, + **kwargs, + } + + +# STATIC VARIABLES +BASE_MENUS = { + 'Groups': { + 'Backup Settings': ( + MenuEntry('Backup Browsers', 'auto_backup_browser_profiles'), + MenuEntry('Backup Power Plans', 'auto_backup_power_plans'), + MenuEntry('Reset Power Plans', 'auto_reset_power_plans'), + MenuEntry('Set Custom Power Plan', 'auto_set_custom_power_plan'), + ), + 'Install Software': ( + MenuEntry('Visual C++ Runtimes', 'auto_install_vcredists'), + MenuEntry('Firefox', 'auto_install_firefox'), + MenuEntry('LibreOffice', 'auto_install_libreoffice', selected=False), + MenuEntry('Open Shell', 'auto_install_open_shell'), + MenuEntry('Software Bundle', 'auto_install_software_bundle'), + ), + 'Configure System': ( + MenuEntry('Configure Browsers', 'auto_config_browsers'), + MenuEntry('Open Shell', 'auto_config_open_shell'), + MenuEntry('Enable BSoD MiniDumps', 'auto_enable_bsod_minidumps'), + MenuEntry('Enable RegBack', 'auto_enable_regback'), + MenuEntry('Enable System Restore', 'auto_system_restore_enable'), + MenuEntry('Set System Restore Size', 'auto_system_restore_set_size'), + MenuEntry('Enable Windows Updates', 'auto_windows_updates_enable'), + MenuEntry('User Account Control', 'auto_restore_default_uac'), + MenuEntry('Windows Activation', 'auto_activate_windows'), + MenuEntry('Windows Explorer', 'auto_config_explorer'), + MenuEntry(r'Windows\Temp Fix', 'auto_windows_temp_fix'), + MenuEntry('Create System Restore', 'auto_system_restore_create'), + ), + 'System Information': ( + MenuEntry('AIDA64 Report', 'auto_export_aida64_report'), + MenuEntry('Backup Registry', 'auto_backup_registry'), + ), + 'System Summary': ( + MenuEntry('Operating System', 'auto_show_os_name'), + MenuEntry('Windows Activation', 'auto_show_os_activation'), + MenuEntry('Secure Boot', 'auto_show_secure_boot_status'), + MenuEntry('Installed RAM', 'auto_show_installed_ram'), + MenuEntry('Storage Status', 'auto_show_storage_status'), + MenuEntry('Virus Protection', 'auto_show_installed_antivirus'), + MenuEntry('Partitions 4K Aligned', 'auto_show_4k_alignment_check'), + ), + 'Run Programs': ( + MenuEntry('Device Manager', 'auto_open_device_manager'), + MenuEntry('HWiNFO Sensors', 'auto_open_hwinfo_sensors'), + MenuEntry('Windows Activation', 'auto_open_windows_activation'), + MenuEntry('Windows Updates', 'auto_open_windows_updates'), + MenuEntry('XMPlay', 'auto_open_xmplay'), + ), + }, + 'Actions': ( + MenuEntry('Load Preset'), + MenuEntry('Start', Separator=True), + MenuEntry('Quit'), + ), + } + + +if __name__ == '__main__': + try: + wk.setup.win.run_auto_setup(BASE_MENUS, PRESETS) + except KeyboardInterrupt: + wk.std.abort() + except SystemExit: + raise + except: #pylint: disable=bare-except + wk.std.major_exception() diff --git a/scripts/check_disk.py b/scripts/check_disk.py index 7e6810c9..1682d94f 100644 --- a/scripts/check_disk.py +++ b/scripts/check_disk.py @@ -23,10 +23,10 @@ def main(): # Run or schedule scan if 'Offline' in selection[0]: - function = wk.os.win.run_chkdsk_offline + function = wk.repairs.win.run_chkdsk_offline msg_good = 'Scheduled' else: - function = wk.os.win.run_chkdsk_online + function = wk.repairs.win.run_chkdsk_online msg_good = 'No issues detected' try_print.run( message=f'CHKDSK ({os.environ.get("SYSTEMDRIVE")})...', diff --git a/scripts/ddrescue-tui.py b/scripts/ddrescue-tui.py index 289b49d9..413e81e6 100755 --- a/scripts/ddrescue-tui.py +++ b/scripts/ddrescue-tui.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 """Wizard Kit: ddrescue TUI""" +# pylint: disable=invalid-name # vim: sts=2 sw=2 ts=2 -import wk - from docopt import docopt +import wk + if __name__ == '__main__': try: diff --git a/scripts/get_raw_disks.ps1 b/scripts/get_raw_disks.ps1 new file mode 100644 index 00000000..afdb9300 --- /dev/null +++ b/scripts/get_raw_disks.ps1 @@ -0,0 +1,3 @@ +# Wizard Kit: Get RAW disks + +Get-Disk | Where-Object {$_.PartitionStyle -eq "RAW"} | Select FriendlyName,Size,PartitionStyle | ConvertTo-JSON \ No newline at end of file diff --git a/scripts/hw-diags.py b/scripts/hw-diags.py index 1dc17294..c72fd91f 100755 --- a/scripts/hw-diags.py +++ b/scripts/hw-diags.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 """Wizard Kit: Hardware Diagnostics""" +# pylint: disable=invalid-name # vim: sts=2 sw=2 ts=2 -import wk - from docopt import docopt +import wk + if __name__ == '__main__': try: diff --git a/scripts/outer_scripts_to_review/check_disk.py b/scripts/outer_scripts_to_review/check_disk.py deleted file mode 100644 index fe18650b..00000000 --- a/scripts/outer_scripts_to_review/check_disk.py +++ /dev/null @@ -1,57 +0,0 @@ -# Wizard Kit: Check or repair the %SYSTEMDRIVE% filesystem via CHKDSK - -import os -import sys - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from functions.repairs import * -init_global_vars() -os.system('title {}: Check Disk Tool'.format(KIT_NAME_FULL)) -set_log_file('Check Disk.log') - -if __name__ == '__main__': - try: - stay_awake() - clear_screen() - other_results = { - 'Error': { - 'CalledProcessError': 'Unknown Error', - }, - 'Warning': { - 'GenericRepair': 'Repaired', - 'UnsupportedOSError': 'Unsupported OS', - }} - options = [ - {'Name': 'Run CHKDSK scan (read-only)', 'Repair': False}, - {'Name': 'Schedule CHKDSK scan (offline repair)', 'Repair': True}] - actions = [{'Name': 'Quit', 'Letter': 'Q'}] - selection = menu_select( - '{}: Check Disk Menu\n'.format(KIT_NAME_FULL), - main_entries=options, - action_entries=actions) - print_info('{}: Check Disk Menu\n'.format(KIT_NAME_FULL)) - if selection == 'Q': - abort() - elif selection.isnumeric(): - repair = options[int(selection)-1]['Repair'] - if repair: - cs = 'Scheduled' - else: - cs = 'No issues' - message = 'CHKDSK ({SYSTEMDRIVE})...'.format(**global_vars['Env']) - try_and_print(message=message, function=run_chkdsk, - cs=cs, other_results=other_results, repair=repair) - else: - abort() - - # Done - print_success('Done.') - pause("Press Enter to exit...") - exit_script() - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: - major_exception() - -# vim: sts=2 sw=2 ts=2 diff --git a/scripts/outer_scripts_to_review/dism.py b/scripts/outer_scripts_to_review/dism.py deleted file mode 100644 index 4de5b788..00000000 --- a/scripts/outer_scripts_to_review/dism.py +++ /dev/null @@ -1,58 +0,0 @@ -# Wizard Kit: Check or repair component store health via DISM - -import os -import sys - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from functions.repairs import * -init_global_vars() -os.system('title {}: DISM helper Tool'.format(KIT_NAME_FULL)) -set_log_file('DISM Helper.log') - -if __name__ == '__main__': - try: - stay_awake() - clear_screen() - other_results = { - 'Error': { - 'CalledProcessError': 'Unknown Error', - }, - 'Warning': { - 'GenericRepair': 'Repaired', - 'UnsupportedOSError': 'Unsupported OS', - }} - disabled = bool(global_vars['OS']['Version'] not in ('8', '8.1', '10')) - options = [ - {'Name': 'Check Health', 'Repair': False, 'Disabled': disabled}, - {'Name': 'Restore Health', 'Repair': True, 'Disabled': disabled}] - actions = [{'Name': 'Quit', 'Letter': 'Q'}] - selection = menu_select( - '{}: DISM Menu\n'.format(KIT_NAME_FULL), - main_entries=options, - action_entries=actions) - print_info('{}: DISM Menu\n'.format(KIT_NAME_FULL)) - if selection == 'Q': - abort() - elif selection.isnumeric(): - repair = options[int(selection)-1]['Repair'] - if repair: - message='DISM RestoreHealth...' - else: - message='DISM ScanHealth...' - try_and_print(message=message, function=run_dism, - cs='No corruption', ns='Corruption detected', - other_results=other_results, repair=repair) - else: - abort() - - # Done - print_success('Done.') - pause("Press Enter to exit...") - exit_script() - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: - major_exception() - -# vim: sts=2 sw=2 ts=2 diff --git a/scripts/outer_scripts_to_review/install_sw_bundle.py b/scripts/outer_scripts_to_review/install_sw_bundle.py deleted file mode 100644 index c69a19dd..00000000 --- a/scripts/outer_scripts_to_review/install_sw_bundle.py +++ /dev/null @@ -1,72 +0,0 @@ -# Wizard Kit: Install the standard SW bundle based on the OS version - -import os -import sys - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from functions.setup import * -init_global_vars() -os.system('title {}: SW Bundle Tool'.format(KIT_NAME_FULL)) -set_log_file('Install SW Bundle.log') -D7_MODE = 'd7mode' in sys.argv - -if __name__ == '__main__': - try: - stay_awake() - clear_screen() - print_info('{}: SW Bundle Tool\n'.format(KIT_NAME_FULL)) - other_results = { - 'Error': { - 'CalledProcessError': 'Unknown Error', - 'FileNotFoundError': 'File not found', - }, - 'Warning': { - 'GenericRepair': 'Repaired', - 'UnsupportedOSError': 'Unsupported OS', - }} - answer_extensions = D7_MODE or ask('Install Extensions?') - answer_vcr = D7_MODE or ask('Install Visual C++ Runtimes?') - if D7_MODE: - answer_ninite = True - answer_mse = False - else: - answer_ninite = ask('Install Ninite Bundle?') - if answer_ninite and global_vars['OS']['Version'] in ['7']: - # Vista is dead, not going to check for it - answer_mse = ask('Install MSE?') - else: - answer_mse = False - - print_info('Installing Programs') - if answer_vcr: - install_vcredists() - if answer_ninite: - message='Ninite bundle...' - if D7_MODE: - message='Updating browsers...' - result = try_and_print(message=message, - function=install_ninite_bundle, cs='Started', - browsers_only=D7_MODE, mse=answer_mse, - other_results=other_results) - for proc in result['Out']: - # Wait for all processes to finish - proc.wait() - if answer_extensions: - print_info('Installing Extensions') - try_and_print(message='Classic Shell skin...', - function=install_classicstart_skin, - other_results=other_results) - try_and_print(message='Google Chrome extensions...', - function=install_chrome_extensions) - try_and_print(message='Mozilla Firefox extensions...', - function=install_firefox_extensions, - other_results=other_results) - print_standard('\nDone.') - exit_script() - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: - major_exception() - -# vim: sts=2 sw=2 ts=2 diff --git a/scripts/outer_scripts_to_review/install_vcredists.py b/scripts/outer_scripts_to_review/install_vcredists.py deleted file mode 100644 index 1cd31d95..00000000 --- a/scripts/outer_scripts_to_review/install_vcredists.py +++ /dev/null @@ -1,35 +0,0 @@ -# Wizard Kit: Install Visual C++ Runtimes - -import os -import sys - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from functions.setup import * -init_global_vars() -os.system('title {}: Install Visual C++ Runtimes'.format(KIT_NAME_FULL)) -set_log_file('Install Visual C++ Runtimes.log') - -if __name__ == '__main__': - try: - stay_awake() - clear_screen() - print_info('{}: Install Visual C++ Runtimes\n'.format(KIT_NAME_FULL)) - other_results = { - 'Error': { - 'CalledProcessError': 'Unknown Error', - }} - - if ask('Install Visual C++ Runtimes?'): - install_vcredists() - else: - abort() - - print_standard('\nDone.') - exit_script() - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: - major_exception() - -# vim: sts=2 sw=2 ts=2 diff --git a/scripts/outer_scripts_to_review/system_diagnostics.py b/scripts/outer_scripts_to_review/system_diagnostics.py deleted file mode 100644 index 74e92dd8..00000000 --- a/scripts/outer_scripts_to_review/system_diagnostics.py +++ /dev/null @@ -1,212 +0,0 @@ -# Wizard Kit: System Diagnostics - -import os -import sys - - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from functions.browsers import * -from functions.info import * -from functions.product_keys import * -from functions.repairs import * -from functions.sw_diags import * -init_global_vars() -os.system('title {}: System Diagnostics Tool'.format(KIT_NAME_FULL)) -set_log_file('System Diagnostics.log') -D7_MODE = 'd7mode' in sys.argv - - -# Static Variables -BLEACH_BIT_CLEANERS = { - 'Applications': ( - 'adobe_reader.cache', - 'adobe_reader.tmp', - 'amule.tmp', - 'flash.cache', - 'gimp.tmp', - 'hippo_opensim_viewer.cache', - 'java.cache', - 'libreoffice.cache', - 'liferea.cache', - 'miro.cache', - 'openofficeorg.cache', - 'pidgin.cache', - 'secondlife_viewer.Cache', - 'thunderbird.cache', - 'vuze.backup_files', - 'vuze.cache', - 'vuze.tmp', - 'yahoo_messenger.cache', - ), - 'Browsers': ( - 'chromium.cache', - 'chromium.current_session', - 'firefox.cache', - 'firefox.session_restore', - 'google_chrome.cache', - 'google_chrome.session', - 'google_earth.temporary_files', - 'internet_explorer.temporary_files', - 'opera.cache', - 'opera.current_session', - 'safari.cache', - 'seamonkey.cache', - ), - 'System': ( - 'system.clipboard', - 'system.tmp', - 'winapp2_windows.jump_lists', - 'winapp2_windows.ms_search', - 'windows_explorer.run', - 'windows_explorer.search_history', - 'windows_explorer.thumbnails', - ), -} - - -def check_result(result, other_results): - """Check result for warnings and errors.""" - result_ok = True - if not result['CS']: - for warning in other_results.get('Warning', {}).keys(): - if warning in str(result['Error']): - # Ignore warnings and repair statements - return True - # Error is not a warning - result_ok = False - return result_ok - - -if __name__ == '__main__': - try: - stay_awake() - clear_screen() - print_info('{}: System Diagnostics Tool\n'.format(KIT_NAME_FULL)) - ticket_number = get_ticket_number() - system_ok = True - other_results = { - 'Error': { - 'CalledProcessError': 'Unknown Error', - 'FileNotFoundError': 'File not found', - }, - 'Warning': { - 'GenericRepair': 'Repaired', - 'UnsupportedOSError': 'Unsupported OS', - }} - if ENABLED_TICKET_NUMBERS: - print_info('Starting System Diagnostics for Ticket #{}\n'.format( - ticket_number)) - - # Sanitize Environment - print_info('Sanitizing Environment') - if not D7_MODE: - try_and_print(message='Running RKill...', - function=run_rkill, cs='Done', other_results=other_results) - try_and_print(message='Running TDSSKiller...', - function=run_tdsskiller, cs='Done', other_results=other_results) - - # Re-run if earlier process was stopped. - stay_awake() - - # Start diags - if not D7_MODE: - print_info('Starting Background Scans') - check_connection() - try_and_print(message='Running HitmanPro...', - function=run_hitmanpro, cs='Started', other_results=other_results) - try_and_print(message='Running Autoruns...', - function=run_autoruns, cs='Started', other_results=other_results) - - # OS Health Checks - print_info('OS Health Checks') - result = try_and_print( - message='CHKDSK ({SYSTEMDRIVE})...'.format(**global_vars['Env']), - function=run_chkdsk, other_results=other_results) - system_ok = system_ok and check_result(result, other_results) - result = try_and_print(message='SFC scan...', - function=run_sfc_scan, other_results=other_results) - system_ok = system_ok and check_result(result, other_results) - if D7_MODE: - result = try_and_print(message='DISM RestoreHealth...', - function=run_dism, other_results=other_results, repair=True) - if global_vars['OS']['Version'] in ('8', '8.1', '10'): - system_ok = system_ok and check_result(result, other_results) - else: - try_and_print(message='DISM CheckHealth...', - function=run_dism, other_results=other_results, repair=False) - - if D7_MODE: - # Archive all browsers for all users - print_standard(' ') - archive_all_users() - else: - # Scan for supported browsers - print_info('Scanning for browsers') - scan_for_browsers() - - # Run BleachBit cleaners - print_info('BleachBit Cleanup') - for k, v in sorted(BLEACH_BIT_CLEANERS.items()): - try_and_print(message='{}...'.format(k), - function=run_bleachbit, - cs='SUCCESS', other_results=other_results, - cleaners=v, preview=bool(not D7_MODE)) - print_standard(' ') - - # Export system info - if not D7_MODE: - print_info('Backup System Information') - try_and_print(message='AIDA64 reports...', - function=run_aida64, cs='SUCCESS', other_results=other_results) - backup_browsers() - try_and_print(message='File listing...', - function=backup_file_list, cs='SUCCESS', other_results=other_results) - try_and_print(message='Power plans...', - function=backup_power_plans, cs='SUCCESS') - try_and_print(message='Product Keys...', - function=run_produkey, cs='SUCCESS', other_results=other_results) - try_and_print(message='Registry...', - function=backup_registry, cs='SUCCESS', other_results=other_results, - overwrite=True) - - # Summary - if not D7_MODE: - print_info('Summary') - try_and_print(message='Operating System:', - function=show_os_name, ns='Unknown', silent_function=False) - try_and_print(message='Activation:', - function=show_os_activation, ns='Unknown', silent_function=False) - try_and_print(message='Installed RAM:', - function=show_installed_ram, ns='Unknown', silent_function=False) - show_free_space() - try_and_print(message='Temp Size:', - function=show_temp_files_size, silent_function=False) - try_and_print(message='Installed Antivirus:', - function=get_installed_antivirus, ns='Unknown', - other_results=other_results, print_return=True) - try_and_print(message='Installed Office:', - function=get_installed_office, ns='Unknown', - other_results=other_results, print_return=True) - try_and_print(message='Product Keys:', - function=get_product_keys, ns='Unknown', print_return=True) - - # User data - if not D7_MODE: - print_info('User Data') - try: - show_user_data_summary() - except Exception: - print_error(' Unknown error.') - - # Done - if not D7_MODE or not system_ok: - print_standard('\nDone.') - pause('Press Enter to exit...') - exit_script() - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: - major_exception() - -# vim: sts=2 sw=2 ts=2 diff --git a/scripts/outer_scripts_to_review/system_setup.py b/scripts/outer_scripts_to_review/system_setup.py deleted file mode 100644 index 68294b04..00000000 --- a/scripts/outer_scripts_to_review/system_setup.py +++ /dev/null @@ -1,440 +0,0 @@ -'''Wizard Kit: System Setup''' -# pylint: disable=wildcard-import,wrong-import-position -# vim: sts=2 sw=2 ts=2 - -import os -import pathlib -import sys - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from collections import OrderedDict -from functions.activation import * -from functions.browsers import * -from functions.cleanup import * -from functions.info import * -from functions.product_keys import * -from functions.setup import * -from functions.sw_diags import * -from functions.windows_updates import * -init_global_vars() -os.system('title {}: System Setup'.format(KIT_NAME_FULL)) -set_log_file('System Setup.log') - - -# STATIC VARIABLES -# pylint: disable=bad-whitespace,line-too-long -OTHER_RESULTS = { - 'Error': { - 'BIOSKeyNotFoundError': 'BIOS KEY NOT FOUND', - 'CalledProcessError': 'UNKNOWN ERROR', - 'FileNotFoundError': 'FILE NOT FOUND', - 'GenericError': 'UNKNOWN ERROR', - 'Not4KAlignedError': 'FALSE', - 'SecureBootDisabledError': 'DISABLED', - 'WindowsUnsupportedError': 'UNSUPPORTED', - }, - 'Warning': { - 'GenericRepair': 'REPAIRED', - 'NoProfilesError': 'NO PROFILES FOUND', - 'NotInstalledError': 'NOT INSTALLED', - 'OSInstalledLegacyError': 'OS INSTALLED LEGACY', - 'SecureBootNotAvailError': 'NOT AVAILABLE', - 'SecureBootUnknownError': 'UNKNOWN', - 'UnsupportedOSError': 'UNSUPPORTED OS', - 'WindowsOutdatedError': 'OUTDATED', - }, - } -SETUP_ACTIONS = OrderedDict({ - # Install software - 'Installing Programs': {'Info': True}, - 'VCR': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': install_vcredists, 'Just run': True,}, - 'ESET NOD32 AV': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': install_eset_nod32_av, 'If answer': 'ESET', 'KWArgs': {'msp': False},}, - 'LibreOffice': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': install_libreoffice, - 'If answer': 'LibreOffice', 'KWArgs': {'quickstart': False, 'register_mso_types': True, 'use_mso_formats': True, 'vcredist': False}, - }, - 'Ninite bundle': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': install_ninite_bundle, 'KWArgs': {'cs': 'STARTED'},}, - - # Browsers - 'Scanning for browsers': {'Info': True}, - 'Scan': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': scan_for_browsers, 'Just run': True, 'KWArgs': {'skip_ie': True},}, - 'Backing up browsers': {'Info': True}, - 'Backup browsers': {'New': False, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': backup_browsers, 'Just run': True,}, - - # Install extensions - 'Installing Extensions': {'Info': True}, - 'Classic Shell skin': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': install_classicstart_skin, 'Win10 only': True,}, - 'Chrome extensions': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': install_chrome_extensions,}, - 'Firefox extensions': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': install_firefox_extensions,}, - - # Set Default Apps - 'Set Default Apps': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': open_default_apps, 'Win10 only': True, - 'Pause': 'Please set default browser, and other apps as needed',}, - - # Configure software' - 'Configuring Programs': {'Info': True}, - 'Browser add-ons': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': install_adblock, 'Just run': True, - 'Pause': 'Please enable uBlock Origin for all browsers', - }, - 'Chrome Notifications': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': disable_chrome_notifications,}, - 'Classic Start': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': config_classicstart, 'Win10 only': True,}, - 'Config Windows Updates': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': config_windows_updates, 'Win10 only': True,}, - 'Enable System Restore': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': enable_system_restore,}, - 'Create System Restore': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': False, 'Function': create_system_restore_point,}, - 'Disable Fast Startup': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': disable_fast_startup, 'If answer': 'Fast-Hiber', 'Win10 only': True,}, - 'Disable telemetry': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': disable_windows_telemetry, 'Win10 only': True,}, - 'Enable BSoD mini dumps': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': enable_mini_dumps,}, - 'Enable Hibernation': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': enable_hibernation, 'If answer': 'Fast-Hiber', 'Win10 only': True,}, - 'Enable RegBack': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': enable_regback, 'Win10 only': True,}, - 'Enable Windows Updates': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': enable_windows_updates, 'KWArgs': {'silent': True},}, - 'Explorer (system)': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': config_explorer_system, 'Win10 only': True,}, - 'Explorer (user)': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': config_explorer_user, 'Win10 only': True,}, - 'Restart Explorer': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': restart_explorer,}, - 'Power Plans': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': config_power_plans, 'KWArgs': {'name': 'Balanced'},}, - 'Update Clock': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': update_clock,}, - 'Windows\\Temp Fix': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': fix_windows_temp_dir,}, - - # Cleanup - 'Cleaning up': {'Info': True}, - 'AdwCleaner': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': cleanup_adwcleaner,}, - 'd7II': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': cleanup_d7ii,}, - 'Desktop': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': cleanup_desktop,}, - 'Emsisoft s2cmd': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': cleanup_emsisoft,}, - 'Registry Backup(s)': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': cleanup_regbackups,}, - 'Restore default UAC': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': restore_default_uac,}, - 'KIT_NAME_FULL': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': delete_empty_folders,}, - - # System Info - 'Exporting system info': {'Info': True}, - 'AIDA64 Report': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': run_aida64,}, - 'File listing': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': backup_file_list,}, - 'Product Keys': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': False, 'Function': run_produkey,}, - 'Registry': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': False, 'Function': backup_registry,}, - - # Show Summary - 'Summary': {'Info': True}, - 'Operating System': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': show_os_name, 'KWArgs': {'ns': 'UNKNOWN', 'silent_function': False},}, - 'Activation': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': show_os_activation, 'KWArgs': {'ns': 'UNKNOWN', 'silent_function': False},}, - 'BIOS Activation': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': activate_with_bios, 'If not activated': True,}, - 'Secure Boot': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': check_secure_boot_status, 'KWArgs': {'show_alert': False},}, - 'Installed RAM': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': show_installed_ram, 'KWArgs': {'ns': 'UNKNOWN', 'silent_function': False},}, - 'Temp size': {'New': False, 'Dat': False, 'Cur': True, 'HW': False, 'Verf': False, 'Function': show_temp_files_size, 'KWArgs': {'ns': 'UNKNOWN', 'silent_function': False},}, - 'Show free space': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': show_free_space, 'Just run': True,}, - 'Installed AV': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': get_installed_antivirus, 'KWArgs': {'ns': 'UNKNOWN', 'print_return': True},}, - 'Installed Office': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': get_installed_office, 'KWArgs': {'ns': 'UNKNOWN', 'print_return': True},}, - 'Partitions 4K aligned': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': True, 'Function': check_4k_alignment, 'KWArgs': {'cs': 'TRUE', 'ns': 'FALSE'},}, - - # Open things - 'Opening Programs': {'Info': True}, - 'Device Manager': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': False, 'Function': open_device_manager, 'KWArgs': {'cs': 'STARTED'},}, - 'HWiNFO sensors': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': False, 'Function': run_hwinfo_sensors, 'KWArgs': {'cs': 'STARTED'},}, - 'Snappy': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': False, 'Function': open_snappy_driver_origin, 'KWArgs': {'cs': 'STARTED'},}, - #'Speed test': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': False, 'Function': open_speedtest, 'KWArgs': {'cs': 'STARTED'},}, - 'Windows Updates': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': open_windows_updates, 'KWArgs': {'cs': 'STARTED'},}, - 'Windows Activation': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Verf': False, 'Function': open_windows_activation, 'If not activated': True, 'KWArgs': {'cs': 'STARTED'},}, - 'Sleep': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': False, 'Function': sleep, 'Just run': True, 'KWArgs': {'seconds': 3},}, - 'XMPlay': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Verf': False, 'Function': run_xmplay, 'KWArgs': {'cs': 'STARTED'},}, - }) -SETUP_ACTION_KEYS = ( - 'Function', - 'If not activated', - 'Info', - 'Just run', - 'KWArgs', - 'Pause', - ) -SETUP_QUESTIONS = { - # AV - 'ESET': {'New': None, 'Dat': None, 'Cur': None, 'HW': False}, - 'MSE': {'New': None, 'Dat': None, 'Cur': None, 'HW': False, 'Ninite': True}, - - # Fast Startup / Hibernation - 'Fast-Hiber': {'New': None, 'Dat': None, 'Cur': None, 'HW': False}, - - # LibreOffice - 'LibreOffice': {'New': None, 'Dat': None, 'Cur': None, 'HW': False, 'Ninite': True}, - - # Ninite - 'Base': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Ninite': True}, - 'Missing': {'New': False, 'Dat': True, 'Cur': False, 'HW': False, 'Ninite': True}, - 'Standard': {'New': True, 'Dat': True, 'Cur': False, 'HW': False, 'Ninite': True}, - } -# pylint: enable=bad-whitespace,line-too-long - - -# Functions -def check_os_and_abort(): - """Check OS and prompt to abort if not supported.""" - result = try_and_print( - message='OS support status...', - function=check_os_support_status, - cs='GOOD', - ) - if not result['CS'] and 'Unsupported' in result['Error']: - print_warning('OS version not supported by this script') - if not ask('Continue anyway? (NOT RECOMMENDED)'): - abort() - - -def get_actions(setup_mode, answers): - """Get actions to perform based on setup_mode, returns OrderedDict.""" - actions = OrderedDict({}) - for _key, _val in SETUP_ACTIONS.items(): - _action = {} - _if_answer = _val.get('If answer', False) - _win10_only = _val.get('Win10 only', False) - - # Set enabled status - _enabled = _val.get(setup_mode, False) - if _if_answer: - _enabled = _enabled and answers[_if_answer] - if _win10_only: - _enabled = _enabled and global_vars['OS']['Version'] == '10' - _action['Enabled'] = _enabled - - # Set other keys - for _sub_key in SETUP_ACTION_KEYS: - _action[_sub_key] = _val.get(_sub_key, None) - - # Fix KWArgs - if _action.get('KWArgs', {}) is None: - _action['KWArgs'] = {} - - # Handle "special" actions - if _key == 'KIT_NAME_FULL': - # Cleanup WK folders - _key = KIT_NAME_FULL - _action['KWArgs'] = {'folder_path': global_vars['ClientDir']} - elif _key == 'Ninite bundle': - # Add install_ninite_bundle() kwargs - _action['KWArgs'].update({ - kw.lower(): kv for kw, kv in answers.items() - if SETUP_QUESTIONS.get(kw, {}).get('Ninite', False) - }) - elif _key == 'Explorer (user)': - # Explorer settings (user) - _action['KWArgs'] = {'setup_mode': setup_mode} - - # Add to dict - actions[_key] = _action - - return actions - - -def get_answers(setup_mode): - """Get setup answers based on setup_mode and user input, returns dict.""" - answers = {k: v.get(setup_mode, False) for k, v in SETUP_QUESTIONS.items()} - - # Answer setup questions as needed - if answers['ESET'] is None or answers['MSE'] is None: - answers.update(get_av_selection()) - - if answers['LibreOffice'] is None: - answers['LibreOffice'] = ask('Install LibreOffice?') - - if answers['Fast-Hiber'] is None: - if global_vars['OS']['Version'] == '10': - # SSD check - if drive_is_rotational(global_vars['Env']['SYSTEMDRIVE']): - answers['Fast-Hiber'] = True - else: - print_standard(' ') - print_standard('Disable Fast Startup and enable Hibernation?') - print_standard(' Recommended for SSDs, optional for HDDs') - answers['Fast-Hiber'] = ask(' Proceed?') - else: - answers['Fast-Hiber'] = False - - return answers - - -def get_av_selection(): - """Get AV selection.""" - av_answers = { - 'ESET': False, - 'MSE': False, - } - av_options = [ - {'Name': 'ESET NOD32 AV'}, - { - 'Name': 'Microsoft Security Essentials', - 'Disabled': global_vars['OS']['Version'] not in ['7'], - }, - ] - actions = [ - {'Name': 'None', 'Letter': 'N'}, - {'Name': 'Quit', 'Letter': 'Q'}, - ] - - # Show menu - selection = menu_select( - 'Please select an option to install', - main_entries=av_options, - action_entries=actions) - if selection.isnumeric(): - index = int(selection) - 1 - if 'ESET' in av_options[index]['Name']: - av_answers['ESET'] = True - av_answers['MSE'] = False - elif 'Microsoft' in av_options[index]['Name']: - av_answers['ESET'] = False - av_answers['MSE'] = True - elif selection == 'Q': - abort() - - # ESET settings - if av_answers['ESET'] and ask(' Use MSP settings (ITS/VIP)?'): - # NOTE: There's probably a better way than updating a static var... - SETUP_ACTIONS['ESET NOD32 AV']['KWArgs']['msp'] = True - - return av_answers - - -def get_mode(): - """Get mode via menu_select, returns str.""" - setup_mode = None - mode_options = [ - {'Name': 'New', 'Display Name': 'Clean install (no data)'}, - {'Name': 'Dat', 'Display Name': 'Clean install (with data)'}, - {'Name': 'Cur', 'Display Name': 'Original OS (post-repairs)'}, - {'Name': 'HW', 'Display Name': 'Hardware service'}, - {'Name': 'Verf', 'Display Name': 'Verify (no changes)'}, - ] - actions = [ - {'Name': 'Quit', 'Letter': 'Q'}, - ] - - # Get selection - selection = menu_select( - 'Please select a setup mode', - main_entries=mode_options, - action_entries=actions) - if selection.isnumeric(): - index = int(selection) - 1 - setup_mode = mode_options[index]['Name'] - elif selection == 'Q': - abort() - - return setup_mode - - -def main(): - """Main function.""" - stay_awake() - clear_screen() - - # Check installed OS - check_os_and_abort() - - # Get setup mode - setup_mode = get_mode() - - # Get answers to setup questions - answers = get_answers(setup_mode) - - # Get actions to perform - actions = get_actions(setup_mode, answers) - - # Perform actions - for action, values in actions.items(): - kwargs = values.get('KWArgs', {}) - - # Print info lines - if values.get('Info', False): - print_info(action) - continue - - # Print disabled actions - if not values.get('Enabled', False): - show_data( - message='{}...'.format(action), - data='DISABLED', - warning=True, - ) - continue - - # Check Windows activation if requested - if values.get('If not activated', False) and windows_is_activated(): - # Skip - continue - - # Run function - if values.get('Just run', False): - values['Function'](**kwargs) - else: - result = try_and_print( - message='{}...'.format(action), - function=values['Function'], - other_results=OTHER_RESULTS, - **kwargs) - - # Wait for Ninite proc(s) - if action == 'Ninite bundle': - print_standard('Waiting for installations to finish...') - try: - for proc in result['Out']: - proc.wait() - except KeyboardInterrupt: - pass - - # Pause - if values.get('Pause', False): - print_standard(values['Pause']) - pause() - - # Show alert box for SecureBoot issues - try: - check_secure_boot_status(show_alert=True) - except Exception: # pylint: disable=broad-except - # Ignoring exceptions since we just want to show the popup - pass - - # Eject ODD - try: - run_nircmd('cdrom', 'open') - except Exception: - pass - - # Verf step - if setup_mode == 'Verf' and ask('Open programs (Activation, Device Manager, etc...)? '): - open_all_the_things() - - # Done - pause('Press Enter to exit... ') - - -def open_all_the_things(): - """TODO""" - open_device_manager() - run_hwinfo_sensors() - open_snappy_driver_origin() - open_speedtest() - open_windows_updates() - if not windows_is_activated(): - open_windows_activation() - sleep(3) - run_xmplay() - if setup_mode == 'Dat': - # System needs full AV scan - print_standard('Please run a full virus scan before continuing') - eset_path = pathlib.Path( - f'{os.environ.get("PROGRAMFILES", "")}/ESET/ESET Security/ecmds.exe') - if eset_path.exists(): - popen_program([eset_path, '/launch']) - else: - try: - run_kvrt() - except Exception: - # Meh - pass - pause('Press Enter to exit...') - - -if __name__ == '__main__': - try: - main() - exit_script() - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: # pylint: disable=bare-except - major_exception() diff --git a/scripts/outer_scripts_to_review/transferred_keys.py b/scripts/outer_scripts_to_review/transferred_keys.py deleted file mode 100644 index 216f2046..00000000 --- a/scripts/outer_scripts_to_review/transferred_keys.py +++ /dev/null @@ -1,29 +0,0 @@ -# Wizard Kit: Search for product keys in the transfer folder - -import os -import sys - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from functions.product_keys import * -init_global_vars() -os.system('title {}: Transferred Key Finder'.format(KIT_NAME_FULL)) -set_log_file('Transferred Keys.log') - -if __name__ == '__main__': - try: - stay_awake() - clear_screen() - print_info('{}: Transferred Key Finder\n'.format(KIT_NAME_FULL)) - try_and_print(message='Searching for keys...', - function=list_clientdir_keys, print_return=True) - - # Done - print_standard('\nDone.') - exit_script() - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: - major_exception() - -# vim: sts=2 sw=2 ts=2 diff --git a/scripts/outer_scripts_to_review/update_kit.py b/scripts/outer_scripts_to_review/update_kit.py deleted file mode 100644 index 4ac91ffb..00000000 --- a/scripts/outer_scripts_to_review/update_kit.py +++ /dev/null @@ -1,142 +0,0 @@ -# Wizard Kit: Download the latest versions of the programs in the kit - -import os -import sys - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from functions.update import * -init_global_vars() -os.system('title {}: Kit Update Tool'.format(KIT_NAME_FULL)) - -if __name__ == '__main__': - try: - clear_screen() - print_info('{}: Kit Update Tool\n'.format(KIT_NAME_FULL)) - other_results = { - 'Error': { - 'CalledProcessError': 'Unknown Error', - }} - - ## Prep ## - update_sdio = ask('Update SDI Origin?') - - ## Download ## - print_success('Downloading tools') - - # Data Recovery - print_info(' Data Recovery') - try_and_print(message='TestDisk / PhotoRec...', function=update_testdisk, other_results=other_results, width=40) - - # Data Transfers - print_info(' Data Transfers') - try_and_print(message='FastCopy...', function=update_fastcopy, other_results=other_results, width=40) - try_and_print(message='Linux Reader...', function=update_linux_reader, other_results=other_results, width=40) - try_and_print(message='wimlib...', function=update_wimlib, other_results=other_results, width=40) - try_and_print(message='XYplorer...', function=update_xyplorer, other_results=other_results, width=40) - - # Diagnostics - print_info(' Diagnostics') - try_and_print(message='AIDA64...', function=update_aida64, other_results=other_results, width=40) - try_and_print(message='Autoruns...', function=update_autoruns, other_results=other_results, width=40) - try_and_print(message='BleachBit...', function=update_bleachbit, other_results=other_results, width=40) - try_and_print(message='Blue Screen View...', function=update_bluescreenview, other_results=other_results, width=40) - try_and_print(message='ERUNT...', function=update_erunt, other_results=other_results, width=40) - try_and_print(message='FurMark...', function=update_furmark, other_results=other_results, width=40) - try_and_print(message='Hitman Pro...', function=update_hitmanpro, other_results=other_results, width=40) - try_and_print(message='HWiNFO...', function=update_hwinfo, other_results=other_results, width=40) - try_and_print(message='NirCmd...', function=update_nircmd, other_results=other_results, width=40) - try_and_print(message='ProduKey...', function=update_produkey, other_results=other_results, width=40) - - # Drivers - print_info(' Drivers') - try_and_print(message='Intel RST...', function=update_intel_rst, other_results=other_results, width=40) - try_and_print(message='Intel SSD Toolbox...', function=update_intel_ssd_toolbox, other_results=other_results, width=40) - try_and_print(message='Samsing Magician...', function=update_samsung_magician, other_results=other_results, width=40) - if update_sdio: - try_and_print(message='Snappy Driver Installer Origin...', function=update_sdi_origin, other_results=other_results, width=40) - - # Installers - print_info(' Installers') - try_and_print(message='Adobe Reader DC...', function=update_adobe_reader_dc, other_results=other_results, width=40) - try_and_print(message='ESET Configs...', function=update_eset_config, other_results=other_results, width=40) - try_and_print(message='ESET NOD32...', function=update_eset_nod32, other_results=other_results, width=40) - try_and_print(message='LibreOffice...', function=update_libreoffice, other_results=other_results, width=40) - try_and_print(message='Macs Fan Control...', function=update_macs_fan_control, other_results=other_results, width=40) - try_and_print(message='MS Office...', function=update_office, other_results=other_results, width=40) - try_and_print(message='Visual C++ Runtimes...', function=update_vcredists, other_results=other_results, width=40) - try_and_print(message='Windows Updates...', function=download_windows_updates, other_results=other_results, width=40) - update_all_ninite(other_results=other_results, width=40) - - # Misc - print_info(' Misc') - try_and_print(message='Caffeine...', function=update_caffeine, other_results=other_results, width=40) - try_and_print(message='Classic Start Skin...', function=update_classic_start_skin, other_results=other_results, width=40) - try_and_print(message='Du...', function=update_du, other_results=other_results, width=40) - try_and_print(message='Everything...', function=update_everything, other_results=other_results, width=40) - try_and_print(message='Firefox Extensions...', function=update_firefox_ublock_origin, other_results=other_results, width=40) - try_and_print(message='PuTTY...', function=update_putty, other_results=other_results, width=40) - try_and_print(message='ShutUp10...', function=update_shutup10, other_results=other_results, width=40) - try_and_print(message='smartmontools...', function=update_smartmontools, other_results=other_results, width=40) - try_and_print(message='Notepad++...', function=update_notepadplusplus, other_results=other_results, width=40) - try_and_print(message='WizTree...', function=update_wiztree, other_results=other_results, width=40) - try_and_print(message='XMPlay...', function=update_xmplay, other_results=other_results, width=40) - - # Repairs - print_info(' Repairs') - try_and_print(message='AdwCleaner...', function=update_adwcleaner, other_results=other_results, width=40) - try_and_print(message='ESET Online Scanner...', function=update_eset_online_scanner, other_results=other_results, width=40) - try_and_print(message='KVRT...', function=update_kvrt, other_results=other_results, width=40) - try_and_print(message='RKill...', function=update_rkill, other_results=other_results, width=40) - try_and_print(message='TDSS Killer...', function=update_tdsskiller, other_results=other_results, width=40) - try_and_print(message='WinAIO Repair...', function=update_winaiorepair, other_results=other_results, width=40) - - # Uninstallers - print_info(' Uninstallers') - try_and_print(message='ESET AV Remover...', function=update_eset_av_remover, other_results=other_results, width=40) - try_and_print(message='IObit Uninstaller...', function=update_iobit_uninstaller, other_results=other_results, width=40) - - ## Review ## - print_standard('Please review the results and download/extract any missing items to .cbin') - pause('Press Enter to compress the .cbin items') - - ## Compress ## - print_success('Compressing tools') - print_info(' _Drivers') - for item in os.scandir(r'{}\_Drivers'.format(global_vars['CBinDir'])): - if not re.search(r'^(_Drivers|.*7z)$', item.name, re.IGNORECASE): - try_and_print( - message='{}...'.format(item.name), - function=compress_and_remove_item, - other_results = other_results, - width=40, - item = item) - print_info(' .cbin') - for item in os.scandir(global_vars['CBinDir']): - if not re.search(r'^(_Drivers|_include|.*7z)$', item.name, re.IGNORECASE): - try_and_print( - message='{}...'.format(item.name), - function=compress_and_remove_item, - other_results = other_results, - width=40, - item = item) - - ## Generate Launchers - print_success('Generating launchers') - for section in sorted(LAUNCHERS.keys()): - print_info(' {}'.format(section)) - for name, options in sorted(LAUNCHERS[section].items()): - try_and_print(message=name, function=generate_launcher, - section=section, name=name, options=options, - other_results=other_results, width=40) - - # Done - print_standard('\nDone.') - pause("Press Enter to exit...") - exit_script() - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: - major_exception() - -# vim: sts=2 sw=2 ts=2 diff --git a/scripts/outer_scripts_to_review/user_data_transfer.py b/scripts/outer_scripts_to_review/user_data_transfer.py deleted file mode 100644 index 60b3c464..00000000 --- a/scripts/outer_scripts_to_review/user_data_transfer.py +++ /dev/null @@ -1,67 +0,0 @@ -# Wizard Kit: Copy user data to the system from a local or network source - -import os -import sys - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from functions.data import * -from functions.repairs import * -init_global_vars() -os.system('title {}: User Data Transfer Tool'.format(KIT_NAME_FULL)) -set_log_file('User Data Transfer.log') - -if __name__ == '__main__': - try: - # Prep - stay_awake() - clear_screen() - print_info('{}: User Data Transfer Tool\n'.format(KIT_NAME_FULL)) - - # Get backup name prefix - ticket_number = get_ticket_number() - if ENABLED_TICKET_NUMBERS: - backup_prefix = ticket_number - else: - backup_prefix = get_simple_string(prompt='Enter backup name prefix') - backup_prefix = backup_prefix.replace(' ', '_') - - # Set destination - folder_path = r'{}\Transfer'.format(KIT_NAME_SHORT) - dest = select_destination(folder_path=folder_path, - prompt='Which disk are we transferring to?') - - # Set source items - source = select_source(backup_prefix) - items = scan_source(source, dest) - - # Transfer - clear_screen() - print_info('Transfer Details:\n') - if ENABLED_TICKET_NUMBERS: - show_data('Ticket:', ticket_number) - show_data('Source:', source.path) - show_data('Destination:', dest) - - if (not ask('Proceed with transfer?')): - umount_backup_shares() - abort() - - print_info('Transferring Data') - transfer_source(source, dest, items) - try_and_print(message='Removing extra files...', - function=cleanup_transfer, cs='Done', dest_path=dest) - umount_backup_shares() - - # Done - try_and_print(message='Running KVRT...', - function=run_kvrt, cs='Started') - print_standard('\nDone.') - pause("Press Enter to exit...") - exit_script() - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: - major_exception() - -# vim: sts=2 sw=2 ts=2 diff --git a/scripts/outer_scripts_to_review/windows_updates.py b/scripts/outer_scripts_to_review/windows_updates.py deleted file mode 100644 index 9332e706..00000000 --- a/scripts/outer_scripts_to_review/windows_updates.py +++ /dev/null @@ -1,51 +0,0 @@ -# Wizard Kit: Windows updates - -import os -import sys - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from functions.windows_updates import * -init_global_vars() -os.system('title {}: Windows Updates Tool'.format(KIT_NAME_FULL)) -set_log_file('Windows Updates Tool.log') -D7_MODE = 'd7mode' in sys.argv - -if __name__ == '__main__': - try: - clear_screen() - print_info('{}: Windows Updates Tool\n'.format(KIT_NAME_FULL)) - - # Check args - if '--disable' in sys.argv: - disable_windows_updates() - elif '--enable' in sys.argv: - enable_windows_updates() - else: - print_error('Bad mode.') - abort() - - # Done - exit_script() - except GenericError as err: - # Failed to complete request, show error(s) and prompt tech - print_standard(' ') - for line in str(err).splitlines(): - print_warning(line) - print_standard(' ') - print_error('Error(s) encountered, see above.') - print_standard(' ') - if '--disable' in sys.argv: - if D7_MODE: - print_warning('Please disable d7II auto mode!') - print_standard('Then reboot, re-enable this step, and try again.') - else: - print_standard('Please reboot and try again.') - pause('Press Enter to exit... ') - exit_script(1) - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: - major_exception() - -# vim: sts=2 sw=2 ts=2 diff --git a/scripts/outer_scripts_to_review/winpe_root_menu.py b/scripts/outer_scripts_to_review/winpe_root_menu.py deleted file mode 100644 index 94669609..00000000 --- a/scripts/outer_scripts_to_review/winpe_root_menu.py +++ /dev/null @@ -1,23 +0,0 @@ -# Wizard Kit: WinPE Root Menu - -import os -import sys - -# Init -sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from functions.winpe_menus import * -# Fix 7-Zip name -TOOLS['SevenZip'].pop('64') -init_global_vars() -set_title('{}: Root Menu'.format(KIT_NAME_FULL)) -set_log_file('WinPE.log') - -if __name__ == '__main__': - try: - menu_root() - except SystemExit as sys_exit: - exit_script(sys_exit.code) - except: - major_exception() - -# vim: sts=2 sw=2 ts=2 diff --git a/scripts/sfc_scan.py b/scripts/sfc_scan.py index 02d84f77..b3132f1a 100644 --- a/scripts/sfc_scan.py +++ b/scripts/sfc_scan.py @@ -19,7 +19,7 @@ def main(): print('') # Run - try_print.run('SFC scan...', wk.os.win.run_sfc_scan) + try_print.run('SFC scan...', wk.repairs.win.run_sfc_scan) # Done print('Done') diff --git a/scripts/wk/__init__.py b/scripts/wk/__init__.py index 16692557..fd853daf 100644 --- a/scripts/wk/__init__.py +++ b/scripts/wk/__init__.py @@ -4,19 +4,19 @@ import platform from sys import version_info as version -from wk import cfg -from wk import debug -from wk import exe -from wk import hw -from wk import io -from wk import kit -from wk import log -from wk import net -from wk import os -from wk import repairs -from wk import std -from wk import sw -from wk import tmux +from . import cfg +from . import debug +from . import exe +from . import hw +from . import io +from . import kit +from . import log +from . import net +from . import os +from . import repairs +from . import setup +from . import std +from . import tmux if platform.system() != 'Windows': from wk import graph diff --git a/scripts/wk/cfg/__init__.py b/scripts/wk/cfg/__init__.py index d35b8874..f79d77ef 100644 --- a/scripts/wk/cfg/__init__.py +++ b/scripts/wk/cfg/__init__.py @@ -1,9 +1,10 @@ """WizardKit: cfg module init""" -from wk.cfg import ddrescue -from wk.cfg import hw -from wk.cfg import log -from wk.cfg import main -from wk.cfg import net -from wk.cfg import tools -from wk.cfg import ufd +from . import ddrescue +from . import hw +from . import log +from . import main +from . import net +from . import sources +from . import ufd +from . import windows_builds diff --git a/scripts/wk/cfg/tools.py b/scripts/wk/cfg/sources.py similarity index 84% rename from scripts/wk/cfg/tools.py rename to scripts/wk/cfg/sources.py index bbb0ed59..69688dca 100644 --- a/scripts/wk/cfg/tools.py +++ b/scripts/wk/cfg/sources.py @@ -32,8 +32,10 @@ SOURCES = { 'Everything32': 'https://www.voidtools.com/Everything-1.4.1.1005.x86.en-US.zip', 'Everything64': 'https://www.voidtools.com/Everything-1.4.1.1005.x64.en-US.zip', 'FastCopy': 'https://ftp.vector.co.jp/73/10/2323/FastCopy392_installer.exe', + 'Fluent-Metro': 'https://github.com/bonzibudd/Fluent-Metro/releases/download/v1.5.2/Fluent-Metro_1.5.2.zip', 'FurMark': 'https://geeks3d.com/dl/get/569', - 'Firefox uBO': 'https://addons.mozilla.org/firefox/downloads/file/3740966/ublock_origin-1.34.0-an+fx.xpi', + 'Firefox32': 'https://download.mozilla.org/?product=firefox-latest-ssl&os=win&lang=en-US', + 'Firefox64': 'https://download.mozilla.org/?product=firefox-latest-ssl&os=win64&lang=en-US', 'HitmanPro': 'https://dl.surfright.nl/HitmanPro.exe', 'HitmanPro64': 'https://dl.surfright.nl/HitmanPro_x64.exe', 'HWiNFO': 'https://files1.majorgeeks.com/c8a055180587599139f8f454712dcc618cd1740e/systeminfo/hwi_702.zip', @@ -47,6 +49,7 @@ SOURCES = { 'NirCmd32': 'https://www.nirsoft.net/utils/nircmd.zip', 'NirCmd64': 'https://www.nirsoft.net/utils/nircmd-x64.zip', 'NotepadPlusPlus': 'https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v7.9.5/npp.7.9.5.portable.minimalist.7z', + 'OpenShell': 'https://github.com/Open-Shell/Open-Shell-Menu/releases/download/v4.4.160/OpenShellSetup_4_4_160.exe', 'Office Deployment Tool': 'https://download.microsoft.com/download/2/7/A/27AF1BE6-DD20-4CB4-B154-EBAB8A7D4A7E/officedeploymenttool_11617-33601.exe', 'ProduKey32': 'http://www.nirsoft.net/utils/produkey.zip', 'ProduKey64': 'http://www.nirsoft.net/utils/produkey-x64.zip', @@ -56,10 +59,17 @@ SOURCES = { 'Samsung Magician': 'https://s3.ap-northeast-2.amazonaws.com/global.semi.static/SAMSUNG_SSD_v5_3_0_181121/CD0C7CC1BE00525FAC4675B9E502899B41D5C3909ECE3AA2FB6B74A766B2A1EA/Samsung_Magician_Installer.zip', 'SDIO Themes': 'http://snappy-driver-installer.org/downloads/SDIO_Themes.zip', 'SDIO Torrent': 'http://snappy-driver-installer.org/downloads/SDIO_Update.torrent', + 'Software Bundle': 'https://ninite.com/.net4.8-7zip-chrome-edge-vlc/ninite.exe', 'ShutUp10': 'https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe', 'smartmontools': 'https://1278-105252244-gh.circle-artifacts.com/0/builds/smartmontools-win32-setup-7.3-r5216.exe', 'TDSSKiller': 'https://media.kaspersky.com/utilities/VirusUtilities/EN/tdsskiller.exe', 'TestDisk': 'https://www.cgsecurity.org/testdisk-7.2-WIP.win.zip', + 'VCRedist_2012_x32': 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe', + 'VCRedist_2012_x64': 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe', + 'VCRedist_2013_x32': 'https://aka.ms/highdpimfc2013x86enu', + 'VCRedist_2013_x64': 'https://aka.ms/highdpimfc2013x64enu', + 'VCRedist_2019_x32': 'https://aka.ms/vs/16/release/vc_redist.x86.exe', + 'VCRedist_2019_x64': 'https://aka.ms/vs/16/release/vc_redist.x64.exe', 'wimlib32': 'https://wimlib.net/downloads/wimlib-1.13.3-windows-i686-bin.zip', 'wimlib64': 'https://wimlib.net/downloads/wimlib-1.13.3-windows-x86_64-bin.zip', 'WinAIO Repair': 'http://www.tweaking.com/files/setups/tweaking.com_windows_repair_aio.zip', diff --git a/scripts/wk/cfg/windows_builds.py b/scripts/wk/cfg/windows_builds.py new file mode 100644 index 00000000..580564b4 --- /dev/null +++ b/scripts/wk/cfg/windows_builds.py @@ -0,0 +1,36 @@ +"""WizardKit: Config - Windows Builds""" +# vim: sts=2 sw=2 ts=2 + + +OLDEST_SUPPORTED_BUILD = 19041 # Windows 10 20H1 +OUTDATED_BUILD_NUMBERS = ( + 9600, # Windows 8.1 Update + 18363, # Windows 10 19H2 + ) +WINDOWS_BUILDS = { + # Windows 7 + '6.1.7600': 'RTM "Vienna"', + '6.1.7601': 'SP1 "Vienna"', + + # Windows 8 + '6.2.9200': 'RTM', + + # Widnows 8.1 + '6.3.9200': '"Blue"', + '6.3.9600': '"Update"', + + # Windows 10 + '10.0.10240': '1507 "Threshold 1"', + '10.0.10586': '1511 "Threshold 2"', + '10.0.14393': '1607 "Redstone 1"', + '10.0.15063': '1703 "Redstone 2"', + '10.0.16299': '1709 "Redstone 3"', + '10.0.17134': '1803 "Redstone 4"', + '10.0.17763': '1809 "Redstone 5"', + '10.0.18362': '1903 / 19H1', + '10.0.18363': '1909 / 19H2', + '10.0.19041': '2004 / 20H1', + '10.0.19042': '20H2', + '10.0.19043': '21H1', + '10.0.19044': '21H2', +} diff --git a/scripts/wk/exe.py b/scripts/wk/exe.py index ab49018b..e57240c9 100644 --- a/scripts/wk/exe.py +++ b/scripts/wk/exe.py @@ -67,7 +67,7 @@ class NonBlockingStreamReader(): out = self.read(0.1) if out: out_bytes += out - with open(out_path, 'a') as _f: + with open(out_path, 'a', encoding='utf-8') as _f: _f.write(out_bytes.decode('utf-8', errors='ignore')) # Close stream to prevent 100% CPU usage @@ -200,6 +200,7 @@ def popen_program(cmd, minimized=False, pipe=False, shell=False, **kwargs): shell=shell, **kwargs) try: + # pylint: disable=consider-using-with proc = subprocess.Popen(**cmd_kwargs) except FileNotFoundError: LOG.error('Command not found: %s', cmd) diff --git a/scripts/wk/hw/__init__.py b/scripts/wk/hw/__init__.py index 6486c045..52c5c609 100644 --- a/scripts/wk/hw/__init__.py +++ b/scripts/wk/hw/__init__.py @@ -2,9 +2,9 @@ import platform -from wk.hw import obj -from wk.hw import sensors +from . import obj +from . import sensors if platform.system() != 'Windows': - from wk.hw import ddrescue - from wk.hw import diags + from . import ddrescue + from . import diags diff --git a/scripts/wk/hw/ddrescue.py b/scripts/wk/hw/ddrescue.py index 21d8f1ee..3423cd1c 100644 --- a/scripts/wk/hw/ddrescue.py +++ b/scripts/wk/hw/ddrescue.py @@ -403,7 +403,7 @@ class State(): # Try loading JSON data if settings_file.exists(): - with open(settings_file, 'r') as _f: + with open(settings_file, 'r', encoding='utf-8') as _f: try: settings = json.loads(_f.read()) except (OSError, json.JSONDecodeError) as err: @@ -451,7 +451,7 @@ class State(): # Try saving JSON data try: - with open(settings_file, 'w') as _f: + with open(settings_file, 'w', encoding='utf-8') as _f: json.dump(settings, _f) except OSError as err: std.print_error('Failed to save clone settings') @@ -904,7 +904,7 @@ class State(): f'{self.working_dir}/' f'sfdisk_{self.destination.path.name}.script' ) - with open(script_path, 'w') as _f: + with open(script_path, 'w', encoding='utf-8') as _f: _f.write('\n'.join(sfdisk_script)) # Skip real format for dry runs @@ -914,7 +914,7 @@ class State(): # Format disk LOG.warning('Formatting destination: %s', self.destination.path) - with open(script_path, 'r') as _f: + with open(script_path, 'r', encoding='utf-8') as _f: proc = exe.run_program( cmd=['sudo', 'sfdisk', self.destination.path], stdin=_f, @@ -942,7 +942,7 @@ class State(): pair.status[name] = 'Pending' # Mark all non-trimmed, non-scraped, and bad areas as non-tried - with open(pair.map_path, 'r') as _f: + with open(pair.map_path, 'r', encoding='utf-8') as _f: for line in _f.readlines(): line = line.strip() if line.startswith('0x') and line.endswith(bad_statuses): @@ -950,7 +950,7 @@ class State(): map_data.append(line) # Save updated map - with open(pair.map_path, 'w') as _f: + with open(pair.map_path, 'w', encoding='utf-8') as _f: _f.write('\n'.join(map_data)) # Reinitialize status @@ -1021,14 +1021,15 @@ class State(): # State (self) std.save_pickles({'state': self}, debug_dir) - with open(f'{debug_dir}/state.report', 'a') as _f: + with open(f'{debug_dir}/state.report', 'a', encoding='utf-8') as _f: _f.write('[Debug report]\n') _f.write('\n'.join(debug.generate_object_report(self))) _f.write('\n') # Block pairs for _bp in self.block_pairs: - with open(f'{debug_dir}/block_pairs.report', 'a') as _f: + with open( + f'{debug_dir}/block_pairs.report', 'a', encoding='utf-8') as _f: _f.write('[Debug report]\n') _f.write('\n'.join(debug.generate_object_report(_bp))) _f.write('\n') @@ -1093,7 +1094,7 @@ class State(): # Write to progress file out_path = pathlib.Path(f'{self.log_dir}/progress.out') - with open(out_path, 'w') as _f: + with open(out_path, 'w', encoding='utf-8') as _f: _f.write('\n'.join(report)) def update_top_panes(self): @@ -2033,7 +2034,7 @@ def run_ddrescue(state, block_pair, pass_name, settings, dry_run=True): """Update SMART pane every 30 seconds.""" state.source.update_smart_details() now = datetime.datetime.now(tz=TIMEZONE).strftime('%Y-%m-%d %H:%M %Z') - with open(f'{state.log_dir}/smart.out', 'w') as _f: + with open(f'{state.log_dir}/smart.out', 'w', encoding='utf-8') as _f: _f.write( std.color_string( ['SMART Attributes', f'Updated: {now}\n'], diff --git a/scripts/wk/hw/diags.py b/scripts/wk/hw/diags.py index 1f9ac788..8713cd3f 100644 --- a/scripts/wk/hw/diags.py +++ b/scripts/wk/hw/diags.py @@ -386,11 +386,11 @@ class State(): # State (self) std.save_pickles({'state': self}, debug_dir) - with open(f'{debug_dir}/state.report', 'a') as _f: + with open(f'{debug_dir}/state.report', 'a', encoding='utf-8') as _f: _f.write('\n'.join(debug.generate_object_report(self))) # CPU/RAM - with open(f'{debug_dir}/cpu.report', 'a') as _f: + with open(f'{debug_dir}/cpu.report', 'a', encoding='utf-8') as _f: _f.write('\n'.join(debug.generate_object_report(self.cpu))) _f.write('\n\n[Tests]') for name, test in self.cpu.tests.items(): @@ -399,7 +399,9 @@ class State(): # Disks for disk in self.disks: - with open(f'{debug_dir}/disk_{disk.path.name}.report', 'a') as _f: + with open( + f'{debug_dir}/disk_{disk.path.name}.report', 'a', + encoding='utf-8') as _f: _f.write('\n'.join(debug.generate_object_report(disk))) _f.write('\n\n[Tests]') for name, test in disk.tests.items(): @@ -427,7 +429,7 @@ class State(): except Exception: # pylint: disable=broad-except LOG.ERROR('Error(s) encountered while exporting SMC data') data = [line.strip() for line in data] - with open(f'{debug_dir}/smc.data', 'a') as _f: + with open(f'{debug_dir}/smc.data', 'a', encoding='utf-8') as _f: _f.write('\n'.join(data)) def update_clock(self): @@ -464,7 +466,7 @@ class State(): # Write to progress file out_path = pathlib.Path(f'{self.log_dir}/progress.out') - with open(out_path, 'w') as _f: + with open(out_path, 'w', encoding='utf-8') as _f: _f.write('\n'.join(report)) def update_top_pane(self, text): @@ -697,7 +699,7 @@ def check_mprime_results(test_obj, working_dir): """Read file and split into lines, returns list.""" lines = [] try: - with open(f'{working_dir}/{log_name}', 'r') as _f: + with open(f'{working_dir}/{log_name}', 'r', encoding='utf-8') as _f: lines = _f.readlines() except FileNotFoundError: # File may be missing on older systems @@ -990,7 +992,7 @@ def disk_io_benchmark(state, test_objects, skip_usb=True): match.group(1) # Show progress - with open(log_path, 'a') as _f: + with open(log_path, 'a', encoding='utf-8') as _f: if _i % 5 == 0: percent = (_i / dd_values['Read Chunks']) * 100 _f.write(f' {graph.vertical_graph_line(percent, read_rates[-1])}\n') @@ -1175,7 +1177,7 @@ def disk_surface_scan(state, test_objects): # Start scan cmd = ['sudo', 'badblocks', '-sv', '-b', block_size, '-e', '1', dev_path] - with open(log_path, 'a') as _f: + with open(log_path, 'a', encoding='utf-8') as _f: size_str = std.bytes_to_string(dev.details["size"], use_binary=False) _f.write( std.color_string( @@ -1194,7 +1196,7 @@ def disk_surface_scan(state, test_objects): ) # Check results - with open(log_path, 'r') as _f: + with open(log_path, 'r', encoding='utf-8') as _f: for line in _f.readlines(): line = std.strip_colors(line.strip()) if not line or line.startswith('Checking') or line.startswith('['): @@ -1816,13 +1818,13 @@ def show_results(state): def start_mprime(working_dir, log_path): """Start mprime and save filtered output to log, returns Popen object.""" set_apple_fan_speed('max') - proc_mprime = subprocess.Popen( + proc_mprime = subprocess.Popen( # pylint: disable=consider-using-with ['mprime', '-t'], cwd=working_dir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, ) - proc_grep = subprocess.Popen( + proc_grep = subprocess.Popen( # pylint: disable=consider-using-with 'grep --ignore-case --invert-match --line-buffered stress.txt'.split(), stdin=proc_mprime.stdout, stdout=subprocess.PIPE, @@ -1861,7 +1863,9 @@ def start_sysbench(sensors, sensors_out, log_path, pane): tmux.respawn_pane(pane, watch_file=log_path, watch_cmd='tail') # Start sysbench - filehandle_sysbench = open(log_path, 'a') + filehandle_sysbench = open( # pylint: disable=consider-using-with + log_path, 'a', encoding='utf-8', + ) proc_sysbench = exe.popen_program(sysbench_cmd, stdout=filehandle_sysbench) # Done diff --git a/scripts/wk/hw/obj.py b/scripts/wk/hw/obj.py index b59246fc..961576e9 100644 --- a/scripts/wk/hw/obj.py +++ b/scripts/wk/hw/obj.py @@ -370,9 +370,11 @@ class Disk(BaseObj): self.details[attr] = -1 # Set description - self.description = '{size_str} ({bus}) {model} {serial}'.format( - size_str=bytes_to_string(self.details['size'], use_binary=False), - **self.details, + self.description = ( + f'{bytes_to_string(self.details["size"], use_binary=False)}' + f' ({self.details["bus"]})' + f' {self.details["model"]}' + f' {self.details["serial"]}' ) def get_labels(self): @@ -496,7 +498,7 @@ class Disk(BaseObj): test_minutes = int(test_minutes) + 10 # Start test - with open(log_path, 'w') as _f: + with open(log_path, 'w', encoding='utf-8') as _f: _f.write(f'{header_str}\nInitializing...') cmd = [ 'sudo', @@ -521,7 +523,7 @@ class Disk(BaseObj): status_str = status_str.capitalize() # Update log - with open(log_path, 'w') as _f: + with open(log_path, 'w', encoding='utf-8') as _f: _f.write(f'{header_str}\nSMART self-test status:\n {status_str}') # Check if finished diff --git a/scripts/wk/hw/sensors.py b/scripts/wk/hw/sensors.py index e5b27bc1..f0e7b97c 100644 --- a/scripts/wk/hw/sensors.py +++ b/scripts/wk/hw/sensors.py @@ -141,7 +141,7 @@ class Sensors(): if thermal_action: run_program(thermal_action, check=False) report = self.generate_report(*temp_labels) - with open(out_path, 'w') as _f: + with open(out_path, 'w', encoding='utf-8') as _f: _f.write('\n'.join(report)) # Check if we should stop diff --git a/scripts/wk/kit/__init__.py b/scripts/wk/kit/__init__.py index 4641fae7..c6eedd73 100644 --- a/scripts/wk/kit/__init__.py +++ b/scripts/wk/kit/__init__.py @@ -3,7 +3,7 @@ import platform -from wk.kit import tools +from . import tools if platform.system() == 'Linux': - from wk.kit import ufd + from . import ufd diff --git a/scripts/wk/kit/tools.py b/scripts/wk/kit/tools.py index bed41823..da3e69c4 100644 --- a/scripts/wk/kit/tools.py +++ b/scripts/wk/kit/tools.py @@ -4,18 +4,18 @@ from datetime import datetime, timedelta import logging import pathlib -import sys +import platform import requests from wk.cfg.main import ARCHIVE_PASSWORD -from wk.cfg.tools import SOURCES, DOWNLOAD_FREQUENCY +from wk.cfg.sources import DOWNLOAD_FREQUENCY, SOURCES from wk.exe import popen_program, run_program from wk.std import GenericError # STATIC VARIABLES -ARCH = '64' if sys.maxsize > 2**32 else '32' +ARCH = '64' if platform.architecture()[0] == '64bit' else '32' LOG = logging.getLogger(__name__) @@ -27,10 +27,12 @@ CACHED_DIRS = {} def download_file(out_path, source_url, as_new=False, overwrite=False): """Download a file using requests, returns pathlib.Path.""" out_path = pathlib.Path(out_path).resolve() + name = out_path.name + download_failed = None + download_msg = f'Downloading {name}...' if as_new: out_path = out_path.with_suffix(f'{out_path.suffix}.new') - cursor_left = '\u001B[14D' - print(f'Downloading...{cursor_left}', end='', flush=True) + print(download_msg, end='', flush=True) # Avoid clobbering if out_path.exists() and not overwrite: @@ -40,15 +42,17 @@ def download_file(out_path, source_url, as_new=False, overwrite=False): out_path.parent.mkdir(parents=True, exist_ok=True) # Request download - response = requests.get(source_url, stream=True) - if not response.ok: - name = out_path.name - if as_new: - name = name[:-4] - LOG.error( - 'Failed to download file (status %s): %s', - response.status_code, name, - ) + try: + response = requests.get(source_url, stream=True) + except requests.RequestException as _err: + download_failed = _err + else: + if not response.ok: + download_failed = response + + # Download failed + if download_failed: + LOG.error('Failed to download file: %s', download_failed) raise GenericError(f'Failed to download file: {name}') # Write to file @@ -57,14 +61,14 @@ def download_file(out_path, source_url, as_new=False, overwrite=False): _f.write(chunk) # Done - print(f' {cursor_left}', end='', flush=True) + print(f'\033[{len(download_msg)}D\033[0K', end='', flush=True) return out_path -def download_tool(folder, name): +def download_tool(folder, name, suffix=None): """Download tool.""" name_arch = f'{name}{ARCH}' - out_path = get_tool_path(folder, name, check=False) + out_path = get_tool_path(folder, name, check=False, suffix=suffix) up_to_date = False # Check if tool is up to date @@ -144,16 +148,18 @@ def find_kit_dir(name=None): return cur_path -def get_tool_path(folder, name, check=True): +def get_tool_path(folder, name, check=True, suffix=None): """Get tool path, returns pathlib.Path""" bin_dir = find_kit_dir('.bin') + if not suffix: + suffix = 'exe' name_arch = f'{name}{ARCH}' # "Search" - tool_path = bin_dir.joinpath(f'{folder}/{name_arch}.exe') + tool_path = bin_dir.joinpath(f'{folder}/{name_arch}.{suffix}') if not (tool_path.exists() or name_arch in SOURCES): # Use "default" path instead - tool_path = tool_path.with_name(f'{name}.exe') + tool_path = tool_path.with_name(f'{name}.{suffix}') # Missing? if check and not tool_path.exists(): diff --git a/scripts/wk/kit/ufd.py b/scripts/wk/kit/ufd.py index 1c3761d2..3e71fd59 100644 --- a/scripts/wk/kit/ufd.py +++ b/scripts/wk/kit/ufd.py @@ -157,7 +157,7 @@ def build_ufd(): ) for s_label, s_path in sources.items(): try_print.run( - message='Copying {}...'.format(s_label), + message=f'Copying {s_label}...', function=copy_source, source=s_path, items=ITEMS[s_label], @@ -273,7 +273,7 @@ def copy_source(source, items, overwrite=False): def create_table(dev_path, use_mbr=False, images=None): - """Create GPT or DOS partition table, returns dict.""" + """Create GPT or DOS partition table.""" cmd = [ 'sudo', 'parted', dev_path, @@ -378,7 +378,7 @@ def get_uuid(path): def hide_items(ufd_dev_first_partition, items): """Set FAT32 hidden flag for items.""" - with open('/root/.mtoolsrc', 'w') as _f: + with open('/root/.mtoolsrc', 'w', encoding='utf-8') as _f: _f.write(f'drive U: file="{ufd_dev_first_partition}"\n') _f.write('mtools_skip_check=1\n') diff --git a/scripts/wk/os/__init__.py b/scripts/wk/os/__init__.py index dff18ac2..693ec59c 100644 --- a/scripts/wk/os/__init__.py +++ b/scripts/wk/os/__init__.py @@ -4,8 +4,8 @@ import platform if platform.system() == 'Darwin': - from wk.os import mac + from . import mac if platform.system() == 'Linux': - from wk.os import linux + from . import linux if platform.system() == 'Windows': - from wk.os import win + from . import win diff --git a/scripts/wk/os/linux.py b/scripts/wk/os/linux.py index 73e6d85b..f3325fb7 100644 --- a/scripts/wk/os/linux.py +++ b/scripts/wk/os/linux.py @@ -218,7 +218,7 @@ def scan_corestorage_container(container, timeout=300): # Create mapper device(s) if necessary for name, cmd in detected_volumes.items(): cmd_file = make_temp_file() - cmd_file.write_text(cmd) + cmd_file.write_text(cmd, encoding='utf-8') proc = run_program( cmd=['sudo', 'dmsetup', 'create', name, cmd_file], check=False, diff --git a/scripts/wk/os/win.py b/scripts/wk/os/win.py index 0eb71971..4d73c21e 100644 --- a/scripts/wk/os/win.py +++ b/scripts/wk/os/win.py @@ -1,6 +1,7 @@ """WizardKit: Windows Functions""" # vim: sts=2 sw=2 ts=2 +import ctypes import logging import os import pathlib @@ -16,12 +17,26 @@ except ImportError as err: raise err from wk.borrowed import acpi -from wk.exe import run_program -from wk.std import GenericError, GenericWarning, sleep +from wk.cfg.main import KIT_NAME_FULL +from wk.cfg.windows_builds import ( + OLDEST_SUPPORTED_BUILD, + OUTDATED_BUILD_NUMBERS, + WINDOWS_BUILDS, + ) +from wk.exe import get_json_from_command, run_program +from wk.kit.tools import find_kit_dir +from wk.std import ( + GenericError, + GenericWarning, + bytes_to_string, + color_string, + sleep, + ) # STATIC VARIABLES LOG = logging.getLogger(__name__) +ARCH = '64' if platform.architecture()[0] == '64bit' else '32' CONEMU = 'ConEmuPID' in os.environ KNOWN_DATA_TYPES = { 'BINARY': winreg.REG_BINARY, @@ -57,6 +72,8 @@ KNOWN_HIVE_NAMES = { winreg.HKEY_USERS: 'HKEY_USERS', } OS_VERSION = float(platform.win32_ver()[0]) +RAM_OK = 5.5 * 1024**3 # ~6 GiB assuming a bit of shared memory +RAM_WARNING = 3.5 * 1024**3 # ~4 GiB assuming a bit of shared memory REG_MSISERVER = r'HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\Network\MSIServer' SLMGR = pathlib.Path(f'{os.environ.get("SYSTEMROOT")}/System32/slmgr.vbs') @@ -72,6 +89,11 @@ def activate_with_bios(): ##################################################### bios_key = None table = b"MSDM" + # Check if activation is needed + if is_activated(): + raise GenericWarning('System already activated') + + # Get BIOS key if acpi.FindAcpiTable(table) is True: rawtable = acpi.GetAcpiTable(table) #http://msdn.microsoft.com/library/windows/hardware/hh673514 @@ -82,10 +104,6 @@ def activate_with_bios(): if not bios_key: raise GenericError('BIOS key not found.') - # Check if activation is needed - if is_activated(): - raise GenericWarning('System already activated') - # Install Key cmd = ['cscript', '//nologo', SLMGR, '/ipk', bios_key] run_program(cmd, check=False) @@ -119,6 +137,189 @@ def is_activated(): return act_str and 'permanent' in act_str +# Date / Time functions +def get_timezone(): + """Get current timezone using tzutil, returns str.""" + cmd = ['tzutil', '/g'] + proc = run_program(cmd, check=False) + return proc.stdout + + +def set_timezone(zone): + """Set current timezone using tzutil.""" + cmd = ['tzutil', '/s', zone] + run_program(cmd, check=False) + + +# Info Functions +def check_4k_alignment(show_alert=False): + """Check if all partitions are 4K aligned, returns book.""" + cmd = ['WMIC', 'partition', 'get', 'StartingOffset'] + + # Check offsets + proc = run_program(cmd) + for offset in proc.stdout.splitlines(): + offset = offset.strip() + if not offset.isnumeric(): + continue + if int(offset) % 4096 != 0: + # Not aligned + if show_alert: + show_alert_box('One or more partitions are not 4K aligned') + raise GenericError('One or more partitions are not 4K aligned') + + +def get_installed_antivirus(): + """Get list of installed antivirus programs, returns list.""" + cmd = [ + 'WMIC', r'/namespace:\\root\SecurityCenter2', + 'path', 'AntivirusProduct', + 'get', 'displayName', '/value', + ] + products = [] + report = [] + + # Get list of products + proc = run_program(cmd) + for line in proc.stdout.splitlines(): + line = line.strip() + if '=' in line: + products.append(line.split('=')[1]) + + # Check product(s) status + for product in sorted(products): + cmd = [ + 'WMIC', r'/namespace:\\root\SecurityCenter2', + 'path', 'AntivirusProduct', + 'where', f'displayName="{product}"', + 'get', 'productState', '/value', + ] + proc = run_program(cmd) + state = proc.stdout.split('=')[1] + state = hex(int(state)) + if str(state)[3:5] not in ['10', '11']: + report.append(color_string(f'[Disabled] {product}', 'YELLOW')) + else: + report.append(product) + + # Final check + if not report: + report.append(color_string('No products detected', 'RED')) + + # Done + return report + + +def get_installed_ram(as_list=False, raise_exceptions=False): + """Get installed RAM.""" + mem = psutil.virtual_memory() + mem_str = bytes_to_string(mem.total, decimals=1) + + # Raise exception if necessary + if raise_exceptions: + if RAM_OK > mem.total >= RAM_WARNING: + raise GenericWarning(mem_str) + if mem.total > RAM_WARNING: + raise GenericError(mem_str) + + # Done + return [mem_str] if as_list else mem_str + + +def get_os_activation(as_list=False, check=True): + """Get OS activation status, returns str. + + NOTE: If check=True then raise an exception if OS isn't activated. + """ + act_str = get_activation_string() + + if check and not is_activated(): + if 'unavailable' in act_str.lower(): + raise GenericWarning(act_str) + # Else + raise GenericError(act_str) + + # Done + return [act_str] if as_list else act_str + + +def get_os_name(as_list=False, check=True): + """Build OS display name, returns str. + + NOTE: If check=True then an exception is raised if the OS version is + outdated or unsupported. + """ + key = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion' + build_version = int(reg_read_value("HKLM", key, "CurrentBuild")) + build_version_full = platform.win32_ver()[1] + details = WINDOWS_BUILDS.get(build_version_full, f'Build {build_version}') + display_name = ( + f'{reg_read_value("HKLM", key, "ProductName")} {ARCH}-bit {details}' + ) + + # Check for support issues + if check: + if build_version in OUTDATED_BUILD_NUMBERS: + raise GenericWarning(f'{display_name} (outdated)') + + if build_version < OLDEST_SUPPORTED_BUILD: + raise GenericError(f'{display_name} (unsupported)') + + # Done + return [display_name] if as_list else display_name + + +def get_raw_disks(): + """Get all disks without a partiton table, returns list.""" + script_path = find_kit_dir('Scripts').joinpath('get_raw_disks.ps1') + cmd = ['PowerShell', '-ExecutionPolicy', 'Bypass', '-File', script_path] + json_data = get_json_from_command(cmd) + raw_disks = [] + + # Fix JSON if only one disk was detected + if isinstance(json_data, dict): + json_data = [json_data] + + # Parse JSON + for disk in json_data: + size_str = bytes_to_string(int(disk["Size"]), use_binary=False) + raw_disks.append(f'{disk["FriendlyName"]} ({size_str})') + + # Done + return raw_disks + + +def get_volume_usage(use_colors=False): + """Get space usage info for all fixed volumes, returns list.""" + report = [] + for disk in psutil.disk_partitions(): + if 'fixed' not in disk.opts: + continue + total, _, free, percent = psutil.disk_usage(disk.device) + color = None + if percent > 85: + color = 'RED' + elif percent > 75: + color = 'YELLOW' + display_str = ( + f'{free/total:>5.2f}% Free' + f' ({bytes_to_string(free, 2):>10} / {bytes_to_string(total, 2):>10})' + ) + if use_colors: + display_str = color_string(display_str, color) + report.append(f'{disk.device} {display_str}') + + # Done + return report + + +def show_alert_box(message, title=None): + """Show Windows alert box with message.""" + title = title if title else f'{KIT_NAME_FULL} Warning' + message_box = ctypes.windll.user32.MessageBoxW + message_box(None, message, title, 0x00001030) + + # Registry Functions def reg_delete_key(hive, key, recurse=False): # pylint: disable=raise-missing-from @@ -221,7 +422,10 @@ def reg_key_exists(hive, key): def reg_read_value(hive, key, value, force_32=False, force_64=False): - """Query value from hive/hey, returns multiple types.""" + """Query value from hive/hey, returns multiple types. + + NOTE: Set value='' to read the default value. + """ access = winreg.KEY_READ data = None hive = reg_get_hive(hive) @@ -344,6 +548,72 @@ def enable_safemode_msi(): run_program(cmd) +# Secure Boot Functions +def is_booted_uefi(): + """Check if booted UEFI or legacy, returns bool.""" + kernel = ctypes.windll.kernel32 + firmware_type = ctypes.c_uint() + + # Get value from kernel32 API (firmware_type is updated by the call) + try: + kernel.GetFirmwareType(ctypes.byref(firmware_type)) + except Exception: # pylint: disable=broad-except + # Ignore and set firmware_type back to zero + firmware_type = ctypes.c_uint(0) + + # Check result + return firmware_type.value == 2 + + +def is_secure_boot_enabled(raise_exceptions=False, show_alert=False): + """Check if Secure Boot is enabled, returns bool. + + If raise_exceptions is True then an exception is raised with details. + If show_alert is True a popup alert box is shown if it's not enabled. + """ + booted_uefi = is_booted_uefi() + cmd = ['PowerShell', '-Command', 'Confirm-SecureBootUEFI'] + enabled = False + msg_error = None + msg_warning = None + + # Bail early + if OS_VERSION < 8: + if raise_exceptions: + raise GenericWarning(f'Secure Boot not available for {OS_VERSION}') + return False + + # Check results + proc = run_program(cmd, check=False) + if proc.returncode: + # Something went wrong + if booted_uefi: + msg_warning = 'UNKNOWN' + else: + msg_warning = 'DISABLED\n\nOS installed LEGACY' + else: + # Command completed + enabled = 'True' in proc.stdout + if 'False' in proc.stdout: + msg_error = 'ERROR' + else: + msg_warning = 'UNKNOWN' + + # Show popup and/or raise exceptions as necessary + for msg, exc in ((msg_error, GenericError), (msg_warning, GenericWarning)): + if not msg: + continue + msg = f'Secure Boot {msg}' + if show_alert: + show_alert_box(msg) + if raise_exceptions: + raise exc(msg) + break + + # Done + return enabled + + # Service Functions def disable_service(service_name): """Set service startup to disabled.""" @@ -414,19 +684,5 @@ def stop_service(service_name): raise GenericError(f'Failed to stop service {service_name}') -# Date / Time functions -def get_timezone(): - """Get current timezone using tzutil, returns str.""" - cmd = ['tzutil', '/g'] - proc = run_program(cmd, check=False) - return proc.stdout - - -def set_timezone(zone): - """Set current timezone using tzutil.""" - cmd = ['tzutil', '/s', zone] - run_program(cmd, check=False) - - if __name__ == '__main__': print("This file is not meant to be called directly.") diff --git a/scripts/wk/repairs/__init__.py b/scripts/wk/repairs/__init__.py index cbdf27e4..724c52c0 100644 --- a/scripts/wk/repairs/__init__.py +++ b/scripts/wk/repairs/__init__.py @@ -4,4 +4,4 @@ import platform if platform.system() == 'Windows': - from wk.repairs import win + from . import win diff --git a/scripts/wk/repairs/win.py b/scripts/wk/repairs/win.py index 7ed64ffc..b478eafd 100644 --- a/scripts/wk/repairs/win.py +++ b/scripts/wk/repairs/win.py @@ -33,17 +33,6 @@ from wk.kit.tools import ( run_tool, ) from wk.log import format_log_path, update_log_path -from wk.os.win import ( - get_timezone, - set_timezone, - reg_delete_value, - reg_read_value, - reg_set_value, - reg_write_settings, - disable_service, - enable_service, - stop_service, - ) from wk.std import ( GenericError, GenericWarning, @@ -62,6 +51,34 @@ from wk.std import ( sleep, strip_colors, ) +if platform.system() == 'Windows': + from wk.os.win import ( + OS_VERSION, + get_timezone, + set_timezone, + reg_delete_value, + reg_read_value, + reg_set_value, + reg_write_settings, + disable_service, + enable_service, + stop_service, + ) +else: + # Workaround to allow basic testing under non-Windows environments + OS_VERSION = -1 + def no_op(*args, **kwargs): # pylint: disable=unused-argument + """No-op function.""" + # wk.os.win + get_timezone = no_op + set_timezone = no_op + reg_delete_value = no_op + reg_read_value = no_op + reg_set_value = no_op + reg_write_settings = no_op + disable_service = no_op + enable_service = no_op + stop_service = no_op # STATIC VARIABLES @@ -215,17 +232,6 @@ def build_menus(base_menus, title): def end_session(): """End Auto Repairs session.""" - # Delete Auto Repairs keys - try: - reg_delete_value('HKCU', AUTO_REPAIR_KEY, 'SessionStarted') - except FileNotFoundError: - LOG.error('Ending repair session but session not started.') - try: - cmd = ['reg', 'delete', fr'HKCU\{AUTO_REPAIR_KEY}', '/f'] - run_program(cmd) - except CalledProcessError: - LOG.error('Failed to remote Auto Repairs session settings') - # Remove logon task cmd = [ 'schtasks', '/delete', '/f', @@ -237,20 +243,26 @@ def end_session(): LOG.error("Failed to remove scheduled task or it doesn't exist.") # Disable Autologon - if is_autologon_enabled(): + autologon_selected = reg_read_value( + 'HKCU', AUTO_REPAIR_KEY, 'Use Autologon', + ) + if autologon_selected and is_autologon_enabled(): run_tool('Sysinternals', 'Autologon', download=True) reg_set_value( 'HKLM', r'Software\Microsoft\Windows NT\CurrentVersion\Winlogon', 'AutoAdminLogon', '0', 'SZ', ) - reg_delete_value( - 'HKLM', r'Software\Microsoft\Windows NT\CurrentVersion\Winlogon', - 'DefaultUserName', - ) - reg_delete_value( - 'HKLM', r'Software\Microsoft\Windows NT\CurrentVersion\Winlogon', - 'DefaultDomainName', - ) + + # Delete Auto Repairs keys + try: + reg_delete_value('HKCU', AUTO_REPAIR_KEY, 'SessionStarted') + except FileNotFoundError: + LOG.error('Ending repair session but session not started.') + try: + cmd = ['reg', 'delete', fr'HKCU\{AUTO_REPAIR_KEY}', '/f'] + run_program(cmd) + except CalledProcessError: + LOG.error('Failed to remote Auto Repairs session settings') def get_entry_settings(group, name): @@ -283,6 +295,12 @@ def init(menus): download=True, msg_good='DONE', ) + # Check if autologon is needed + if not session_started and is_autologon_enabled(): + # Avoid running Autologon and keep current settings + menus['Options'].options['Use Autologon']['Selected'] = False + save_selection_settings(menus) + # Start or resume a repair session if session_started: load_settings(menus) @@ -427,6 +445,10 @@ def run_auto_repairs(base_menus): save_selection_settings(menus) print_info('Initializing...') init_run(menus['Options'].options) + reg_set_value( + 'HKCU', AUTO_REPAIR_KEY, 'Use Autologon', + int(is_autologon_enabled()), 'DWORD', + ) if not is_autologon_enabled(): # Either it wasn't selected or a password wasn't entered menus['Options'].options['Use Autologon']['Selected'] = False @@ -820,8 +842,11 @@ def auto_restore_uac_defaults(group, name): def auto_set_custom_power_plan(group, name): - """Set to a custom power plan.""" - result = TRY_PRINT.run('Set Custom Power Plan...', create_custom_power_plan) + """Set custom power plan.""" + result = TRY_PRINT.run( + 'Set Custom Power Plan...', create_custom_power_plan, + keep_display_on=True, + ) save_settings(group, name, result=result) @@ -832,7 +857,7 @@ def auto_sfc(group, name): def auto_system_restore_create(group, name): - """Create a System Restore point.""" + """Create System Restore point.""" result = TRY_PRINT.run( 'Create System Restore...', create_system_restore_point, ) @@ -915,6 +940,16 @@ def backup_browser_chromium(backup_path, browser, search_path, use_try_print): if not match: continue output_path = backup_path.joinpath(f'{browser}-{item.name}.7z') + if output_path.exists(): + # Assuming backup was already done + if use_try_print: + show_data( + f'{" "*8}{browser} ({item.name})...', 'Backup already exists.', + color='YELLOW', width=WIDTH, + ) + continue + + # Backup data cmd = [ *BACKUP_BROWSER_BASE_CMD, output_path, item.joinpath('*'), '-x!*Cache*', '-x!Service Worker', @@ -931,6 +966,18 @@ def backup_browser_chromium(backup_path, browser, search_path, use_try_print): def backup_browser_firefox(backup_path, search_path, use_try_print): """Backup Firefox browser profile.""" output_path = backup_path.joinpath('Firefox.7z') + + # Bail early + if output_path.exists(): + # Assuming backup was already done + if use_try_print: + show_data( + f'{" "*8}Firefox (All)...', 'Backup already exists.', + color='YELLOW', width=WIDTH, + ) + return + + # Backup data cmd = [ *BACKUP_BROWSER_BASE_CMD, output_path, search_path.joinpath('Profiles'), search_path.joinpath('profiles.ini'), @@ -974,7 +1021,14 @@ def backup_registry(): """Backup Registry.""" backup_path = set_backup_path('Registry', date=True) backup_path.parent.mkdir(parents=True, exist_ok=True) - run_tool('Erunt', 'ERUNT', backup_path, 'sysreg', 'curuser', 'otherusers') + + # Check if backup was already done today + if backup_path.exists(): + raise GenericWarning('Backup already exists.') + + # Backup registry + extract_tool('ERUNT') + run_tool('ERUNT', 'ERUNT', backup_path, 'sysreg', 'curuser', 'otherusers') def delete_registry_null_keys(): @@ -1033,8 +1087,8 @@ def run_bleachbit(cleaners, preview=True): proc = run_tool('BleachBit', 'bleachbit_console', *cmd_args, cbin=True) # Save logs - log_path.write_text(proc.stdout) - log_path.with_suffix('.err').write_text(proc.stderr) + log_path.write_text(proc.stdout, encoding='utf-8') + log_path.with_suffix('.err').write_text(proc.stderr, encoding='utf-8') def run_emsisoft_cmd_scan(): @@ -1102,7 +1156,7 @@ def run_kvrt(): download_tool('KVRT', 'KVRT') kvrt_path = get_tool_path('KVRT', 'KVRT') tmp_file = fr'{os.environ.get("TMP")}\run_kvrt.cmd' - with open(tmp_file, 'w') as _f: + with open(tmp_file, 'w', encoding='utf-8') as _f: _f.write('@echo off\n') _f.write(f'"{kvrt_path}" {" ".join(cmd_args)}\n') cmd = ('cmd', '/c', tmp_file, '-new_console:nb', '-new_console:s33V') @@ -1113,7 +1167,7 @@ def run_kvrt(): # Run in background proc = run_tool('KVRT', 'KVRT', *cmd_args, download=True) - log_path.write_text(proc.stdout) + log_path.write_text(proc.stdout, encoding='utf-8') def run_mbam(): @@ -1166,7 +1220,7 @@ def run_microsoft_defender(full=True): # Run scan cmd = (defender_path, '-Scan', '-ScanType', '2' if full else '1') proc = run_program(cmd, check=False) - log_path.write_text(proc.stdout) + log_path.write_text(proc.stdout, encoding='utf-8') if proc.returncode > 0: raise GenericError('Failed to run scan or clean items.') @@ -1176,7 +1230,9 @@ def run_rkill(): log_path = format_log_path(log_name='RKill', timestamp=True, tool=True) log_path.parent.mkdir(parents=True, exist_ok=True) whitelist_path = log_path.with_suffix('.wl') - whitelist_path.write_text('\n'.join(map(str, WHITELIST))) + whitelist_path.write_text( + '\n'.join(map(str, WHITELIST)), encoding='utf-8', + ) cmd_args = ( '-l', log_path, '-w', whitelist_path, @@ -1252,7 +1308,7 @@ def update_emsisoft_cmd(): # OS Built-in Functions -def create_custom_power_plan(): +def create_custom_power_plan(keep_display_on=False): """Create new power plan and set as active.""" custom_guid = POWER_PLANS['Custom'] @@ -1272,9 +1328,10 @@ def create_custom_power_plan(): run_program(cmd) # Keep the display on - for setting in ('monitor-timeout-ac', 'monitor-timeout-dc'): - cmd = ['powercfg', '-Change', setting, '0'] - run_program(cmd) + if keep_display_on: + for setting in ('monitor-timeout-ac', 'monitor-timeout-dc'): + cmd = ['powercfg', '-Change', setting, '0'] + run_program(cmd) # Set CPU min state for arg in ('-SetacValueIndex', '-SetdcValueIndex'): @@ -1321,6 +1378,12 @@ def enable_windows_updates(): def export_power_plans(): """Export existing power plans.""" backup_path = set_backup_path('Power Plans', date=True) + + # Bail early + if backup_path.exists(): + raise GenericWarning('Backup already exists.') + + # Get powercfg data backup_path.mkdir(parents=True, exist_ok=True) cmd = ['powercfg', '/L'] proc = run_program(cmd) @@ -1530,9 +1593,9 @@ def run_sfc_scan(): # Save output os.makedirs(log_path.parent, exist_ok=True) - with open(log_path, 'a') as _f: + with open(log_path, 'a', encoding='utf-8') as _f: _f.write(proc.stdout) - with open(err_path, 'a') as _f: + with open(err_path, 'a', encoding='utf-8') as _f: _f.write(proc.stderr) # Check result diff --git a/scripts/wk/setup/__init__.py b/scripts/wk/setup/__init__.py new file mode 100644 index 00000000..3e5683bb --- /dev/null +++ b/scripts/wk/setup/__init__.py @@ -0,0 +1,8 @@ +"""WizardKit: repairs module init""" +# vim: sts=2 sw=2 ts=2 + +import platform + +#if platform.system() == 'Windows': +# from . import win +from . import win diff --git a/scripts/wk/setup/win.py b/scripts/wk/setup/win.py new file mode 100644 index 00000000..ef6e36c0 --- /dev/null +++ b/scripts/wk/setup/win.py @@ -0,0 +1,1094 @@ +"""WizardKit: Setup - Windows""" +# pylint: disable=too-many-lines +# vim: sts=2 sw=2 ts=2 + +import configparser +import logging +import json +import os +import platform +import re +import sys + +from wk.cfg.main import KIT_NAME_FULL +from wk.exe import kill_procs, run_program, popen_program +from wk.io import case_insensitive_path, get_path_obj +from wk.kit.tools import ( + ARCH, + download_tool, + extract_archive, + extract_tool, + find_kit_dir, + get_tool_path, + run_tool, + ) +from wk.log import format_log_path, update_log_path +from wk.std import ( + GenericError, + GenericWarning, + Menu, + TryAndPrint, + abort, + ask, + clear_screen, + color_string, + pause, + print_error, + print_info, + print_standard, + print_warning, + set_title, + show_data, + sleep, + strip_colors, + ) +if platform.system() == 'Windows': + from wk.os.win import ( + OS_VERSION, + activate_with_bios, + check_4k_alignment, + get_installed_antivirus, + get_installed_ram, + get_os_activation, + get_os_name, + get_raw_disks, + get_volume_usage, + is_activated, + is_secure_boot_enabled, + reg_set_value, + reg_write_settings, + ) + from wk.repairs.win import ( + backup_all_browser_profiles, + backup_registry, + create_custom_power_plan, + create_system_restore_point, + enable_windows_updates, + export_power_plans, + reset_power_plans, + set_system_restore_size, + ) +else: + # Workaround to allow basic testing under non-Windows environments + OS_VERSION = -1 + def no_op(*args, **kwargs): # pylint: disable=unused-argument + """No-op function.""" + # wk.os.win + activate_with_bios = no_op + check_4k_alignment = no_op + get_installed_antivirus = no_op + get_installed_ram = no_op + get_os_activation = no_op + get_os_name = no_op + get_raw_disks = no_op + get_volume_usage = no_op + is_activated = no_op + is_secure_boot_enabled = no_op + reg_read_value = no_op + reg_set_value = no_op + reg_write_settings = no_op + # wk.repairs.win + backup_all_browser_profiles = no_op + backup_registry = no_op + create_custom_power_plan = no_op + create_system_restore_point = no_op + enable_windows_updates = no_op + export_power_plans = no_op + reset_power_plans = no_op + set_system_restore_size = no_op + + +# STATIC VARIABLES +LOG = logging.getLogger(__name__) +BROWSER_PATHS = { + # Relative to PROGRAMFILES_64, PROGRAMFILES_32, LOCALAPPDATA (in that order) + 'Google Chrome': 'Google/Chrome/Application/chrome.exe', + 'Mozilla Firefox': 'Mozilla Firefox/firefox.exe', + 'Microsoft Edge': 'Microsoft/Edge/Application/msedge.exe', + 'Opera': 'Opera/launcher.exe', + } +CONEMU_EXE = get_tool_path('ConEmu', 'ConEmu', check=False) +IN_CONEMU = 'ConEmuPID' in os.environ +LIBREOFFICE_XCU_DATA = ''' + +Impress MS PowerPoint 2007 XML +Calc MS Excel 2007 XML +MS Word 2007 XML +false + +''' +MENU_PRESETS = Menu() +PROGRAMFILES_32 = os.environ.get( + 'PROGRAMFILES(X86)', os.environ.get( + 'PROGRAMFILES', r'C:\Program Files (x86)', + ), + ) +PROGRAMFILES_64 = os.environ.get( + 'PROGRAMW6432', os.environ.get( + 'PROGRAMFILES', r'C:\Program Files', + ), + ) +REG_CHROME_UBLOCK_ORIGIN = { + 'HKLM': { + r'Software\Google\Chrome\Extensions\cjpalhdlnbpafiamejdnhcphjbkeiagm': ( + ('update_url', 'https://clients2.google.com/service/update2/crx', 'SZ', '32'), + ) + }, + } +REG_WINDOWS_EXPLORER = { + # pylint: disable=line-too-long + 'HKLM': { + # Disable Location Tracking + r'Software\Microsoft\Windows NT\CurrentVersion\Sensor\Overrides\{BFA794E4-F964-4FDB-90F6-51056BFE4B44}': ( + ('SensorPermissionState', 0, 'DWORD'), + ), + r'System\CurrentControlSet\Services\lfsvc\Service\Configuration': ( + ('Status', 0, 'DWORD'), + ), + # Disable Telemetry + r'Software\Microsoft\Windows\CurrentVersion\Policies\DataCollection': ( + ('AllowTelemetry', 0, 'DWORD'), + ('AllowTelemetry', 0, 'DWORD', '32'), + ), + r'Software\Policies\Microsoft\Windows\DataCollection': ( + ('AllowTelemetry', 0, 'DWORD'), + ), + # Disable Wi-Fi Sense + r'Software\Microsoft\PolicyManager\default\WiFi\AllowWiFiHotSpotReporting': ( + ('Value', 0, 'DWORD'), + ), + r'Software\Microsoft\PolicyManager\default\WiFi\AllowAutoConnectToWiFiSenseHotspots': ( + ('Value', 0, 'DWORD'), + ), + }, + 'HKCU': { + # Desktop theme (<= v1809 default) + r'Software\Microsoft\Windows\CurrentVersion\Themes\Personalize': { + ('AppsUseLightTheme', 1, 'DWORD'), + ('SystemUsesLightTheme', 0, 'DWORD'), + }, + # Disable features + r'Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager': { + ('SilentInstalledAppsEnabled', 0, 'DWORD'), + # Tips and Tricks + ('SoftLandingEnabled ', 0, 'DWORD'), + ('SubscribedContent-338389Enabled', 0, 'DWORD'), + }, + # File Explorer + r'Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced': { + # Change default Explorer view to "Computer" + ('LaunchTo', 1, 'DWORD'), + ('SeparateProcess', 1, 'DWORD'), + }, + # Hide People bar + r'Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People': { + ('PeopleBand', 0, 'DWORD'), + }, + # Hide Search button / box + r'Software\Microsoft\Windows\CurrentVersion\Search': { + ('SearchboxTaskbarMode', 1, 'DWORD'), + }, + }, + } +REG_OPEN_SHELL_SETTINGS = { + 'HKCU': { + r'Software\OpenShell\StartMenu': ( + ('ShowedStyle2', 1, 'DWORD'), + ), + r'Software\OpenShell\StartMenu\Settings': ( + ('MenuStyle', 'Win7', 'SZ'), + ('RecentPrograms', 'Recent', 'SZ'), + ('SkinW7', 'Fluent-Metro', 'SZ'), + ('SkinVariationW7', '', 'SZ'), + ('SkipMetro', 1, 'DWORD'), + ( + 'SkinOptionsW7', + [ + # NOTE: Seems to need all options specified to work? + 'DARK_MAIN=1', 'METRO_MAIN=0', 'LIGHT_MAIN=0', 'AUTOMODE_MAIN=0', + 'DARK_SUBMENU=0', 'METRO_SUBMENU=0', 'LIGHT_SUBMENU=0', 'AUTOMODE_SUBMENU=1', + 'SUBMENU_SEPARATORS=1', 'DARK_SEARCH=0', 'METRO_SEARCH=0', 'LIGHT_SEARCH=1', + 'AUTOMODE_SEARCH=0', 'SEARCH_FRAME=1', 'SEARCH_COLOR=0', 'SMALL_SEARCH=0', + 'MODERN_SEARCH=1', 'SEARCH_ITALICS=0', 'NONE=0', 'SEPARATOR=0', + 'TWO_TONE=1', 'CLASSIC_SELECTOR=1', 'HALF_SELECTOR=0', 'CURVED_MENUSEL=1', + 'CURVED_SUBMENU=0', 'SELECTOR_REVEAL=0', 'TRANSPARENT=0', 'OPAQUE_SUBMENU=1', + 'OPAQUE_MENU=0', 'OPAQUE=0', 'STANDARD=1', 'SMALL_MAIN2=0', + 'SMALL_ICONS=0', 'COMPACT_SUBMENU=0', 'PRESERVE_MAIN2=0', 'LESS_PADDING=0', + 'EXTRA_PADDING=1', '24_PADDING=0', 'LARGE_PROGRAMS=0', 'TRANSPARENT_SHUTDOWN=0', + 'OUTLINE_SHUTDOWN=0', 'BUTTON_SHUTDOWN=1', 'EXPERIMENTAL_SHUTDOWN=0', 'LARGE_FONT=0', + 'CONNECTED_BORDER=1', 'FLOATING_BORDER=0', 'LARGE_SUBMENU=0', 'LARGE_LISTS=0', + 'THIN_MAIN2=0', 'EXPERIMENTAL_MAIN2=1', 'USER_IMAGE=1', 'USER_OUTSIDE=0', + 'SCALING_USER=1', '56=0', '64=0', 'TRANSPARENT_USER=0', + 'UWP_SCROLLBAR=1', 'MODERN_SCROLLBAR=0', 'OLD_ICONS=0', 'NEW_ICONS=1', + 'SMALL_ARROWS=0', 'ICON_FRAME=0', 'SEARCH_SEPARATOR=0', 'NO_PROGRAMS_BUTTON=0', + ], + 'MULTI_SZ', + ), + ), + }, + } +REG_UAC_DEFAULTS_WIN7 = { + 'HKLM': { + r'Software\Microsoft\Windows\CurrentVersion\Policies\System': ( + ('ConsentPromptBehaviorAdmin', 5, 'DWORD'), + ('EnableLUA', 1, 'DWORD'), + ('PromptOnSecureDesktop', 1, 'DWORD'), + ), + }, + } +REG_UAC_DEFAULTS_WIN10 = { + 'HKLM': { + r'Software\Microsoft\Windows\CurrentVersion\Policies\System': ( + ('ConsentPromptBehaviorAdmin', 5, 'DWORD'), + ('ConsentPromptBehaviorUser', 3, 'DWORD'), + ('EnableInstallerDetection', 1, 'DWORD'), + ('EnableLUA', 1, 'DWORD'), + ('EnableVirtualization', 1, 'DWORD'), + ('PromptOnSecureDesktop', 1, 'DWORD'), + ), + }, + } +SYSTEMDRIVE = os.environ.get('SYSTEMDRIVE', 'C:') +WIDTH = 50 +TRY_PRINT = TryAndPrint() +TRY_PRINT.width = WIDTH +TRY_PRINT.verbose = True +for error in ('CalledProcessError', 'FileNotFoundError'): + TRY_PRINT.add_error(error) +UBLOCK_ORIGIN_URLS = { + # pylint: disable=line-too-long + 'Google Chrome': 'https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm', + 'Microsoft Edge': 'https://microsoftedge.microsoft.com/addons/detail/ublock-origin/odfafepnkmbhccpbejgmiehpchacaeak', + 'Mozilla Firefox': 'https://addons.mozilla.org/addon/ublock-origin/', + 'Opera': 'https://addons.opera.com/extensions/details/ublock/', + } + + +# Auto Setup +def build_menus(base_menus, title, presets): + """Build menus, returns dict.""" + menus = {} + menus['Main'] = Menu(title=f'{title}\n{color_string("Main Menu", "GREEN")}') + + # Main Menu + for entry in base_menus['Actions']: + menus['Main'].add_action(entry.name, entry.details) + for group in base_menus['Groups']: + menus['Main'].add_option(group, {'Selected': True}) + + # Run groups + for group, entries in base_menus['Groups'].items(): + menus[group] = Menu(title=f'{title}\n{color_string(group, "GREEN")}') + for entry in entries: + menus[group].add_option(entry.name, entry.details) + menus[group].add_action('All') + menus[group].add_action('None') + menus[group].add_action('Main Menu', {'Separator': True}) + menus[group].add_action('Quit') + + # Initialize main menu display names + menus['Main'].update() + + # Fix Function references + for group, menu in menus.items(): + if group not in base_menus['Groups']: + continue + for name in menu.options: + _function = menu.options[name]['Function'] + if isinstance(_function, str): + menu.options[name]['Function'] = getattr( + sys.modules[__name__], _function, + ) + + # Update presets + for group, entries in base_menus['Groups'].items(): + presets['Default'][group] = tuple( + entry.name for entry in entries if entry.details['Selected'] + ) + + # Update presets Menu + MENU_PRESETS.title = f'{title}\n{color_string("Load Preset", "GREEN")}' + MENU_PRESETS.add_option('Default') + for name in presets: + MENU_PRESETS.add_option(name) + MENU_PRESETS.add_action('Main Menu') + MENU_PRESETS.add_action('Quit') + MENU_PRESETS.update() + + # Done + return menus + + +def check_os_and_set_menu_title(title): + """Check OS version and update title for menus, returns str.""" + color = None + os_name = get_os_name(check=False) + print_standard(f'Operating System: {os_name}') + + # Check support status and set color + try: + get_os_name() + except GenericWarning: + # Outdated version + print_warning('OS version is outdated, updating is recommended.') + if not ask('Continue anyway?'): + abort() + color = 'YELLOW' + except GenericError: + # Unsupported version + print_error('OS version is unsupported, updating is recommended.') + if not ask('Continue anyway? (NOT RECOMMENDED)'): + abort() + color = 'RED' + + # Done + return f'{title} ({color_string(os_name, color)})' + + +def load_preset(menus, presets): + """Load menu settings from preset, returns selection (str).""" + selection = MENU_PRESETS.simple_select() + + # Exit early + if 'Main Menu' in selection: + return None + if 'Quit' in selection: + raise SystemExit + + # Load preset + preset = presets[selection[0]] + for group, menu in menus.items(): + group_enabled = group in preset + for name in menu.options: + value = group_enabled and name in preset[group] + menu.options[name]['Selected'] = value + + # Done + return selection[0] + + +def run_auto_setup(base_menus, presets): + """Run Auto Setup.""" + update_log_path(dest_name='Auto Setup', timestamp=True) + title = f'{KIT_NAME_FULL}: Auto Setup' + clear_screen() + set_title(title) + print_info(title) + print('') + print_standard('Initializing...') + + # Check OS and update title for menus + title = check_os_and_set_menu_title(title) + + # Generate menus + menus = build_menus(base_menus, title, presets) + + # Get setup preset and ask initial questions + MENU_PRESETS.actions['Main Menu'].update({'Disabled':True, 'Hidden':True}) + selection = load_preset(menus, presets) + MENU_PRESETS.actions['Main Menu'].update({'Disabled':False, 'Hidden':False}) + clear_screen() + print_standard(f'{title}') + print('') + if selection == 'Default' and ask('Install LibreOffice?'): + menus['Install Software'].options['LibreOffice']['Selected'] = True + + # Show Menu + show_main_menu(base_menus, menus, presets) + + # Start setup + clear_screen() + print_standard(title) + print('') + print_info('Running setup') + + # Run setup + for group, menu in menus.items(): + if group in ('Main', 'Options'): + continue + try: + run_group(group, menu) + except KeyboardInterrupt: + abort() + + # Done + print_info('Done') + pause('Press Enter to exit...') + + +def run_group(group, menu): + """Run entries in group if appropriate.""" + print_info(f' {group}') + for name, details in menu.options.items(): + name_str = strip_colors(name) + + # Not selected + if not details.get('Selected', False): + show_data(f'{name_str}...', 'Skipped', 'YELLOW', width=WIDTH) + continue + + # Selected + details['Function']() + + +def show_main_menu(base_menus, menus, presets): + """Show main menu and handle actions.""" + while True: + update_main_menu(menus) + selection = menus['Main'].simple_select(update=False) + if selection[0] in base_menus['Groups'] or selection[0] == 'Options': + show_sub_menu(menus[selection[0]]) + if selection[0] == 'Load Preset': + load_preset(menus, presets) + elif 'Start' in selection: + break + elif 'Quit' in selection: + raise SystemExit + + +def show_sub_menu(menu): + """Show sub-menu and handle sub-menu actions.""" + while True: + selection = menu.advanced_select() + if 'Main Menu' in selection: + break + if 'Quit' in selection: + raise SystemExit + + # Select all or none + value = 'All' in selection + for name in menu.options: + if not menu.options[name].get('Disabled', False): + menu.options[name]['Selected'] = value + + +def update_main_menu(menus): + """Update main menu based on current selections.""" + index = 1 + skip = 'Reboot' + for name in menus['Main'].options: + checkmark = ' ' + selected = [ + _v['Selected'] for _k, _v in menus[name].options.items() if _k != skip + ] + if all(selected): + checkmark = '✓' + elif any(selected): + checkmark = '-' + display_name = f' {index}: [{checkmark}] {name}' + index += 1 + menus['Main'].options[name]['Display Name'] = display_name + + +# Auto Repairs: Wrapper Functions +def auto_backup_registry(): + """Backup registry.""" + TRY_PRINT.run('Backup Registry...', backup_registry) + + +def auto_backup_browser_profiles(): + """Backup browser profiles.""" + backup_all_browser_profiles(use_try_print=True) + + +def auto_backup_power_plans(): + """Backup power plans.""" + TRY_PRINT.run('Backup Power Plans...', export_power_plans) + + +def auto_reset_power_plans(): + """Reset power plans.""" + TRY_PRINT.run('Reset Power Plans...', reset_power_plans) + + +def auto_set_custom_power_plan(): + """Set custom power plan.""" + TRY_PRINT.run('Set Custom Power Plan...', create_custom_power_plan) + + +def auto_enable_bsod_minidumps(): + """Enable saving minidumps during BSoDs.""" + TRY_PRINT.run('Enable BSoD mini dumps...', enable_bsod_minidumps) + + +def auto_enable_regback(): + """Enable RegBack.""" + TRY_PRINT.run( + 'Enable RegBack...', reg_set_value, 'HKLM', + r'System\CurrentControlSet\Control\Session Manager\Configuration Manager', + 'EnablePeriodicBackup', 1, 'DWORD', + ) + + +def auto_system_restore_enable(): + """Enable System Restore.""" + cmd = [ + 'powershell', '-Command', 'Enable-ComputerRestore', + '-Drive', SYSTEMDRIVE, + ] + TRY_PRINT.run('Enable System Restore...', run_program, cmd=cmd) + + +def auto_system_restore_set_size(): + """Set System Restore size.""" + TRY_PRINT.run('Set System Restore Size...', set_system_restore_size) + + +def auto_system_restore_create(): + """Create System Restore point.""" + TRY_PRINT.run('Create System Restore...', create_system_restore_point) + + +def auto_windows_updates_enable(): + """Enable Windows Updates.""" + TRY_PRINT.run('Enable Windows Updates...', enable_windows_updates) + + +# Auto Setup: Wrapper Functions +def auto_activate_windows(): + """Attempt to activate Windows using BIOS key.""" + TRY_PRINT.run('Windows Activation...', activate_with_bios) + + +def auto_config_browsers(): + """Configure Browsers.""" + prompt = ' Press Enter to continue...' + TRY_PRINT.run('Chrome Notifications...', disable_chrome_notifications) + TRY_PRINT.run( + 'uBlock Origin...', enable_ublock_origin, msg_good='STARTED', + ) + TRY_PRINT.run( + 'Set default browser...', set_default_browser, msg_good='STARTED', + ) + print(prompt, end='', flush=True) + pause('') + + # Move cursor to beginning of the previous line and clear prompt + print(f'\033[F\r{" "*len(prompt)}\r', end='', flush=True) + + +def auto_config_explorer(): + """Configure Windows Explorer and restart the process.""" + TRY_PRINT.run('Windows Explorer...', config_explorer) + + +def auto_config_open_shell(): + """Configure Open Shell.""" + TRY_PRINT.run('Open Shell...', reg_write_settings, REG_OPEN_SHELL_SETTINGS) + + +def auto_export_aida64_report(): + """Export AIDA64 reports.""" + TRY_PRINT.run('AIDA64 Report...', export_aida64_report) + + +def auto_install_firefox(): + """Install Firefox.""" + TRY_PRINT.run('Firefox...', install_firefox) + + +def auto_install_libreoffice(): + """Install LibreOffice. + + NOTE: It is assumed that auto_install_vcredists() will be run + before this function to satisfy the vcredist=False usage. + """ + TRY_PRINT.run('LibreOffice...', install_libreoffice, vcredist=False) + + +def auto_install_open_shell(): + """Install Open Shell.""" + TRY_PRINT.run('Open Shell...', install_open_shell) + + +def auto_install_software_bundle(): + """Install standard software bundle.""" + TRY_PRINT.run('Software Bundle...', install_software_bundle) + + +def auto_install_vcredists(): + """Install latest supported Visual C++ runtimes.""" + TRY_PRINT.run('Visual C++ Runtimes...', install_vcredists) + + +def auto_open_device_manager(): + """Open Device Manager.""" + TRY_PRINT.run('Device Manager...', open_device_manager) + + +def auto_open_hwinfo_sensors(): + """Open HWiNFO Sensors.""" + TRY_PRINT.run('HWiNFO Sensors...', open_hwinfo_sensors) + + +def auto_open_windows_activation(): + """Open Windows Activation.""" + if not is_activated(): + TRY_PRINT.run('Windows Activation...', open_windows_activation) + + +def auto_open_windows_updates(): + """Open Windows Updates.""" + TRY_PRINT.run('Windows Updates...', open_windows_updates) + + +def auto_open_xmplay(): + """Open XMPlay.""" + TRY_PRINT.run('XMPlay...', open_xmplay) + + +def auto_restore_default_uac(): + """Restore default UAC settings.""" + TRY_PRINT.run('User Account Control...', restore_default_uac) + + +def auto_show_4k_alignment_check(): + """Display 4K alignment check.""" + TRY_PRINT.run('4K alignment Check...', check_4k_alignment, show_alert=True) + + +def auto_show_installed_antivirus(): + """Display installed antivirus.""" + TRY_PRINT.run('Virus Protection...', get_installed_antivirus) + + +def auto_show_installed_ram(): + """Display installed RAM.""" + TRY_PRINT.run('Installed RAM...', get_installed_ram, + as_list=True, raise_exceptions=True, + ) + + +def auto_show_os_activation(): + """Display OS activation status.""" + TRY_PRINT.run('Activation...', get_os_activation, as_list=True) + + +def auto_show_os_name(): + """Display OS Name.""" + TRY_PRINT.run('Operating System...', get_os_name, as_list=True) + + +def auto_show_secure_boot_status(): + """Display Secure Boot status.""" + TRY_PRINT.run( + 'Secure Boot...', is_secure_boot_enabled, + raise_exceptions=True, show_alert=True, + ) + + +def auto_show_storage_status(): + """Display storage status.""" + TRY_PRINT.run('Storage Status...', get_storage_status) + + +def auto_windows_temp_fix(): + """Restore default ACLs for Windows\\Temp.""" + TRY_PRINT.run(r'Windows\Temp fix...', fix_windows_temp) + + +# Configure Functions +def config_explorer(): + """Configure Windows Explorer and restart the process.""" + reg_write_settings(REG_WINDOWS_EXPLORER) + kill_procs('explorer.exe', force=True) + popen_program(['explorer.exe']) + + +def disable_chrome_notifications(): + """Disable notifications in Google Chrome.""" + defaults_key = 'default_content_setting_values' + profiles = [] + search_path = case_insensitive_path( + f'{os.environ.get("LOCALAPPDATA")}/Google/Chrome/User Data', + ) + + # Bail early + if not search_path: + raise GenericWarning('No profiles detected.') + + # Close any running instances of Chrome + kill_procs('chrome.exe', force=True) + + # Build list of profiles + for item in search_path.iterdir(): + if not item.is_dir(): + continue + + if re.match(r'^(Default|Profile).*', item.name, re.IGNORECASE): + profiles.append(item) + + # Bail if no profiles were detected + if not profiles: + raise GenericWarning('No profiles detected.') + + # Set notifications preference + for profile in profiles: + pref_file = profile.joinpath('Preferences') + if not pref_file.exists(): + continue + + # Update config + pref_data = json.loads(pref_file.read_text()) + if defaults_key not in pref_data['profile']: + pref_data['profile'][defaults_key] = {} + pref_data['profile'][defaults_key]['notifications'] = 2 + + # Save file + pref_file.write_text(json.dumps(pref_data, separators=(',', ':'))) + + +def enable_bsod_minidumps(): + """Enable saving minidumps during BSoDs.""" + cmd = ['wmic', 'RECOVEROS', 'set', 'DebugInfoType', '=', '3'] + run_program(cmd) + + +def enable_ublock_origin(): + """Enable uBlock Origin in supported browsers.""" + base_paths = [ + PROGRAMFILES_64, PROGRAMFILES_32, os.environ.get('LOCALAPPDATA'), + ] + cmds = [] + + # Add Google Chrome registry entries + reg_write_settings(REG_CHROME_UBLOCK_ORIGIN) + + # Build cmds list + for browser, rel_path in BROWSER_PATHS.items(): + browser_path = None + for base_path in base_paths: + try: + browser_path = case_insensitive_path(f'{base_path}/{rel_path}') + except FileNotFoundError: + # Ignore missing browsers + continue + else: + # Found a match, skip checking the rest + break + if browser_path: + cmds.append([browser_path, UBLOCK_ORIGIN_URLS[browser]]) + + # Open detected browsers + for cmd in cmds: + popen_program(cmd) + + +def fix_windows_temp(): + """Restore default permissions for Windows\\Temp.""" + permissions = ( + 'Users:(CI)(X,WD,AD)', + 'Administrators:(OI)(CI)(F)', + ) + for _p in permissions: + cmd = ['icacls', fr'{SYSTEMDRIVE}\Windows\Temp', '/grant:r', _p, '/T'] + run_program(cmd) + + +def restore_default_uac(): + """Restore default UAC settings.""" + settings = REG_UAC_DEFAULTS_WIN10 + if OS_VERSION != 10: + settings = REG_UAC_DEFAULTS_WIN7 + + reg_write_settings(settings) + + +# Install Functions +def install_firefox(): + """Install Firefox. + + As far as I can tell if you use the EXE installers then it will use + the same installation directory as the installed version. As such a + 32-bit installation could be upgraded to a 64-bit one and still use + %PROGRAMFILES(X86)% However, if a 64-bit MSI installer is used then + it ignores the 32-bit directory and just installs a new copy to + %PROGRAMFILES% resulting in two copies of Firefox to be in place. + To address this issue this function will uninstall all copies of + Firefox under 64-bit Windows if it's detected in %PROGRAMFILES(X86)% + before installing the latest 64-bit version. + + Firefox 67 changed how profiles are named to avoid reusing the same + profile between different channels of Firefox (std, beta, ESR, etc). + However the logic used when upgrading from versions before 67 to + current isn't ideal. It can, but doesn't always?, create a new + profile and set it as default; even if there's an existing profile + being used. To address this profiles.ini is read to compare with the + post-install/upgrade state. If the default is changed to a new + profile then it is reverted so the original existing profile instead. + """ + current_default_profile = None + firefox_exe = f'{os.environ["PROGRAMFILES"]}/Mozilla Firefox/firefox.exe' + profiles_ini = case_insensitive_path( + f'{os.environ["APPDATA"]}/Mozilla/Firefox/profiles.ini', + ) + program_path_32bit_exists = False + try: + case_insensitive_path( + f'{PROGRAMFILES_32}/Mozilla Firefox/firefox.exe', + ) + except FileNotFoundError: + # Ignore + pass + else: + program_path_32bit_exists = True + revert_default = False + + # Save current default profile + if profiles_ini.exists(): + current_default_profile = get_firefox_default_profile(profiles_ini) + + # Uninstall Firefox if needed + if ARCH == '64' and program_path_32bit_exists: + uninstall_firefox() + + # Install Firefox + run_tool('Firefox', 'Firefox', '/S', download=True) + + # Open Firefox to force profiles.ini update + popen_program(firefox_exe) + sleep(5) + kill_procs('firefox.exe', force=True) + + # Check if default profile changed + if current_default_profile: + new_default = get_firefox_default_profile(profiles_ini) + revert_default = new_default and new_default != current_default_profile + + # Revert default profile if needed + if revert_default: + out = [] + for line in profiles_ini.read_text(encoding='utf-8').splitlines(): + if 'Default=Profile' in line: + out.append(f'Default={current_default_profile}') + else: + out.append(line) + profiles_ini.write_text('\n'.join(out), encoding='utf-8') + + +def install_libreoffice( + register_mso_types=True, use_mso_formats=False, vcredist=True): + """Install LibreOffice.""" + installer = find_kit_dir('Installers').joinpath('LibreOffice.msi') + xcu_dir = get_path_obj(f'{os.environ.get("APPDATA")}/LibreOffice/4/user') + xcu_file = xcu_dir.joinpath('registrymodifications.xcu') + + # Set default save formats to MSO types + if use_mso_formats and not xcu_file.exists(): + xcu_dir.mkdir(parents=True, exist_ok=True) + with open(xcu_file, 'w', encoding='utf-8', newline='\n') as _f: + _f.write(LIBREOFFICE_XCU_DATA) + + # Build cmd + cmd = [ + 'msiexec', '/passive', '/norestart', + '/i', installer, + 'REBOOTYESNO=No', + f'VC_REDIST={1 if vcredist else 0}', + ] + if register_mso_types: + cmd.append('REGISTER_ALL_MSO_TYPES=1') + else: + cmd.append('REGISTER_NO_MSO_TYPES=1') + + # Install LibreOffice + run_program(cmd) + + +def install_open_shell(): + """Install Open Shell (just the Start Menu).""" + installer = get_tool_path('OpenShell', 'OpenShell', check=False) + + # Bail early + if OS_VERSION != 10: + raise GenericWarning('Unsupported OS') + + # Install OpenShell + download_tool('OpenShell', 'OpenShell') + download_tool('OpenShell', 'Fluent-Metro', suffix='zip') + cmd = [installer, '/qn', 'ADDLOCAL=StartMenu'] + run_program(cmd) + + # Install Skin + skin_zip = installer.with_name('Fluent-Metro.zip') + extract_archive(skin_zip, f'{PROGRAMFILES_64}/Open-Shell/Skins', '-aoa') + + # Add scheduled task to handle OS upgrades + cmd = ['schtasks', '/query', '/tn', 'Open-Shell OS upgrade check'] + proc = run_program(cmd, check=False) + if proc.returncode == 0: + # Task already exists, bail and leave current task unmodified + return + cmd = [ + 'schtasks', '/create', + '/ru', r'NT AUTHORITY\SYSTEM', + '/sc', 'ONSTART', + '/tn', 'Open-Shell OS upgrade check', + '/tr', r'"%PROGRAMFILES%\Open-Shell\StartMenu.exe" -upgrade -silent', + ] + run_program(cmd) + + +def install_software_bundle(): + """Install standard software bundle.""" + download_tool('Ninite', 'Software Bundle') + installer = get_tool_path('Ninite', 'Software Bundle') + msg = 'Waiting for installations to finish...' + warning = 'NOTE: Press CTRL+c to manually resume if it gets stuck...' + + # Start installations and wait for them to finish + print_standard(msg) + print_warning(warning, end='', flush=True) + proc = popen_program([installer]) + try: + proc.wait() + except KeyboardInterrupt: + # Assuming user-forced continue + pass + + # Clear info lines + print( + '\r\033[0K' # Cursor to start of current line and clear to end of line + '\033[F\033[54C' # Cursor to start of prev line and then move 54 right + '\033[0K', # Clear from cursor to end of line + end='', flush=True) + + +def install_vcredists(): + """Install latest supported Visual C++ runtimes.""" + for year in (2012, 2013, 2019): + cmd_args = ['/install', '/passive', '/norestart'] + if year == 2012: + cmd_args.pop(0) + name = f'VCRedist_{year}_x32' + download_tool('VCRedist', name) + installer = get_tool_path('VCRedist', name) + run_program([installer, *cmd_args]) + if ARCH == '64': + name = f'{name[:-2]}64' + download_tool('VCRedist', name) + installer = get_tool_path('VCRedist', name) + run_program([installer, *cmd_args]) + + +def uninstall_firefox(): + """Uninstall all copies of Firefox.""" + json_file = format_log_path(log_name='Installed Programs', timestamp=True) + json_file = json_file.with_name(f'{json_file.stem}.json') + uninstall_data = None + + # Get uninstall_data from UninstallView + extract_tool('UninstallView') + cmd = [get_tool_path('UninstallView', 'UninstallView'), '/sjson', json_file] + run_program(cmd) + with open(json_file, 'rb') as _f: + uninstall_data = json.load(_f) + + # Uninstall Firefox if found + for item in uninstall_data: + if item['Display Name'].lower().startswith('mozilla firefox'): + uninstaller = item['Uninstall String'].replace('"', '') + run_program([uninstaller, '/S']) + + +# Misc Functions +def get_firefox_default_profile(profiles_ini): + """Get Firefox default profile, returns pathlib.Path or None.""" + default_profile = None + parser = None + + # Bail early + if not profiles_ini.exists(): + return None + + # Parse INI + parser = configparser.ConfigParser() + parser.read(profiles_ini) + for section in parser.sections(): + if section.lower().startswith('install'): + default_profile = parser[section].get('default') + break + value = parser[section].get('default') + if value and value == '1': + default_profile = parser[section].get('path') + + # Done + return default_profile + + +def get_storage_status(): + """Get storage status for fixed disks, returns list.""" + report = get_volume_usage(use_colors=True) + for disk in get_raw_disks(): + report.append(color_string(f'Uninitialized Disk: {disk}', 'RED')) + + # Done + return report + + +def set_default_browser(): + """Open Windows Settings to the default apps section.""" + cmd = ['start', '', 'ms-settings:defaultapps'] + popen_program(cmd, shell=True) + + +# Tool Functions +def export_aida64_report(): + """Export AIDA64 report.""" + report_path = format_log_path( + log_name='AIDA64 System Report', + tool=True, timestamp=True, + ) + report_path = report_path.with_suffix('.html') + report_path.parent.mkdir(parents=True, exist_ok=True) + + # Run AIDA64 and check result + proc = run_tool( + 'AIDA64', 'aida64', + '/R', report_path, + '/CUSTOM', 'basic.rpf', + '/HTML', '/SILENT', '/SAFEST', + cbin=True, cwd=True) + if proc.returncode: + raise GenericError('Error(s) encountered exporting report.') + + +def open_device_manager(): + """Open Device Manager.""" + popen_program(['mmc', 'devmgmt.msc']) + + +def open_hwinfo_sensors(): + """Open HWiNFO sensors.""" + hwinfo_path = get_tool_path('HWiNFO', 'HWiNFO') + base_config = hwinfo_path.with_name('general.ini') + + # Write new config to disk + with open(hwinfo_path.with_suffix('.ini'), 'w', encoding='utf-8') as _f: + _f.write( + f'{base_config.read_text(encoding="utf-8")}\n' + 'SensorsOnly=1\nSummaryOnly=0\n' + ) + + # Open HWiNFO + run_tool('HWiNFO', 'HWiNFO', popen=True) + + +def open_windows_activation(): + """Open Windows Activation.""" + popen_program(['slui']) + + +def open_windows_updates(): + """Open Windows Updates.""" + popen_program(['control', '/name', 'Microsoft.WindowsUpdate']) + + +def open_xmplay(): + """Open XMPlay.""" + sleep(2) + run_tool('XMPlay', 'XMPlay', 'music.7z', cbin=True, cwd=True, popen=True) + + +if __name__ == '__main__': + print("This file is not meant to be called directly.") diff --git a/scripts/wk/std.py b/scripts/wk/std.py index 5a3adc0c..6f994bc7 100644 --- a/scripts/wk/std.py +++ b/scripts/wk/std.py @@ -442,10 +442,11 @@ class TryAndPrint(): pass # Prepend exception name - try: - message = f'{_exception.__class__.__name__}: {message}' - except Exception: # pylint: disable=broad-except - message = f'UNKNOWN ERROR: {message}' + if _exception.__class__.__name__ not in ('GenericError', 'GenericWarning'): + try: + message = f'{_exception.__class__.__name__}: {message}' + except Exception: # pylint: disable=broad-except + message = f'UNKNOWN ERROR: {message}' # Fix multi-line messages if '\n' in message: @@ -525,8 +526,8 @@ class TryAndPrint(): return obj # Try all modules - for _mod in sys.modules: - obj = getattr(sys.modules[_mod], name, None) + for _mod in sys.modules.values(): + obj = getattr(_mod, name, None) if obj: break @@ -588,11 +589,11 @@ class TryAndPrint(): verbose, ) f_exception = None - catch_all = catch_all if catch_all else self.catch_all - msg_good = msg_good if msg_good else self.msg_good + catch_all = catch_all if catch_all is not None else self.catch_all + msg_good = msg_good if msg_good is not None else self.msg_good output = None result_msg = 'UNKNOWN' - verbose = verbose if verbose else self.verbose + verbose = verbose if verbose is not None else self.verbose # Build exception tuples e_exceptions = tuple(self._get_exception(e) for e in self.list_errors) @@ -802,7 +803,7 @@ def generate_debug_report(): if log_path: report.append('------ Start Log -------') report.append('') - with open(log_path, 'r') as log_file: + with open(log_path, 'r', encoding='utf-8') as log_file: report.extend(log_file.read().splitlines()) report.append('') report.append('------- End Log --------') diff --git a/scripts/wk/sw/__init__.py b/scripts/wk/sw/__init__.py deleted file mode 100644 index 1cc6236f..00000000 --- a/scripts/wk/sw/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""WizardKit: sw module init""" diff --git a/setup/windows/cbin/_include/AIDA64/basic.rpf b/setup/windows/cbin/_include/AIDA64/basic.rpf new file mode 100644 index 00000000..c3bc9648 --- /dev/null +++ b/setup/windows/cbin/_include/AIDA64/basic.rpf @@ -0,0 +1,35 @@ +InfoPage="Computer;Summary" +InfoPage="Computer;Computer Name" +InfoPage="Computer;DMI" +InfoPage="Computer;IPMI" +InfoPage="Computer;Overclock" +InfoPage="Computer;Power Management" +InfoPage="Motherboard;CPU" +InfoPage="Motherboard;Motherboard" +InfoPage="Motherboard;Memory" +InfoPage="Motherboard;SPD" +InfoPage="Motherboard;Chipset" +InfoPage="Motherboard;BIOS" +InfoPage="Operating System;Operating System" +InfoPage="Server;Users" +InfoPage="Storage;Windows Storage" +InfoPage="Storage;Logical Drives" +InfoPage="Storage;Physical Drives" +InfoPage="Storage;Optical Drives" +InfoPage="Storage;ASPI" +InfoPage="Storage;ATA" +InfoPage="Storage;SMART" +InfoPage="Network;Windows Network" +InfoPage="Devices;Windows Devices" +InfoPage="Devices;Physical Devices" +InfoPage="Devices;PCI Devices" +InfoPage="Software;Auto Start" +InfoPage="Software;Scheduled" +InfoPage="Software;Installed Programs" +InfoPage="Software;Licenses" +InfoPage="Security;Windows Security" +InfoPage="Security;Windows Update" +InfoPage="Security;Anti-Virus" +InfoPage="Security;Firewall" +InfoPage="Security;Anti-Spyware" +InfoPage="Security;Anti-Trojan" diff --git a/setup/windows/cbin/_include/AIDA64/full.rpf b/setup/windows/cbin/_include/AIDA64/full.rpf deleted file mode 100644 index 8d7df2ad..00000000 --- a/setup/windows/cbin/_include/AIDA64/full.rpf +++ /dev/null @@ -1,98 +0,0 @@ -InfoPage="Computer;Summary" -InfoPage="Computer;Computer Name" -InfoPage="Computer;DMI" -InfoPage="Computer;IPMI" -InfoPage="Computer;Overclock" -InfoPage="Computer;Power Management" -InfoPage="Computer;Portable Computer" -InfoPage="Motherboard;CPU" -InfoPage="Motherboard;CPUID" -InfoPage="Motherboard;Motherboard" -InfoPage="Motherboard;Memory" -InfoPage="Motherboard;SPD" -InfoPage="Motherboard;Chipset" -InfoPage="Motherboard;BIOS" -InfoPage="Motherboard;ACPI" -InfoPage="Operating System;Operating System" -InfoPage="Operating System;Processes" -InfoPage="Operating System;System Drivers" -InfoPage="Operating System;Services" -InfoPage="Operating System;AX Files" -InfoPage="Operating System;DLL Files" -InfoPage="Operating System;Certificates" -InfoPage="Operating System;UpTime" -InfoPage="Server;Share" -InfoPage="Server;Opened Files" -InfoPage="Server;Account Security" -InfoPage="Server;Logon" -InfoPage="Server;Users" -InfoPage="Server;Local Groups" -InfoPage="Server;Global Groups" -InfoPage="Display;Windows Video" -InfoPage="Display;PCI / AGP Video" -InfoPage="Display;GPU" -InfoPage="Display;Monitor" -InfoPage="Display;Desktop" -InfoPage="Display;Multi-Monitor" -InfoPage="Display;Video Modes" -InfoPage="Display;OpenGL" -InfoPage="Display;GPGPU" -InfoPage="Display;Mantle" -InfoPage="Display;Vulkan" -InfoPage="Display;Fonts" -InfoPage="Multimedia;Windows Audio" -InfoPage="Multimedia;PCI / PnP Audio" -InfoPage="Multimedia;HD Audio" -InfoPage="Multimedia;OpenAL" -InfoPage="Multimedia;Audio Codecs" -InfoPage="Multimedia;Video Codecs" -InfoPage="Multimedia;MCI" -InfoPage="Multimedia;SAPI" -InfoPage="Storage;Windows Storage" -InfoPage="Storage;Logical Drives" -InfoPage="Storage;Physical Drives" -InfoPage="Storage;Optical Drives" -InfoPage="Storage;ASPI" -InfoPage="Storage;ATA" -InfoPage="Storage;SMART" -InfoPage="Network;Windows Network" -InfoPage="Network;PCI / PnP Network" -InfoPage="Network;RAS" -InfoPage="Network;Net Resources" -InfoPage="Network;IAM" -InfoPage="Network;Internet" -InfoPage="Network;Routes" -InfoPage="Network;IE Cookie" -InfoPage="Network;Browser History" -InfoPage="DirectX;DirectX Files" -InfoPage="DirectX;DirectX Video" -InfoPage="DirectX;DirectX Sound" -InfoPage="Devices;Windows Devices" -InfoPage="Devices;Physical Devices" -InfoPage="Devices;PCI Devices" -InfoPage="Devices;USB Devices" -InfoPage="Devices;Device Resources" -InfoPage="Devices;Input" -InfoPage="Devices;Printers" -InfoPage="Software;Auto Start" -InfoPage="Software;Scheduled" -InfoPage="Software;Installed Programs" -InfoPage="Software;Licenses" -InfoPage="Software;File Types" -InfoPage="Software;Desktop Gadgets" -InfoPage="Security;Windows Security" -InfoPage="Security;Windows Update" -InfoPage="Security;Anti-Virus" -InfoPage="Security;Firewall" -InfoPage="Security;Anti-Spyware" -InfoPage="Security;Anti-Trojan" -InfoPage="Config;Regional" -InfoPage="Config;Environment" -InfoPage="Config;Control Panel" -InfoPage="Config;Recycle Bin" -InfoPage="Config;System Files" -InfoPage="Config;System Folders" -InfoPage="Database;Database Software" -InfoPage="Database;BDE Drivers" -InfoPage="Database;ODBC Drivers" -InfoPage="Database;ODBC Data Sources" diff --git a/setup/windows/cbin/_include/AIDA64/installed_programs.rpf b/setup/windows/cbin/_include/AIDA64/installed_programs.rpf deleted file mode 100644 index 2d79cb30..00000000 --- a/setup/windows/cbin/_include/AIDA64/installed_programs.rpf +++ /dev/null @@ -1 +0,0 @@ -InfoPage="Software;Installed Programs" diff --git a/setup/windows/cbin/_include/AIDA64/licenses.rpf b/setup/windows/cbin/_include/AIDA64/licenses.rpf deleted file mode 100644 index 6ef298f1..00000000 --- a/setup/windows/cbin/_include/AIDA64/licenses.rpf +++ /dev/null @@ -1 +0,0 @@ -InfoPage="Software;Licenses"