Added extra line break after classes/functions/etc
* Also reordered some class/regex/static sections
This commit is contained in:
parent
3b4668e61b
commit
d0c49240d8
23 changed files with 430 additions and 92 deletions
|
|
@ -6,9 +6,11 @@ from borrowed import acpi
|
|||
from functions.common import *
|
||||
from os import environ
|
||||
|
||||
# Variables
|
||||
|
||||
# STATIC VARIABLES
|
||||
SLMGR = r'{}\System32\slmgr.vbs'.format(environ.get('SYSTEMROOT'))
|
||||
|
||||
|
||||
def activate_with_bios():
|
||||
"""Attempt to activate Windows with a key stored in the BIOS."""
|
||||
# Code borrowed from https://github.com/aeruder/get_win8key
|
||||
|
|
@ -43,6 +45,7 @@ def activate_with_bios():
|
|||
if not windows_is_activated():
|
||||
raise Exception('Activation Failed')
|
||||
|
||||
|
||||
def get_activation_string():
|
||||
"""Get activation status, returns str."""
|
||||
act_str = subprocess.run(
|
||||
|
|
@ -53,6 +56,7 @@ def get_activation_string():
|
|||
act_str = act_str[1].strip()
|
||||
return act_str
|
||||
|
||||
|
||||
def windows_is_activated():
|
||||
"""Check if Windows is activated via slmgr.vbs and return bool."""
|
||||
activation_string = subprocess.run(
|
||||
|
|
@ -62,6 +66,7 @@ def windows_is_activated():
|
|||
|
||||
return bool(activation_string and 'permanent' in activation_string)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import ctypes
|
|||
|
||||
from functions.disk import *
|
||||
|
||||
|
||||
# Regex
|
||||
REGEX_BAD_PATH_NAMES = re.compile(
|
||||
r'([<>:"/\|\?\*]'
|
||||
|
|
@ -12,6 +13,7 @@ REGEX_BAD_PATH_NAMES = re.compile(
|
|||
r'|[\s\.]+$',
|
||||
re.IGNORECASE)
|
||||
|
||||
|
||||
def backup_partition(disk, par):
|
||||
"""Create a backup image of a partition."""
|
||||
if (par.get('Image Exists', False)
|
||||
|
|
@ -31,6 +33,7 @@ def backup_partition(disk, par):
|
|||
os.makedirs(dest_dir, exist_ok=True)
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def fix_path(path):
|
||||
"""Replace invalid filename characters with underscores."""
|
||||
local_drive = path[1:2] == ':'
|
||||
|
|
@ -39,6 +42,7 @@ def fix_path(path):
|
|||
new_path = '{}:{}'.format(new_path[0:1], new_path[2:])
|
||||
return new_path
|
||||
|
||||
|
||||
def get_volume_display_name(mountpoint):
|
||||
"""Get display name from volume mountpoint and label, returns str."""
|
||||
name = mountpoint
|
||||
|
|
@ -67,6 +71,7 @@ def get_volume_display_name(mountpoint):
|
|||
|
||||
return name
|
||||
|
||||
|
||||
def prep_disk_for_backup(destination, disk, backup_prefix):
|
||||
"""Gather details about the disk and its partitions.
|
||||
|
||||
|
|
@ -143,6 +148,7 @@ def prep_disk_for_backup(destination, disk, backup_prefix):
|
|||
COLORS['YELLOW'], COLORS['CLEAR'])
|
||||
disk['Backup Warnings'] = warnings
|
||||
|
||||
|
||||
def select_backup_destination(auto_select=True):
|
||||
"""Select a backup destination from a menu, returns server dict."""
|
||||
destinations = [s for s in BACKUP_SERVERS if s['Mounted']]
|
||||
|
|
@ -193,6 +199,7 @@ def select_backup_destination(auto_select=True):
|
|||
else:
|
||||
return destinations[int(selection)-1]
|
||||
|
||||
|
||||
def verify_wim_backup(partition):
|
||||
"""Verify WIM integrity."""
|
||||
if not os.path.exists(partition['Image Path']):
|
||||
|
|
@ -205,6 +212,7 @@ def verify_wim_backup(partition):
|
|||
]
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from functions.common import *
|
|||
|
||||
from operator import itemgetter
|
||||
|
||||
|
||||
# Define other_results for later try_and_print
|
||||
browser_data = {}
|
||||
other_results = {
|
||||
|
|
@ -16,22 +17,6 @@ other_results = {
|
|||
}
|
||||
}
|
||||
|
||||
# Regex
|
||||
REGEX_BACKUP = re.compile(
|
||||
r'\.\w*bak.*',
|
||||
re.IGNORECASE)
|
||||
REGEX_CHROMIUM_PROFILE = re.compile(
|
||||
r'^(Default|Profile)',
|
||||
re.IGNORECASE)
|
||||
REGEX_CHROMIUM_ITEMS = re.compile(
|
||||
r'^(Bookmarks|Cookies|Favicons|Google Profile'
|
||||
r'|History|Login Data|Top Sites|TransportSecurity'
|
||||
r'|Visited Links|Web Data)',
|
||||
re.IGNORECASE)
|
||||
REGEX_MOZILLA = re.compile(
|
||||
r'^(bookmarkbackups|(cookies|formhistory|places).sqlite'
|
||||
r'|key3.db|logins.json|persdict.dat)$',
|
||||
re.IGNORECASE)
|
||||
|
||||
# STATIC VARIABLES
|
||||
DEFAULT_HOMEPAGE = 'https://www.google.com/'
|
||||
|
|
@ -103,6 +88,25 @@ SUPPORTED_BROWSERS = {
|
|||
},
|
||||
}
|
||||
|
||||
|
||||
# Regex
|
||||
REGEX_BACKUP = re.compile(
|
||||
r'\.\w*bak.*',
|
||||
re.IGNORECASE)
|
||||
REGEX_CHROMIUM_PROFILE = re.compile(
|
||||
r'^(Default|Profile)',
|
||||
re.IGNORECASE)
|
||||
REGEX_CHROMIUM_ITEMS = re.compile(
|
||||
r'^(Bookmarks|Cookies|Favicons|Google Profile'
|
||||
r'|History|Login Data|Top Sites|TransportSecurity'
|
||||
r'|Visited Links|Web Data)',
|
||||
re.IGNORECASE)
|
||||
REGEX_MOZILLA = re.compile(
|
||||
r'^(bookmarkbackups|(cookies|formhistory|places).sqlite'
|
||||
r'|key3.db|logins.json|persdict.dat)$',
|
||||
re.IGNORECASE)
|
||||
|
||||
|
||||
def archive_all_users():
|
||||
"""Create backups for all browsers for all users."""
|
||||
users_root = r'{}\Users'.format(global_vars['Env']['SYSTEMDRIVE'])
|
||||
|
|
@ -149,6 +153,7 @@ def archive_all_users():
|
|||
function=run_program, cmd=cmd)
|
||||
print_standard(' ')
|
||||
|
||||
|
||||
def archive_browser(name):
|
||||
"""Create backup of Browser saved in the BackupDir."""
|
||||
source = '{}*'.format(browser_data[name]['user_data_path'])
|
||||
|
|
@ -163,12 +168,14 @@ def archive_browser(name):
|
|||
archive, source]
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def backup_browsers():
|
||||
"""Create backup of all detected browser profiles."""
|
||||
for name in [k for k, v in sorted(browser_data.items()) if v['profiles']]:
|
||||
try_and_print(message='{}...'.format(name),
|
||||
function=archive_browser, name=name)
|
||||
|
||||
|
||||
def clean_chromium_profile(profile):
|
||||
"""Recreate profile with only the essential user data.
|
||||
|
||||
|
|
@ -191,6 +198,7 @@ def clean_chromium_profile(profile):
|
|||
shutil.copy(entry.path, r'{}\{}'.format(
|
||||
profile['path'], entry.name))
|
||||
|
||||
|
||||
def clean_internet_explorer(**kwargs):
|
||||
"""Uses the built-in function to reset IE and sets the homepage.
|
||||
|
||||
|
|
@ -208,6 +216,7 @@ def clean_internet_explorer(**kwargs):
|
|||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
|
||||
def clean_mozilla_profile(profile):
|
||||
"""Recreate profile with only the essential user data.
|
||||
|
||||
|
|
@ -240,6 +249,7 @@ def clean_mozilla_profile(profile):
|
|||
for k, v in MOZILLA_PREFS.items():
|
||||
f.write('user_pref("{}", {});\n'.format(k, v))
|
||||
|
||||
|
||||
def get_browser_details(name):
|
||||
"""Get installation and profile details for all supported browsers."""
|
||||
browser = SUPPORTED_BROWSERS[name].copy()
|
||||
|
|
@ -314,6 +324,7 @@ def get_browser_details(name):
|
|||
elif num_installs > 1 and browser['base'] != 'ie':
|
||||
raise MultipleInstallationsError
|
||||
|
||||
|
||||
def get_chromium_profiles(search_path):
|
||||
"""Find any chromium-style profiles and return as a list of dicts."""
|
||||
profiles = []
|
||||
|
|
@ -330,6 +341,7 @@ def get_chromium_profiles(search_path):
|
|||
|
||||
return profiles
|
||||
|
||||
|
||||
def get_ie_homepages():
|
||||
"""Read homepages from the registry and return as a list."""
|
||||
homepages = []
|
||||
|
|
@ -354,6 +366,7 @@ def get_ie_homepages():
|
|||
homepages = [h.replace('{', '').replace('}', '') for h in homepages]
|
||||
return homepages
|
||||
|
||||
|
||||
def get_mozilla_homepages(prefs_path):
|
||||
"""Read homepages from prefs.js and return as a list."""
|
||||
homepages = []
|
||||
|
|
@ -369,6 +382,7 @@ def get_mozilla_homepages(prefs_path):
|
|||
|
||||
return homepages
|
||||
|
||||
|
||||
def get_mozilla_profiles(search_path, dev=False):
|
||||
"""Find any mozilla-style profiles and return as a list of dicts."""
|
||||
profiles = []
|
||||
|
|
@ -393,6 +407,7 @@ def get_mozilla_profiles(search_path, dev=False):
|
|||
|
||||
return profiles
|
||||
|
||||
|
||||
def install_adblock(indent=8, width=32, just_firefox=False):
|
||||
"""Install adblock for all supported browsers."""
|
||||
for browser in sorted(browser_data):
|
||||
|
|
@ -461,6 +476,7 @@ def install_adblock(indent=8, width=32, just_firefox=False):
|
|||
cs='Done', function=function,
|
||||
cmd=[exe_path, *urls], check=False)
|
||||
|
||||
|
||||
def list_homepages(indent=8, width=32):
|
||||
"""List current homepages for reference."""
|
||||
browser_list = [k for k, v in sorted(browser_data.items()) if v['exe_path']]
|
||||
|
|
@ -491,6 +507,7 @@ def list_homepages(indent=8, width=32):
|
|||
print_standard('{indent}{name:<{width}}{page}'.format(
|
||||
indent=' '*indent, width=width, name=name, page=page))
|
||||
|
||||
|
||||
def reset_browsers(indent=8, width=32):
|
||||
"""Reset all detected browsers to safe defaults."""
|
||||
browser_list = [k for k, v in sorted(browser_data.items()) if v['profiles']]
|
||||
|
|
@ -508,6 +525,7 @@ def reset_browsers(indent=8, width=32):
|
|||
indent=indent, width=width, function=function,
|
||||
other_results=other_results, profile=profile)
|
||||
|
||||
|
||||
def scan_for_browsers(just_firefox=False):
|
||||
"""Scan system for any supported browsers."""
|
||||
for name, details in sorted(SUPPORTED_BROWSERS.items()):
|
||||
|
|
@ -517,6 +535,7 @@ def scan_for_browsers(just_firefox=False):
|
|||
function=get_browser_details, cs='Detected',
|
||||
other_results=other_results, name=name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
from functions.common import *
|
||||
|
||||
|
||||
def cleanup_adwcleaner():
|
||||
"""Move AdwCleaner folders into the ClientDir."""
|
||||
source_path = r'{SYSTEMDRIVE}\AdwCleaner'.format(**global_vars['Env'])
|
||||
|
|
@ -26,6 +27,7 @@ def cleanup_adwcleaner():
|
|||
dest_name = non_clobber_rename(dest_name)
|
||||
shutil.move(source_path, dest_name)
|
||||
|
||||
|
||||
def cleanup_cbs(dest_folder):
|
||||
"""Safely cleanup a known CBS archive bug under Windows 7.
|
||||
|
||||
|
|
@ -65,6 +67,7 @@ def cleanup_cbs(dest_folder):
|
|||
r'{}\CbsPersist*'.format(temp_folder)]
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def cleanup_desktop():
|
||||
"""Move known backup files and reports into the ClientDir."""
|
||||
dest_folder = r'{LogDir}\Tools'.format(**global_vars)
|
||||
|
|
@ -81,6 +84,7 @@ def cleanup_desktop():
|
|||
# Remove dir if empty
|
||||
delete_empty_folders(dest_folder)
|
||||
|
||||
|
||||
def delete_empty_folders(folder_path):
|
||||
"""Delete all empty folders in path (depth first)."""
|
||||
if not os.path.exists(folder_path) or not os.path.isdir(folder_path):
|
||||
|
|
@ -98,6 +102,7 @@ def delete_empty_folders(folder_path):
|
|||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def delete_registry_key(hive, key, recurse=False):
|
||||
"""Delete a registry key and all it's subkeys."""
|
||||
access = winreg.KEY_ALL_ACCESS
|
||||
|
|
@ -117,12 +122,14 @@ def delete_registry_key(hive, key, recurse=False):
|
|||
# Ignore
|
||||
pass
|
||||
|
||||
|
||||
def delete_registry_value(hive, key, value):
|
||||
"""Delete a registry value."""
|
||||
access = winreg.KEY_ALL_ACCESS
|
||||
with winreg.OpenKeyEx(hive, key, 0, access) as k:
|
||||
winreg.DeleteValue(k, value)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ from settings.main import *
|
|||
from settings.tools import *
|
||||
from settings.windows_builds import *
|
||||
|
||||
|
||||
# Global variables
|
||||
global_vars = {}
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
COLORS = {
|
||||
'CLEAR': '\033[0m',
|
||||
|
|
@ -42,6 +44,7 @@ except NameError:
|
|||
if psutil.WINDOWS:
|
||||
raise
|
||||
|
||||
|
||||
# Error Classes
|
||||
class BIOSKeyNotFoundError(Exception):
|
||||
pass
|
||||
|
|
@ -85,6 +88,7 @@ class SecureBootNotAvailError(Exception):
|
|||
class SecureBootUnknownError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# General functions
|
||||
def abort():
|
||||
"""Abort script."""
|
||||
|
|
@ -93,6 +97,7 @@ def abort():
|
|||
pause(prompt='Press Enter to exit... ')
|
||||
exit_script()
|
||||
|
||||
|
||||
def ask(prompt='Kotaero!'):
|
||||
"""Prompt the user with a Y/N question, returns bool."""
|
||||
answer = None
|
||||
|
|
@ -109,6 +114,7 @@ def ask(prompt='Kotaero!'):
|
|||
print_log(message=message)
|
||||
return answer
|
||||
|
||||
|
||||
def choice(choices, prompt='Kotaero!'):
|
||||
"""Prompt the user with a choice question, returns str."""
|
||||
answer = None
|
||||
|
|
@ -137,6 +143,7 @@ def choice(choices, prompt='Kotaero!'):
|
|||
# Done
|
||||
return answer
|
||||
|
||||
|
||||
def clear_screen():
|
||||
"""Simple wrapper for cls/clear."""
|
||||
if psutil.WINDOWS:
|
||||
|
|
@ -144,6 +151,7 @@ def clear_screen():
|
|||
else:
|
||||
os.system('clear')
|
||||
|
||||
|
||||
def convert_to_bytes(size):
|
||||
"""Convert human-readable size str to bytes and return an int."""
|
||||
size = str(size)
|
||||
|
|
@ -165,6 +173,7 @@ def convert_to_bytes(size):
|
|||
|
||||
return size
|
||||
|
||||
|
||||
def exit_script(return_value=0):
|
||||
"""Exits the script after some cleanup and opens the log (if set)."""
|
||||
# Remove dirs (if empty)
|
||||
|
|
@ -192,6 +201,7 @@ def exit_script(return_value=0):
|
|||
# Exit
|
||||
sys.exit(return_value)
|
||||
|
||||
|
||||
def extract_item(item, filter='', silent=False):
|
||||
"""Extract item from .cbin into .bin."""
|
||||
cmd = [
|
||||
|
|
@ -211,6 +221,7 @@ def extract_item(item, filter='', silent=False):
|
|||
if not silent:
|
||||
print_warning('WARNING: Errors encountered while exctracting data')
|
||||
|
||||
|
||||
def get_process(name=None):
|
||||
"""Get process by name, returns psutil.Process obj."""
|
||||
proc = None
|
||||
|
|
@ -226,6 +237,7 @@ def get_process(name=None):
|
|||
pass
|
||||
return proc
|
||||
|
||||
|
||||
def get_simple_string(prompt='Enter string'):
|
||||
"""Get string from user (restricted character set), returns str."""
|
||||
simple_string = None
|
||||
|
|
@ -235,6 +247,7 @@ def get_simple_string(prompt='Enter string'):
|
|||
simple_string = _input.strip()
|
||||
return simple_string
|
||||
|
||||
|
||||
def get_ticket_number():
|
||||
"""Get TicketNumber from user, save in LogDir, and return as str."""
|
||||
if not ENABLED_TICKET_NUMBERS:
|
||||
|
|
@ -251,6 +264,7 @@ def get_ticket_number():
|
|||
f.write(ticket_number)
|
||||
return ticket_number
|
||||
|
||||
|
||||
def human_readable_size(size, decimals=0):
|
||||
"""Convert size from bytes to a human-readable format, returns str."""
|
||||
# Prep string formatting
|
||||
|
|
@ -290,12 +304,14 @@ def human_readable_size(size, decimals=0):
|
|||
return '{size:>{width}.{decimals}f} {units}'.format(
|
||||
size=size, width=width, decimals=decimals, units=units)
|
||||
|
||||
|
||||
def kill_process(name):
|
||||
"""Kill any running caffeine.exe processes."""
|
||||
for proc in psutil.process_iter():
|
||||
if proc.name() == name:
|
||||
proc.kill()
|
||||
|
||||
|
||||
def major_exception():
|
||||
"""Display traceback and exit"""
|
||||
print_error('Major exception')
|
||||
|
|
@ -319,6 +335,7 @@ def major_exception():
|
|||
pause('Press Enter to exit...')
|
||||
exit_script(1)
|
||||
|
||||
|
||||
def menu_select(
|
||||
title='[Untitled Menu]',
|
||||
prompt='Please make a selection', secret_actions=[], secret_exit=False,
|
||||
|
|
@ -382,6 +399,7 @@ def menu_select(
|
|||
|
||||
return answer.upper()
|
||||
|
||||
|
||||
def non_clobber_rename(full_path):
|
||||
"""Append suffix to path, if necessary, to avoid clobbering path"""
|
||||
new_path = full_path
|
||||
|
|
@ -392,10 +410,12 @@ def non_clobber_rename(full_path):
|
|||
|
||||
return new_path
|
||||
|
||||
|
||||
def pause(prompt='Press Enter to continue... '):
|
||||
"""Simple pause implementation."""
|
||||
input(prompt)
|
||||
|
||||
|
||||
def ping(addr='google.com'):
|
||||
"""Attempt to ping addr."""
|
||||
cmd = [
|
||||
|
|
@ -405,6 +425,7 @@ def ping(addr='google.com'):
|
|||
addr]
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def popen_program(cmd, pipe=False, minimized=False, shell=False, **kwargs):
|
||||
"""Run program and return a subprocess.Popen object."""
|
||||
cmd_kwargs = {'args': cmd, 'shell': shell}
|
||||
|
|
@ -426,14 +447,17 @@ def popen_program(cmd, pipe=False, minimized=False, shell=False, **kwargs):
|
|||
|
||||
return subprocess.Popen(**cmd_kwargs)
|
||||
|
||||
|
||||
def print_error(*args, **kwargs):
|
||||
"""Prints message to screen in RED."""
|
||||
print_standard(*args, color=COLORS['RED'], **kwargs)
|
||||
|
||||
|
||||
def print_info(*args, **kwargs):
|
||||
"""Prints message to screen in BLUE."""
|
||||
print_standard(*args, color=COLORS['BLUE'], **kwargs)
|
||||
|
||||
|
||||
def print_standard(message='Generic info',
|
||||
color=None, end='\n', timestamp=True, **kwargs):
|
||||
"""Prints message to screen and log (if set)."""
|
||||
|
|
@ -444,14 +468,17 @@ def print_standard(message='Generic info',
|
|||
print(display_message.format(**COLORS), end=end, **kwargs)
|
||||
print_log(message, end, timestamp)
|
||||
|
||||
|
||||
def print_success(*args, **kwargs):
|
||||
"""Prints message to screen in GREEN."""
|
||||
print_standard(*args, color=COLORS['GREEN'], **kwargs)
|
||||
|
||||
|
||||
def print_warning(*args, **kwargs):
|
||||
"""Prints message to screen in YELLOW."""
|
||||
print_standard(*args, color=COLORS['YELLOW'], **kwargs)
|
||||
|
||||
|
||||
def print_log(message='', end='\n', timestamp=True):
|
||||
"""Writes message to a log if LogFile is set."""
|
||||
time_str = time.strftime("%Y-%m-%d %H%M%z: ") if timestamp else ''
|
||||
|
|
@ -463,6 +490,7 @@ def print_log(message='', end='\n', timestamp=True):
|
|||
line = line,
|
||||
end = end))
|
||||
|
||||
|
||||
def run_program(cmd, args=[], check=True, pipe=True, shell=False, **kwargs):
|
||||
"""Run program and return a subprocess.CompletedProcess object."""
|
||||
if args:
|
||||
|
|
@ -486,6 +514,7 @@ def run_program(cmd, args=[], check=True, pipe=True, shell=False, **kwargs):
|
|||
|
||||
return subprocess.run(**cmd_kwargs)
|
||||
|
||||
|
||||
def set_title(title='[Some Title]'):
|
||||
"""Set title.
|
||||
|
||||
|
|
@ -493,6 +522,7 @@ def set_title(title='[Some Title]'):
|
|||
global_vars['Title'] = title
|
||||
os.system('title {}'.format(title))
|
||||
|
||||
|
||||
def show_data(
|
||||
message='[Some message]', data='[Some data]',
|
||||
indent=8, width=32,
|
||||
|
|
@ -509,10 +539,12 @@ def show_data(
|
|||
else:
|
||||
print_standard(message)
|
||||
|
||||
|
||||
def sleep(seconds=2):
|
||||
"""Wait for a while."""
|
||||
time.sleep(seconds)
|
||||
|
||||
|
||||
def stay_awake():
|
||||
"""Prevent the system from sleeping or hibernating."""
|
||||
# DISABLED due to VCR2008 dependency
|
||||
|
|
@ -529,12 +561,14 @@ def stay_awake():
|
|||
print_error('ERROR: No caffeine available.')
|
||||
print_warning('Please set the power setting to High Performance.')
|
||||
|
||||
|
||||
def strip_colors(s):
|
||||
"""Remove all ASCII color escapes from string, returns str."""
|
||||
for c in COLORS.values():
|
||||
s = s.replace(c, '')
|
||||
return s
|
||||
|
||||
|
||||
def get_exception(s):
|
||||
"""Get exception by name, returns Exception object."""
|
||||
try:
|
||||
|
|
@ -544,6 +578,7 @@ def get_exception(s):
|
|||
obj = getattr(sys.modules['builtins'], s)
|
||||
return obj
|
||||
|
||||
|
||||
def try_and_print(message='Trying...',
|
||||
function=None, cs='CS', ns='NS', other_results={},
|
||||
catch_all=True, print_return=False, silent_function=True,
|
||||
|
|
@ -600,6 +635,7 @@ def try_and_print(message='Trying...',
|
|||
else:
|
||||
return {'CS': not bool(err), 'Error': err, 'Out': out}
|
||||
|
||||
|
||||
def upload_crash_details():
|
||||
"""Upload log and runtime data to the CRASH_SERVER.
|
||||
|
||||
|
|
@ -611,13 +647,11 @@ def upload_crash_details():
|
|||
if 'LogFile' in global_vars and global_vars['LogFile']:
|
||||
if ask('Upload crash details to {}?'.format(CRASH_SERVER['Name'])):
|
||||
with open(global_vars['LogFile']) as f:
|
||||
data = '''{}
|
||||
#############################
|
||||
Runtime Details:
|
||||
|
||||
sys.argv: {}
|
||||
|
||||
global_vars: {}'''.format(f.read(), sys.argv, global_vars)
|
||||
data = '{}\n'.format(f.read())
|
||||
data += '#############################\n'
|
||||
data += 'Runtime Details:\n\n'
|
||||
data += 'sys.argv: {}\n\n'.format(sys.argv)
|
||||
data += 'global_vars: {}\n'.format(global_vars)
|
||||
filename = global_vars.get('LogFile', 'Unknown')
|
||||
filename = re.sub(r'.*(\\|/)', '', filename)
|
||||
filename += '.txt'
|
||||
|
|
@ -639,6 +673,7 @@ global_vars: {}'''.format(f.read(), sys.argv, global_vars)
|
|||
# No LogFile defined (or invalid LogFile)
|
||||
raise GenericError
|
||||
|
||||
|
||||
def wait_for_process(name, poll_rate=3):
|
||||
"""Wait for process by name."""
|
||||
running = True
|
||||
|
|
@ -654,6 +689,7 @@ def wait_for_process(name, poll_rate=3):
|
|||
pass
|
||||
sleep(1)
|
||||
|
||||
|
||||
# global_vars functions
|
||||
def init_global_vars(silent=False):
|
||||
"""Sets global variables based on system info."""
|
||||
|
|
@ -687,6 +723,7 @@ def init_global_vars(silent=False):
|
|||
except:
|
||||
major_exception()
|
||||
|
||||
|
||||
def check_os():
|
||||
"""Set OS specific variables."""
|
||||
tmp = {}
|
||||
|
|
@ -749,6 +786,7 @@ def check_os():
|
|||
|
||||
global_vars['OS'] = tmp
|
||||
|
||||
|
||||
def check_tools():
|
||||
"""Set tool variables based on OS bit-depth and tool availability."""
|
||||
if global_vars['OS'].get('Arch', 32) == 64:
|
||||
|
|
@ -761,6 +799,7 @@ def check_tools():
|
|||
global_vars['Tools'] = {k: os.path.join(global_vars['BinDir'], v)
|
||||
for (k, v) in global_vars['Tools'].items()}
|
||||
|
||||
|
||||
def clean_env_vars():
|
||||
"""Remove conflicting global_vars and env variables.
|
||||
|
||||
|
|
@ -769,6 +808,7 @@ def clean_env_vars():
|
|||
for key in global_vars.keys():
|
||||
global_vars['Env'].pop(key, None)
|
||||
|
||||
|
||||
def find_bin():
|
||||
"""Find .bin folder in the cwd or it's parents."""
|
||||
wd = os.getcwd()
|
||||
|
|
@ -785,6 +825,7 @@ def find_bin():
|
|||
raise BinNotFoundError
|
||||
global_vars['BaseDir'] = base
|
||||
|
||||
|
||||
def make_tmp_dirs():
|
||||
"""Make temp directories."""
|
||||
os.makedirs(global_vars['BackupDir'], exist_ok=True)
|
||||
|
|
@ -794,6 +835,7 @@ def make_tmp_dirs():
|
|||
os.makedirs(r'{}\Tools'.format(global_vars['LogDir']), exist_ok=True)
|
||||
os.makedirs(global_vars['TmpDir'], exist_ok=True)
|
||||
|
||||
|
||||
def set_common_vars():
|
||||
"""Set common variables."""
|
||||
global_vars['Date'] = time.strftime("%Y-%m-%d")
|
||||
|
|
@ -816,6 +858,7 @@ def set_common_vars():
|
|||
global_vars['TmpDir'] = r'{BinDir}\tmp'.format(
|
||||
**global_vars)
|
||||
|
||||
|
||||
def set_linux_vars():
|
||||
"""Set common variables in a Linux environment.
|
||||
|
||||
|
|
@ -832,6 +875,7 @@ def set_linux_vars():
|
|||
'SevenZip': '7z',
|
||||
}
|
||||
|
||||
|
||||
def set_log_file(log_name):
|
||||
"""Sets global var LogFile and creates path as needed."""
|
||||
folder_path = r'{}\{}'.format(global_vars['LogDir'], KIT_NAME_FULL)
|
||||
|
|
@ -839,6 +883,7 @@ def set_log_file(log_name):
|
|||
os.makedirs(folder_path, exist_ok=True)
|
||||
global_vars['LogFile'] = log_file
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -7,57 +7,6 @@ from operator import itemgetter
|
|||
|
||||
from functions.common import *
|
||||
|
||||
# Classes
|
||||
class LocalDisk():
|
||||
def __init__(self, disk):
|
||||
self.disk = disk
|
||||
self.name = disk.mountpoint.upper()
|
||||
self.path = self.name
|
||||
def is_dir(self):
|
||||
# Should always be true
|
||||
return True
|
||||
def is_file(self):
|
||||
# Should always be false
|
||||
return False
|
||||
|
||||
class SourceItem():
|
||||
def __init__(self, name, path):
|
||||
self.name = name
|
||||
self.path = path
|
||||
|
||||
# Regex
|
||||
REGEX_EXCL_ITEMS = re.compile(
|
||||
r'^(\.(AppleDB|AppleDesktop|AppleDouble'
|
||||
r'|com\.apple\.timemachine\.supported|dbfseventsd'
|
||||
r'|DocumentRevisions-V100.*|DS_Store|fseventsd|PKInstallSandboxManager'
|
||||
r'|Spotlight.*|SymAV.*|symSchedScanLockxz|TemporaryItems|Trash.*'
|
||||
r'|vol|VolumeIcon\.icns)|desktop\.(ini|.*DB|.*DF)'
|
||||
r'|(hiberfil|pagefile)\.sys|lost\+found|Network\.*Trash\.*Folder'
|
||||
r'|Recycle[dr]|System\.*Volume\.*Information|Temporary\.*Items'
|
||||
r'|Thumbs\.db)$',
|
||||
re.IGNORECASE)
|
||||
REGEX_EXCL_ROOT_ITEMS = re.compile(
|
||||
r'^(boot(mgr|nxt)$|Config.msi'
|
||||
r'|(eula|globdata|install|vc_?red)'
|
||||
r'|.*.sys$|System Volume Information|RECYCLER?|\$Recycle\.bin'
|
||||
r'|\$?Win(dows(.old.*|\. BT|)$|RE_)|\$GetCurrent|Windows10Upgrade'
|
||||
r'|PerfLogs|Program Files|SYSTEM.SAV'
|
||||
r'|.*\.(esd|swm|wim|dd|map|dmg|image)$)',
|
||||
re.IGNORECASE)
|
||||
REGEX_INCL_ROOT_ITEMS = re.compile(
|
||||
r'^(AdwCleaner|(My\s*|)(Doc(uments?( and Settings|)|s?)|Downloads'
|
||||
r'|Media|Music|Pic(ture|)s?|Vid(eo|)s?)'
|
||||
r'|{prefix}(-?Info|-?Transfer|)'
|
||||
r'|(ProgramData|Recovery|Temp.*|Users)$'
|
||||
r'|.*\.(log|txt|rtf|qb\w*|avi|m4a|m4v|mp4|mkv|jpg|png|tiff?)$)'
|
||||
r''.format(prefix=KIT_NAME_SHORT),
|
||||
re.IGNORECASE)
|
||||
REGEX_WIM_FILE = re.compile(
|
||||
r'\.wim$',
|
||||
re.IGNORECASE)
|
||||
REGEX_WINDOWS_OLD = re.compile(
|
||||
r'^Win(dows|)\.old',
|
||||
re.IGNORECASE)
|
||||
|
||||
# STATIC VARIABLES
|
||||
FAST_COPY_EXCLUDES = [
|
||||
|
|
@ -116,6 +65,63 @@ SEM_FAILCRITICALERRORS = 1
|
|||
SEM_NOOPENFILEERRORBOX = 0x8000
|
||||
SEM_FAIL = SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS
|
||||
|
||||
|
||||
# Regex
|
||||
REGEX_EXCL_ITEMS = re.compile(
|
||||
r'^(\.(AppleDB|AppleDesktop|AppleDouble'
|
||||
r'|com\.apple\.timemachine\.supported|dbfseventsd'
|
||||
r'|DocumentRevisions-V100.*|DS_Store|fseventsd|PKInstallSandboxManager'
|
||||
r'|Spotlight.*|SymAV.*|symSchedScanLockxz|TemporaryItems|Trash.*'
|
||||
r'|vol|VolumeIcon\.icns)|desktop\.(ini|.*DB|.*DF)'
|
||||
r'|(hiberfil|pagefile)\.sys|lost\+found|Network\.*Trash\.*Folder'
|
||||
r'|Recycle[dr]|System\.*Volume\.*Information|Temporary\.*Items'
|
||||
r'|Thumbs\.db)$',
|
||||
re.IGNORECASE)
|
||||
REGEX_EXCL_ROOT_ITEMS = re.compile(
|
||||
r'^(boot(mgr|nxt)$|Config.msi'
|
||||
r'|(eula|globdata|install|vc_?red)'
|
||||
r'|.*.sys$|System Volume Information|RECYCLER?|\$Recycle\.bin'
|
||||
r'|\$?Win(dows(.old.*|\. BT|)$|RE_)|\$GetCurrent|Windows10Upgrade'
|
||||
r'|PerfLogs|Program Files|SYSTEM.SAV'
|
||||
r'|.*\.(esd|swm|wim|dd|map|dmg|image)$)',
|
||||
re.IGNORECASE)
|
||||
REGEX_INCL_ROOT_ITEMS = re.compile(
|
||||
r'^(AdwCleaner|(My\s*|)(Doc(uments?( and Settings|)|s?)|Downloads'
|
||||
r'|Media|Music|Pic(ture|)s?|Vid(eo|)s?)'
|
||||
r'|{prefix}(-?Info|-?Transfer|)'
|
||||
r'|(ProgramData|Recovery|Temp.*|Users)$'
|
||||
r'|.*\.(log|txt|rtf|qb\w*|avi|m4a|m4v|mp4|mkv|jpg|png|tiff?)$)'
|
||||
r''.format(prefix=KIT_NAME_SHORT),
|
||||
re.IGNORECASE)
|
||||
REGEX_WIM_FILE = re.compile(
|
||||
r'\.wim$',
|
||||
re.IGNORECASE)
|
||||
REGEX_WINDOWS_OLD = re.compile(
|
||||
r'^Win(dows|)\.old',
|
||||
re.IGNORECASE)
|
||||
|
||||
|
||||
# Classes
|
||||
class LocalDisk():
|
||||
def __init__(self, disk):
|
||||
self.disk = disk
|
||||
self.name = disk.mountpoint.upper()
|
||||
self.path = self.name
|
||||
def is_dir(self):
|
||||
# Should always be true
|
||||
return True
|
||||
def is_file(self):
|
||||
# Should always be false
|
||||
return False
|
||||
|
||||
|
||||
class SourceItem():
|
||||
def __init__(self, name, path):
|
||||
self.name = name
|
||||
self.path = path
|
||||
|
||||
|
||||
# Functions
|
||||
def cleanup_transfer(dest_path):
|
||||
"""Fix attributes and move excluded items to separate folder."""
|
||||
try:
|
||||
|
|
@ -153,6 +159,7 @@ def cleanup_transfer(dest_path):
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def find_core_storage_volumes(device_path=None):
|
||||
"""Try to create block devices for any Apple CoreStorage volumes."""
|
||||
corestorage_uuid = '53746f72-6167-11aa-aa11-00306543ecac'
|
||||
|
|
@ -216,10 +223,12 @@ def find_core_storage_volumes(device_path=None):
|
|||
cmd = ['sudo', 'dmsetup', 'create', name, dmsetup_cmd_file]
|
||||
run_program(cmd, check=False)
|
||||
|
||||
|
||||
def fix_path_sep(path_str):
|
||||
"""Replace non-native and duplicate dir separators, returns str."""
|
||||
return re.sub(r'(\\|/)+', lambda s: os.sep, path_str)
|
||||
|
||||
|
||||
def is_valid_wim_file(item):
|
||||
"""Checks if the item is a valid WIM file, returns bool."""
|
||||
valid = bool(item.is_file() and REGEX_WIM_FILE.search(item.name))
|
||||
|
|
@ -233,6 +242,7 @@ def is_valid_wim_file(item):
|
|||
print_log('WARNING: Image "{}" damaged.'.format(item.name))
|
||||
return valid
|
||||
|
||||
|
||||
def get_mounted_volumes():
|
||||
"""Get mounted volumes, returns dict."""
|
||||
cmd = [
|
||||
|
|
@ -250,6 +260,7 @@ def get_mounted_volumes():
|
|||
mounted_volumes.extend(item.get('children', []))
|
||||
return {item['source']: item for item in mounted_volumes}
|
||||
|
||||
|
||||
def mount_volumes(
|
||||
all_devices=True, device_path=None,
|
||||
read_write=False, core_storage=True):
|
||||
|
|
@ -342,6 +353,7 @@ def mount_volumes(
|
|||
|
||||
return report
|
||||
|
||||
|
||||
def mount_backup_shares(read_write=False):
|
||||
"""Mount the backup shares unless labeled as already mounted."""
|
||||
if psutil.LINUX:
|
||||
|
|
@ -363,6 +375,7 @@ def mount_backup_shares(read_write=False):
|
|||
|
||||
mount_network_share(server, read_write)
|
||||
|
||||
|
||||
def mount_network_share(server, read_write=False):
|
||||
"""Mount a network share defined by server."""
|
||||
if read_write:
|
||||
|
|
@ -415,6 +428,7 @@ def mount_network_share(server, read_write=False):
|
|||
print_info(success)
|
||||
server['Mounted'] = True
|
||||
|
||||
|
||||
def run_fast_copy(items, dest):
|
||||
"""Copy items to dest using FastCopy."""
|
||||
if not items:
|
||||
|
|
@ -427,6 +441,7 @@ def run_fast_copy(items, dest):
|
|||
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def run_wimextract(source, items, dest):
|
||||
"""Extract items from source WIM to dest folder."""
|
||||
if not items:
|
||||
|
|
@ -452,6 +467,7 @@ def run_wimextract(source, items, dest):
|
|||
'--nullglob']
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def list_source_items(source_obj, rel_path=None):
|
||||
"""List items in a dir or WIM, returns list of SourceItem objects."""
|
||||
items = []
|
||||
|
|
@ -489,6 +505,7 @@ def list_source_items(source_obj, rel_path=None):
|
|||
# Done
|
||||
return items
|
||||
|
||||
|
||||
def scan_source(source_obj, dest_path, rel_path='', interactive=True):
|
||||
"""Scan source for files/folders to transfer, returns list.
|
||||
|
||||
|
|
@ -572,6 +589,7 @@ def scan_source(source_obj, dest_path, rel_path='', interactive=True):
|
|||
# Done
|
||||
return selected_items
|
||||
|
||||
|
||||
def get_source_item_obj(source_obj, rel_path, item_path):
|
||||
"""Check if the item exists, returns SourceItem object or None."""
|
||||
item_obj = None
|
||||
|
|
@ -611,6 +629,7 @@ def get_source_item_obj(source_obj, rel_path, item_path):
|
|||
item_path))
|
||||
return item_obj
|
||||
|
||||
|
||||
def select_destination(folder_path, prompt='Select destination'):
|
||||
"""Select destination drive, returns path as string."""
|
||||
disk = select_volume(prompt)
|
||||
|
|
@ -627,6 +646,7 @@ def select_destination(folder_path, prompt='Select destination'):
|
|||
|
||||
return path
|
||||
|
||||
|
||||
def select_source(backup_prefix):
|
||||
"""Select matching backup from BACKUP_SERVERS, returns obj."""
|
||||
selected_source = None
|
||||
|
|
@ -792,6 +812,7 @@ def select_source(backup_prefix):
|
|||
# Done
|
||||
return selected_source
|
||||
|
||||
|
||||
def select_volume(title='Select disk', auto_select=True):
|
||||
"""Select disk from attached disks. returns dict."""
|
||||
actions = [{'Name': 'Quit', 'Letter': 'Q'}]
|
||||
|
|
@ -829,6 +850,7 @@ def select_volume(title='Select disk', auto_select=True):
|
|||
else:
|
||||
return disks[int(selection)-1]
|
||||
|
||||
|
||||
def set_thread_error_mode(silent=True):
|
||||
"""Disable or Enable Windows error message dialogs.
|
||||
|
||||
|
|
@ -842,6 +864,7 @@ def set_thread_error_mode(silent=True):
|
|||
else:
|
||||
kernel32.SetThreadErrorMode(SEM_NORMAL, ctypes.byref(SEM_NORMAL))
|
||||
|
||||
|
||||
def transfer_source(source_obj, dest_path, selected_items):
|
||||
"""Transfer, or extract, files/folders from source to destination."""
|
||||
if source_obj.is_dir():
|
||||
|
|
@ -864,11 +887,13 @@ def transfer_source(source_obj, dest_path, selected_items):
|
|||
print_error('ERROR: Unsupported image: {}'.format(source_obj.path))
|
||||
raise GenericError
|
||||
|
||||
|
||||
def umount_backup_shares():
|
||||
"""Unmount the backup shares regardless of current status."""
|
||||
for server in BACKUP_SERVERS:
|
||||
umount_network_share(server)
|
||||
|
||||
|
||||
def umount_network_share(server):
|
||||
"""Unmount a network share defined by server."""
|
||||
cmd = r'net use \\{IP}\{Share} /delete'.format(**server)
|
||||
|
|
@ -882,6 +907,7 @@ def umount_network_share(server):
|
|||
print_info('Umounted {Name}'.format(**server))
|
||||
server['Mounted'] = False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from functions.hw_diags import *
|
|||
from functions.tmux import *
|
||||
from operator import itemgetter
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
AUTO_PASS_1_THRESHOLD = 95
|
||||
AUTO_PASS_2_THRESHOLD = 98
|
||||
|
|
@ -778,6 +779,7 @@ def menu_ddrescue(source_path, dest_path, run_mode):
|
|||
run_program(['tmux', 'kill-window'])
|
||||
exit_script()
|
||||
|
||||
|
||||
def menu_main(state):
|
||||
"""Main menu is used to set ddrescue settings."""
|
||||
title = '{GREEN}ddrescue TUI: Main Menu{CLEAR}\n\n'.format(**COLORS)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
from functions.common import *
|
||||
from settings.partition_uids import *
|
||||
|
||||
|
||||
# Regex
|
||||
REGEX_BAD_PARTITION = re.compile(r'(RAW|Unknown)', re.IGNORECASE)
|
||||
REGEX_DISK_GPT = re.compile(
|
||||
|
|
@ -11,6 +12,7 @@ REGEX_DISK_GPT = re.compile(
|
|||
REGEX_DISK_MBR = re.compile(r'Disk ID: [A-Z0-9]+', re.IGNORECASE)
|
||||
REGEX_DISK_RAW = re.compile(r'Disk ID: 00000000', re.IGNORECASE)
|
||||
|
||||
|
||||
def assign_volume_letters():
|
||||
"""Assign a volume letter to all available volumes."""
|
||||
remove_volume_letters()
|
||||
|
|
@ -24,6 +26,7 @@ def assign_volume_letters():
|
|||
# Run
|
||||
run_diskpart(script)
|
||||
|
||||
|
||||
def get_boot_mode():
|
||||
"""Check if the boot mode was UEFI or legacy."""
|
||||
boot_mode = 'Legacy'
|
||||
|
|
@ -38,6 +41,7 @@ def get_boot_mode():
|
|||
|
||||
return boot_mode
|
||||
|
||||
|
||||
def get_disk_details(disk):
|
||||
"""Get disk details using DiskPart."""
|
||||
details = {}
|
||||
|
|
@ -63,6 +67,7 @@ def get_disk_details(disk):
|
|||
|
||||
return details
|
||||
|
||||
|
||||
def get_disks():
|
||||
"""Get list of attached disks using DiskPart."""
|
||||
disks = []
|
||||
|
|
@ -82,6 +87,7 @@ def get_disks():
|
|||
|
||||
return disks
|
||||
|
||||
|
||||
def get_partition_details(disk, partition):
|
||||
"""Get partition details using DiskPart and fsutil."""
|
||||
details = {}
|
||||
|
|
@ -161,6 +167,7 @@ def get_partition_details(disk, partition):
|
|||
|
||||
return details
|
||||
|
||||
|
||||
def get_partitions(disk):
|
||||
"""Get list of partition using DiskPart."""
|
||||
partitions = []
|
||||
|
|
@ -184,6 +191,7 @@ def get_partitions(disk):
|
|||
|
||||
return partitions
|
||||
|
||||
|
||||
def get_table_type(disk):
|
||||
"""Get disk partition table type using DiskPart."""
|
||||
part_type = 'Unknown'
|
||||
|
|
@ -206,6 +214,7 @@ def get_table_type(disk):
|
|||
|
||||
return part_type
|
||||
|
||||
|
||||
def get_volumes():
|
||||
"""Get list of volumes using DiskPart."""
|
||||
vols = []
|
||||
|
|
@ -221,10 +230,12 @@ def get_volumes():
|
|||
|
||||
return vols
|
||||
|
||||
|
||||
def is_bad_partition(par):
|
||||
"""Check if the partition is accessible."""
|
||||
return 'Letter' not in par or REGEX_BAD_PARTITION.search(par['FileSystem'])
|
||||
|
||||
|
||||
def prep_disk_for_formatting(disk=None):
|
||||
"""Gather details about the disk and its partitions."""
|
||||
disk['Format Warnings'] = '\n'
|
||||
|
|
@ -270,6 +281,7 @@ def prep_disk_for_formatting(disk=None):
|
|||
# For all partitions
|
||||
partition['Display String'] = display
|
||||
|
||||
|
||||
def reassign_volume_letter(letter, new_letter='I'):
|
||||
"""Assign a new letter to a volume using DiskPart."""
|
||||
if not letter:
|
||||
|
|
@ -286,6 +298,7 @@ def reassign_volume_letter(letter, new_letter='I'):
|
|||
else:
|
||||
return new_letter
|
||||
|
||||
|
||||
def remove_volume_letters(keep=None):
|
||||
"""Remove all assigned volume letters using DiskPart."""
|
||||
if not keep:
|
||||
|
|
@ -303,6 +316,7 @@ def remove_volume_letters(keep=None):
|
|||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
|
||||
|
||||
def run_diskpart(script):
|
||||
"""Run DiskPart script."""
|
||||
tempfile = r'{}\diskpart.script'.format(global_vars['Env']['TMP'])
|
||||
|
|
@ -321,6 +335,7 @@ def run_diskpart(script):
|
|||
sleep(2)
|
||||
return result
|
||||
|
||||
|
||||
def scan_disks():
|
||||
"""Get details about the attached disks"""
|
||||
disks = get_disks()
|
||||
|
|
@ -343,6 +358,7 @@ def scan_disks():
|
|||
# Done
|
||||
return disks
|
||||
|
||||
|
||||
def select_disk(title='Which disk?', disks=[]):
|
||||
"""Select a disk from the attached disks"""
|
||||
# Build menu
|
||||
|
|
@ -391,6 +407,7 @@ def select_disk(title='Which disk?', disks=[]):
|
|||
elif (selection == 'M'):
|
||||
raise GenericAbort
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from collections import OrderedDict
|
|||
from functions.sensors import *
|
||||
from functions.tmux import *
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
ATTRIBUTES = {
|
||||
'NVMe': {
|
||||
|
|
@ -83,13 +84,16 @@ TMUX_LAYOUT = OrderedDict({
|
|||
'Progress': {'x': SIDE_PANE_WIDTH, 'Check': True},
|
||||
})
|
||||
|
||||
|
||||
# Regex
|
||||
REGEX_ERROR_STATUS = re.compile('|'.join(STATUSES['RED']))
|
||||
|
||||
|
||||
# Error Classes
|
||||
class DeviceTooSmallError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# Classes
|
||||
class CpuObj():
|
||||
"""Object for tracking CPU specific data."""
|
||||
|
|
@ -130,6 +134,7 @@ class CpuObj():
|
|||
|
||||
return report
|
||||
|
||||
|
||||
class DiskObj():
|
||||
"""Object for tracking disk specific data."""
|
||||
def __init__(self, disk_path):
|
||||
|
|
@ -487,6 +492,7 @@ class DiskObj():
|
|||
for t in ['badblocks', 'I/O Benchmark']:
|
||||
self.disable_test(t, 'Denied')
|
||||
|
||||
|
||||
class State():
|
||||
"""Object to track device objects and overall state."""
|
||||
def __init__(self):
|
||||
|
|
@ -559,6 +565,7 @@ class State():
|
|||
if not skip_disk:
|
||||
self.disks.append(disk_obj)
|
||||
|
||||
|
||||
class TestObj():
|
||||
"""Object to track test data."""
|
||||
def __init__(self, dev, label=None, info_label=False):
|
||||
|
|
@ -589,6 +596,7 @@ class TestObj():
|
|||
self.status = build_status_string(
|
||||
self.label, 'Working', self.info_label)
|
||||
|
||||
|
||||
# Functions
|
||||
def build_outer_panes(state):
|
||||
"""Build top and side panes."""
|
||||
|
|
@ -611,6 +619,7 @@ def build_outer_panes(state):
|
|||
lines=SIDE_PANE_WIDTH,
|
||||
watch=state.progress_out)
|
||||
|
||||
|
||||
def build_status_string(label, status, info_label=False):
|
||||
"""Build status string with appropriate colors."""
|
||||
status_color = COLORS['CLEAR']
|
||||
|
|
@ -626,6 +635,7 @@ def build_status_string(label, status, info_label=False):
|
|||
s_w=SIDE_PANE_WIDTH-len(label),
|
||||
**COLORS)
|
||||
|
||||
|
||||
def fix_tmux_panes(state, tmux_layout):
|
||||
"""Fix pane sizes if the window has been resized."""
|
||||
needs_fixed = False
|
||||
|
|
@ -669,6 +679,7 @@ def fix_tmux_panes(state, tmux_layout):
|
|||
# Resize pane
|
||||
tmux_resize_pane(pane_id=target, **v)
|
||||
|
||||
|
||||
def generate_horizontal_graph(rates, oneline=False):
|
||||
"""Generate horizontal graph from rates, returns list."""
|
||||
graph = ['', '', '', '']
|
||||
|
|
@ -714,6 +725,7 @@ def generate_horizontal_graph(rates, oneline=False):
|
|||
else:
|
||||
return graph
|
||||
|
||||
|
||||
def get_graph_step(rate, scale=16):
|
||||
"""Get graph step based on rate and scale, returns int."""
|
||||
m_rate = rate / (1024**2)
|
||||
|
|
@ -726,6 +738,7 @@ def get_graph_step(rate, scale=16):
|
|||
break
|
||||
return step
|
||||
|
||||
|
||||
def get_read_rate(s):
|
||||
"""Get read rate in bytes/s from dd progress output."""
|
||||
real_rate = None
|
||||
|
|
@ -734,6 +747,7 @@ def get_read_rate(s):
|
|||
real_rate = convert_to_bytes(human_rate)
|
||||
return real_rate
|
||||
|
||||
|
||||
def menu_diags(state, args):
|
||||
"""Main menu to select and run HW tests."""
|
||||
args = [a.lower() for a in args]
|
||||
|
|
@ -840,12 +854,14 @@ def menu_diags(state, args):
|
|||
elif selection == 'S':
|
||||
run_hw_tests(state)
|
||||
|
||||
|
||||
def run_audio_test():
|
||||
"""Run audio test."""
|
||||
clear_screen()
|
||||
run_program(['hw-diags-audio'], check=False, pipe=False)
|
||||
pause('Press Enter to return to main menu... ')
|
||||
|
||||
|
||||
def run_badblocks_test(state, test):
|
||||
"""Run a read-only surface scan with badblocks."""
|
||||
# Bail early
|
||||
|
|
@ -939,6 +955,7 @@ def run_badblocks_test(state, test):
|
|||
# Cleanup
|
||||
tmux_kill_pane(state.panes['badblocks'])
|
||||
|
||||
|
||||
def run_hw_tests(state):
|
||||
"""Run enabled hardware tests."""
|
||||
print_standard('Scanning devices...')
|
||||
|
|
@ -1016,6 +1033,7 @@ def run_hw_tests(state):
|
|||
# Cleanup
|
||||
tmux_kill_pane(*state.panes.values())
|
||||
|
||||
|
||||
def run_io_benchmark(state, test):
|
||||
"""Run a read-only I/O benchmark using dd."""
|
||||
# Bail early
|
||||
|
|
@ -1173,11 +1191,13 @@ def run_io_benchmark(state, test):
|
|||
# Cleanup
|
||||
tmux_kill_pane(state.panes['io_benchmark'])
|
||||
|
||||
|
||||
def run_keyboard_test():
|
||||
"""Run keyboard test."""
|
||||
clear_screen()
|
||||
run_program(['xev', '-event', 'keyboard'], check=False, pipe=False)
|
||||
|
||||
|
||||
def run_mprime_test(state, test):
|
||||
"""Test CPU with Prime95 and track temps."""
|
||||
# Bail early
|
||||
|
|
@ -1371,12 +1391,14 @@ def run_mprime_test(state, test):
|
|||
tmux_kill_pane(state.panes['mprime'], state.panes['Temps'])
|
||||
test.monitor_proc.kill()
|
||||
|
||||
|
||||
def run_network_test():
|
||||
"""Run network test."""
|
||||
clear_screen()
|
||||
run_program(['hw-diags-network'], check=False, pipe=False)
|
||||
pause('Press Enter to return to main menu... ')
|
||||
|
||||
|
||||
def run_nvme_smart_tests(state, test):
|
||||
"""Run NVMe or SMART test for test.dev."""
|
||||
# Bail early
|
||||
|
|
@ -1520,6 +1542,7 @@ def run_nvme_smart_tests(state, test):
|
|||
# Done
|
||||
update_progress_pane(state)
|
||||
|
||||
|
||||
def secret_screensaver(screensaver=None):
|
||||
"""Show screensaver."""
|
||||
if screensaver == 'matrix':
|
||||
|
|
@ -1530,6 +1553,7 @@ def secret_screensaver(screensaver=None):
|
|||
raise Exception('Invalid screensaver')
|
||||
run_program(cmd, check=False, pipe=False)
|
||||
|
||||
|
||||
def show_report(report, log_report=False):
|
||||
"""Show report on screen and optionally save to log w/out color."""
|
||||
for line in report:
|
||||
|
|
@ -1537,6 +1561,7 @@ def show_report(report, log_report=False):
|
|||
if log_report:
|
||||
print_log(strip_colors(line))
|
||||
|
||||
|
||||
def show_results(state):
|
||||
"""Show results for all tests."""
|
||||
clear_screen()
|
||||
|
|
@ -1564,6 +1589,7 @@ def show_results(state):
|
|||
show_report(disk.generate_disk_report(), log_report=True)
|
||||
print_standard(' ')
|
||||
|
||||
|
||||
def update_main_options(state, selection, main_options):
|
||||
"""Update menu and state based on selection."""
|
||||
index = int(selection) - 1
|
||||
|
|
@ -1607,6 +1633,7 @@ def update_main_options(state, selection, main_options):
|
|||
# Done
|
||||
return main_options
|
||||
|
||||
|
||||
def update_io_progress(percent, rate, progress_file):
|
||||
"""Update I/O progress file."""
|
||||
bar_color = COLORS['CLEAR']
|
||||
|
|
@ -1631,6 +1658,7 @@ def update_io_progress(percent, rate, progress_file):
|
|||
with open(progress_file, 'a') as f:
|
||||
f.write(line)
|
||||
|
||||
|
||||
def update_progress_pane(state):
|
||||
"""Update progress file for side pane."""
|
||||
output = []
|
||||
|
|
@ -1658,6 +1686,7 @@ def update_progress_pane(state):
|
|||
with open(state.progress_out, 'w') as f:
|
||||
f.writelines(output)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -6,15 +6,6 @@ from operator import itemgetter
|
|||
from functions.common import *
|
||||
from functions.activation import *
|
||||
|
||||
# Regex
|
||||
REGEX_OFFICE = re.compile(
|
||||
r'(Microsoft (Office\s+'
|
||||
r'(365|Enterprise|Home|Pro(\s|fessional)'
|
||||
r'|Single|Small|Standard|Starter|Ultimate|system)'
|
||||
r'|Works[-\s\d]+\d)'
|
||||
r'|(Libre|Open|Star)\s*Office'
|
||||
r'|WordPerfect|Gnumeric|Abiword)',
|
||||
re.IGNORECASE)
|
||||
|
||||
# STATIC VARIABLES
|
||||
REG_PROFILE_LIST = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList'
|
||||
|
|
@ -55,6 +46,18 @@ SHELL_FOLDERS = {
|
|||
),
|
||||
}
|
||||
|
||||
|
||||
# Regex
|
||||
REGEX_OFFICE = re.compile(
|
||||
r'(Microsoft (Office\s+'
|
||||
r'(365|Enterprise|Home|Pro(\s|fessional)'
|
||||
r'|Single|Small|Standard|Starter|Ultimate|system)'
|
||||
r'|Works[-\s\d]+\d)'
|
||||
r'|(Libre|Open|Star)\s*Office'
|
||||
r'|WordPerfect|Gnumeric|Abiword)',
|
||||
re.IGNORECASE)
|
||||
|
||||
|
||||
def backup_file_list():
|
||||
"""Export current file listing for the system."""
|
||||
extract_item('Everything', silent=True)
|
||||
|
|
@ -66,6 +69,7 @@ def backup_file_list():
|
|||
global_vars['Env']['SYSTEMDRIVE']]
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def backup_power_plans():
|
||||
"""Export current power plans."""
|
||||
os.makedirs(r'{BackupDir}\Power Plans\{Date}'.format(
|
||||
|
|
@ -83,6 +87,7 @@ def backup_power_plans():
|
|||
cmd = ['powercfg', '-export', out, guid]
|
||||
run_program(cmd, check=False)
|
||||
|
||||
|
||||
def backup_registry(overwrite=False):
|
||||
"""Backup registry including user hives."""
|
||||
extract_item('erunt', silent=True)
|
||||
|
|
@ -97,6 +102,7 @@ def backup_registry(overwrite=False):
|
|||
cmd.append('/noconfirmdelete')
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def get_folder_size(path):
|
||||
"""Get (human-readable) size of folder passed, returns str."""
|
||||
size = 'Unknown'
|
||||
|
|
@ -119,6 +125,7 @@ def get_folder_size(path):
|
|||
size = human_readable_size(size)
|
||||
return size
|
||||
|
||||
|
||||
def get_installed_antivirus():
|
||||
"""Get list of installed Antivirus programs."""
|
||||
programs = []
|
||||
|
|
@ -149,6 +156,7 @@ def get_installed_antivirus():
|
|||
programs = ['No programs found']
|
||||
return programs
|
||||
|
||||
|
||||
def get_installed_office():
|
||||
"""Get list of installed Office programs."""
|
||||
programs = []
|
||||
|
|
@ -163,6 +171,7 @@ def get_installed_office():
|
|||
programs = ['No programs found']
|
||||
return programs
|
||||
|
||||
|
||||
def get_shell_path(folder, user='current'):
|
||||
"""Get shell path using knownpaths, returns str.
|
||||
|
||||
|
|
@ -189,6 +198,7 @@ def get_shell_path(folder, user='current'):
|
|||
|
||||
return path
|
||||
|
||||
|
||||
def get_user_data_paths(user):
|
||||
"""Get user data paths for provided user, returns dict."""
|
||||
hive_path = user['SID']
|
||||
|
|
@ -273,6 +283,7 @@ def get_user_data_paths(user):
|
|||
# Done
|
||||
return paths
|
||||
|
||||
|
||||
def get_user_folder_sizes(users):
|
||||
"""Update list(users) to include folder paths and sizes."""
|
||||
extract_item('du', filter='du*', silent=True)
|
||||
|
|
@ -293,6 +304,7 @@ def get_user_folder_sizes(users):
|
|||
u['Extra Folders'][folder]['Size'] = get_folder_size(
|
||||
u['Extra Folders'][folder]['Path'])
|
||||
|
||||
|
||||
def get_user_list():
|
||||
"""Get user list via WMIC, returns list of dicts."""
|
||||
users = []
|
||||
|
|
@ -325,6 +337,7 @@ def get_user_list():
|
|||
# Done
|
||||
return users
|
||||
|
||||
|
||||
def reg_path_exists(hive, path):
|
||||
"""Test if specified path exists, returns bool."""
|
||||
try:
|
||||
|
|
@ -334,6 +347,7 @@ def reg_path_exists(hive, path):
|
|||
else:
|
||||
return True
|
||||
|
||||
|
||||
def run_aida64():
|
||||
"""Run AIDA64 to save system reports."""
|
||||
extract_item('AIDA64', silent=True)
|
||||
|
|
@ -372,6 +386,7 @@ def run_aida64():
|
|||
'/TEXT', '/SILENT', '/SAFEST']
|
||||
run_program(cmd, check=False)
|
||||
|
||||
|
||||
def run_bleachbit(cleaners=None, preview=True):
|
||||
"""Run BleachBit preview and save log.
|
||||
|
||||
|
|
@ -404,6 +419,7 @@ def run_bleachbit(cleaners=None, preview=True):
|
|||
for line in out.stdout.decode().splitlines():
|
||||
f.write(line.strip() + '\n')
|
||||
|
||||
|
||||
def show_disk_usage(disk):
|
||||
"""Show free and used space for a specified disk."""
|
||||
print_standard('{:5}'.format(disk.device.replace('/', ' ')),
|
||||
|
|
@ -423,6 +439,7 @@ def show_disk_usage(disk):
|
|||
except Exception:
|
||||
print_warning('Unknown', timestamp=False)
|
||||
|
||||
|
||||
def show_free_space(indent=8, width=32):
|
||||
"""Show free space info for all fixed disks."""
|
||||
message = 'Free Space:'
|
||||
|
|
@ -436,6 +453,7 @@ def show_free_space(indent=8, width=32):
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def show_installed_ram():
|
||||
"""Show installed RAM."""
|
||||
mem = psutil.virtual_memory()
|
||||
|
|
@ -448,6 +466,7 @@ def show_installed_ram():
|
|||
else:
|
||||
print_error(human_readable_size(mem.total).strip(), timestamp=False)
|
||||
|
||||
|
||||
def show_os_activation():
|
||||
"""Show OS activation info."""
|
||||
act_str = get_activation_string()
|
||||
|
|
@ -458,6 +477,7 @@ def show_os_activation():
|
|||
else:
|
||||
print_error(act_str, timestamp=False)
|
||||
|
||||
|
||||
def show_os_name():
|
||||
"""Show extended OS name (including warnings)."""
|
||||
os_name = global_vars['OS']['DisplayName']
|
||||
|
|
@ -475,6 +495,7 @@ def show_os_name():
|
|||
else:
|
||||
print_standard(os_name, timestamp=False)
|
||||
|
||||
|
||||
def show_temp_files_size():
|
||||
"""Show total size of temp files identified by BleachBit."""
|
||||
size = None
|
||||
|
|
@ -488,6 +509,7 @@ def show_temp_files_size():
|
|||
else:
|
||||
print_standard(size, timestamp=False)
|
||||
|
||||
|
||||
def show_user_data_summary(indent=8, width=32):
|
||||
"""Print user data folder sizes for all users."""
|
||||
users = get_user_list()
|
||||
|
|
@ -520,6 +542,7 @@ def show_user_data_summary(indent=8, width=32):
|
|||
size = folders[folder].get('Size', 'Unknown'),
|
||||
path = folders[folder].get('Path', 'Unknown')))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
|||
sys.path.append(os.getcwd())
|
||||
from functions.common import *
|
||||
|
||||
|
||||
# REGEX
|
||||
REGEX_VALID_IP = re.compile(
|
||||
r'(10.\d+.\d+.\d+'
|
||||
|
|
@ -18,6 +19,7 @@ REGEX_VALID_IP = re.compile(
|
|||
r'|192.168.\d+.\d+)',
|
||||
re.IGNORECASE)
|
||||
|
||||
|
||||
def connect_to_network():
|
||||
"""Connect to network if not already connected."""
|
||||
net_ifs = psutil.net_if_addrs()
|
||||
|
|
@ -38,6 +40,7 @@ def connect_to_network():
|
|||
function = run_program,
|
||||
cmd = cmd)
|
||||
|
||||
|
||||
def is_connected():
|
||||
"""Check for a valid private IP."""
|
||||
devs = psutil.net_if_addrs()
|
||||
|
|
@ -49,6 +52,7 @@ def is_connected():
|
|||
# Else
|
||||
return False
|
||||
|
||||
|
||||
def show_valid_addresses():
|
||||
"""Show all valid private IP addresses assigned to the system."""
|
||||
devs = psutil.net_if_addrs()
|
||||
|
|
@ -58,6 +62,7 @@ def show_valid_addresses():
|
|||
# Valid IP found
|
||||
show_data(message=dev, data=family.address)
|
||||
|
||||
|
||||
def speedtest():
|
||||
"""Run a network speedtest using speedtest-cli."""
|
||||
result = run_program(['speedtest-cli', '--simple'])
|
||||
|
|
@ -67,6 +72,7 @@ def speedtest():
|
|||
output = [(a, float(b), c) for a, b, c in output]
|
||||
return ['{:10}{:6.2f} {}'.format(*line) for line in output]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
from functions.common import *
|
||||
|
||||
|
||||
# Regex
|
||||
REGEX_REGISTRY_DIRS = re.compile(
|
||||
r'^(config$|RegBack$|System32$|Transfer|Win)',
|
||||
re.IGNORECASE)
|
||||
REGEX_SOFTWARE_HIVE = re.compile(r'^Software$', re.IGNORECASE)
|
||||
|
||||
|
||||
def extract_keys():
|
||||
"""Extract keys from provided hives and return a dict."""
|
||||
keys = {}
|
||||
|
|
@ -43,6 +45,7 @@ def extract_keys():
|
|||
# Done
|
||||
return keys
|
||||
|
||||
|
||||
def list_clientdir_keys():
|
||||
"""List product keys found in hives inside the ClientDir."""
|
||||
keys = extract_keys()
|
||||
|
|
@ -57,6 +60,7 @@ def list_clientdir_keys():
|
|||
|
||||
return key_list
|
||||
|
||||
|
||||
def find_software_hives():
|
||||
"""Search for transferred SW hives and return a list."""
|
||||
hives = []
|
||||
|
|
@ -71,6 +75,7 @@ def find_software_hives():
|
|||
|
||||
return hives
|
||||
|
||||
|
||||
def get_product_keys():
|
||||
"""List product keys from saved report."""
|
||||
keys = []
|
||||
|
|
@ -86,6 +91,7 @@ def get_product_keys():
|
|||
else:
|
||||
return ['No product keys found']
|
||||
|
||||
|
||||
def run_produkey():
|
||||
"""Run ProduKey and save report in the ClientDir."""
|
||||
extract_item('ProduKey', silent=True)
|
||||
|
|
@ -107,6 +113,7 @@ def run_produkey():
|
|||
log_file]
|
||||
run_program(cmd, check=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
from functions.common import *
|
||||
|
||||
|
||||
def run_chkdsk(repair=False):
|
||||
"""Run CHKDSK scan or schedule offline repairs."""
|
||||
if repair:
|
||||
|
|
@ -9,6 +10,7 @@ def run_chkdsk(repair=False):
|
|||
else:
|
||||
run_chkdsk_scan()
|
||||
|
||||
|
||||
def run_chkdsk_scan():
|
||||
"""Run CHKDSK in a "split window" and report errors."""
|
||||
if global_vars['OS']['Version'] in ('8', '8.1', '10'):
|
||||
|
|
@ -32,6 +34,7 @@ def run_chkdsk_scan():
|
|||
for line in out.stdout.decode().splitlines():
|
||||
f.write(line.strip() + '\n')
|
||||
|
||||
|
||||
def run_chkdsk_offline():
|
||||
"""Set filesystem 'dirty bit' to force a chkdsk during next boot."""
|
||||
cmd = [
|
||||
|
|
@ -42,6 +45,7 @@ def run_chkdsk_offline():
|
|||
if int(out.returncode) > 0:
|
||||
raise GenericError
|
||||
|
||||
|
||||
def run_dism(repair=False):
|
||||
"""Run DISM to either scan or repair component store health."""
|
||||
if global_vars['OS']['Version'] in ('8', '8.1', '10'):
|
||||
|
|
@ -75,6 +79,7 @@ def run_dism(repair=False):
|
|||
else:
|
||||
raise UnsupportedOSError
|
||||
|
||||
|
||||
def run_kvrt():
|
||||
"""Run KVRT."""
|
||||
extract_item('KVRT', silent=True)
|
||||
|
|
@ -86,6 +91,7 @@ def run_kvrt():
|
|||
'-processlevel', '3']
|
||||
popen_program(cmd, pipe=False)
|
||||
|
||||
|
||||
def run_sfc_scan():
|
||||
"""Run SFC in a "split window" and report errors."""
|
||||
cmd = [
|
||||
|
|
@ -109,6 +115,7 @@ def run_sfc_scan():
|
|||
else:
|
||||
raise GenericError
|
||||
|
||||
|
||||
def run_tdsskiller():
|
||||
"""Run TDSSKiller."""
|
||||
extract_item('TDSSKiller', silent=True)
|
||||
|
|
@ -122,6 +129,7 @@ def run_tdsskiller():
|
|||
'-dcexact', '-tdlfs']
|
||||
run_program(cmd, pipe=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,19 +2,23 @@
|
|||
|
||||
from functions.common import *
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
REG_MSISERVER = r'HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\Network\MSIServer'
|
||||
|
||||
|
||||
def disable_safemode_msi():
|
||||
"""Disable MSI access under safemode."""
|
||||
cmd = ['reg', 'delete', REG_MSISERVER, '/f']
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def disable_safemode():
|
||||
"""Edit BCD to remove safeboot value."""
|
||||
cmd = ['bcdedit', '/deletevalue', '{default}', 'safeboot']
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def enable_safemode_msi():
|
||||
"""Enable MSI access under safemode."""
|
||||
cmd = ['reg', 'add', REG_MSISERVER, '/f']
|
||||
|
|
@ -23,15 +27,18 @@ def enable_safemode_msi():
|
|||
'/t', 'REG_SZ', '/d', 'Service', '/f']
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def enable_safemode():
|
||||
"""Edit BCD to set safeboot as default."""
|
||||
cmd = ['bcdedit', '/set', '{default}', 'safeboot', 'network']
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def reboot(delay=3):
|
||||
cmd = ['shutdown', '-r', '-t', '{}'.format(delay)]
|
||||
run_program(cmd, check=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import re
|
|||
|
||||
from functions.tmux import *
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
TEMP_LIMITS = {
|
||||
'GREEN': 60,
|
||||
|
|
@ -13,9 +14,11 @@ TEMP_LIMITS = {
|
|||
'RED': 90,
|
||||
}
|
||||
|
||||
|
||||
# REGEX
|
||||
REGEX_COLORS = re.compile(r'\033\[\d+;?1?m')
|
||||
|
||||
|
||||
def clear_temps(sensor_data):
|
||||
"""Clear saved temps but keep structure, returns dict."""
|
||||
for _section, _adapters in sensor_data.items():
|
||||
|
|
@ -23,6 +26,7 @@ def clear_temps(sensor_data):
|
|||
for _source, _data in _sources.items():
|
||||
_data['Temps'] = []
|
||||
|
||||
|
||||
def fix_sensor_str(s):
|
||||
"""Cleanup string and return str."""
|
||||
s = re.sub(r'^(\w+)-(\w+)-(\w+)', r'\1 (\2 \3)', s, re.IGNORECASE)
|
||||
|
|
@ -36,6 +40,7 @@ def fix_sensor_str(s):
|
|||
s = s.replace(' ', ' ')
|
||||
return s
|
||||
|
||||
|
||||
def generate_sensor_report(
|
||||
sensor_data, *temp_labels,
|
||||
colors=True, core_only=False):
|
||||
|
|
@ -73,6 +78,7 @@ def generate_sensor_report(
|
|||
# Done
|
||||
return report
|
||||
|
||||
|
||||
def get_colored_temp_str(temp):
|
||||
"""Get colored string based on temp, returns str."""
|
||||
try:
|
||||
|
|
@ -97,6 +103,7 @@ def get_colored_temp_str(temp):
|
|||
temp = temp,
|
||||
**COLORS)
|
||||
|
||||
|
||||
def get_raw_sensor_data():
|
||||
"""Read sensor data and return dict."""
|
||||
data = {}
|
||||
|
|
@ -110,6 +117,7 @@ def get_raw_sensor_data():
|
|||
|
||||
return data
|
||||
|
||||
|
||||
def get_sensor_data():
|
||||
"""Parse raw sensor data and return new dict."""
|
||||
json_data = get_raw_sensor_data()
|
||||
|
|
@ -141,6 +149,7 @@ def get_sensor_data():
|
|||
# Done
|
||||
return sensor_data
|
||||
|
||||
|
||||
def get_temp_str(temp, colors=True):
|
||||
"""Get temp string, returns str."""
|
||||
if colors:
|
||||
|
|
@ -154,6 +163,7 @@ def get_temp_str(temp, colors=True):
|
|||
'-' if temp < 0 else '',
|
||||
temp)
|
||||
|
||||
|
||||
def monitor_sensors(monitor_pane, monitor_file):
|
||||
"""Continually update sensor data and report to screen."""
|
||||
sensor_data = get_sensor_data()
|
||||
|
|
@ -166,6 +176,7 @@ def monitor_sensors(monitor_pane, monitor_file):
|
|||
if monitor_pane and not tmux_poll_pane(monitor_pane):
|
||||
break
|
||||
|
||||
|
||||
def save_average_temp(sensor_data, temp_label, seconds=10):
|
||||
"""Save average temps under temp_label, returns dict."""
|
||||
clear_temps(sensor_data)
|
||||
|
|
@ -181,6 +192,7 @@ def save_average_temp(sensor_data, temp_label, seconds=10):
|
|||
for _source, _data in _sources.items():
|
||||
_data[temp_label] = sum(_data['Temps']) / len(_data['Temps'])
|
||||
|
||||
|
||||
def update_sensor_data(sensor_data):
|
||||
"""Read sensors and update existing sensor_data, returns dict."""
|
||||
json_data = get_raw_sensor_data()
|
||||
|
|
@ -193,12 +205,14 @@ def update_sensor_data(sensor_data):
|
|||
_data['Max'] = max(_temp, _data['Max'])
|
||||
_data['Temps'].append(_temp)
|
||||
|
||||
|
||||
def join_columns(column1, column2, width=55):
|
||||
return '{:<{}}{}'.format(
|
||||
column1,
|
||||
55+len(column1)-len(REGEX_COLORS.sub('', column1)),
|
||||
column2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
from functions.common import *
|
||||
from functions.update import *
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
HKU = winreg.HKEY_USERS
|
||||
HKCR = winreg.HKEY_CLASSES_ROOT
|
||||
|
|
@ -128,6 +129,7 @@ VCR_REDISTS = [
|
|||
'/passive', '/norestart']},
|
||||
]
|
||||
|
||||
|
||||
def config_classicstart():
|
||||
"""Configure ClassicStart."""
|
||||
# User level, not system level
|
||||
|
|
@ -180,14 +182,17 @@ def config_classicstart():
|
|||
sleep(1)
|
||||
popen_program(cs_exe)
|
||||
|
||||
|
||||
def config_explorer_system():
|
||||
"""Configure Windows Explorer for all users."""
|
||||
write_registry_settings(SETTINGS_EXPLORER_SYSTEM, all_users=True)
|
||||
|
||||
|
||||
def config_explorer_user():
|
||||
"""Configure Windows Explorer for current user."""
|
||||
write_registry_settings(SETTINGS_EXPLORER_USER, all_users=False)
|
||||
|
||||
|
||||
def disable_windows_telemetry():
|
||||
"""Disable Windows 10 telemetry settings with O&O ShutUp10."""
|
||||
extract_item('ShutUp10', silent=True)
|
||||
|
|
@ -197,6 +202,7 @@ def disable_windows_telemetry():
|
|||
'/quiet']
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def update_clock():
|
||||
"""Set Timezone and sync clock."""
|
||||
run_program(['tzutil' ,'/s', WINDOWS_TIME_ZONE], check=False)
|
||||
|
|
@ -209,6 +215,7 @@ def update_clock():
|
|||
run_program(['net', 'start', 'w32ime'], check=False)
|
||||
run_program(['w32tm', '/resync', '/nowait'], check=False)
|
||||
|
||||
|
||||
def write_registry_settings(settings, all_users=False):
|
||||
"""Write registry values from custom dict of dicts."""
|
||||
hive = HKCU
|
||||
|
|
@ -228,6 +235,7 @@ def write_registry_settings(settings, all_users=False):
|
|||
for name, value in v.get('SZ Items', {}).items():
|
||||
winreg.SetValueEx(key, name, 0, winreg.REG_SZ, value)
|
||||
|
||||
|
||||
# Installations
|
||||
def install_adobe_reader():
|
||||
"""Install Adobe Reader."""
|
||||
|
|
@ -240,10 +248,12 @@ def install_adobe_reader():
|
|||
'EULA_ACCEPT=YES']
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def install_chrome_extensions():
|
||||
"""Install Google Chrome extensions for all users."""
|
||||
write_registry_settings(SETTINGS_GOOGLE_CHROME, all_users=True)
|
||||
|
||||
|
||||
def install_classicstart_skin():
|
||||
"""Extract ClassicStart skin to installation folder."""
|
||||
if global_vars['OS']['Version'] not in ('8', '8.1', '10'):
|
||||
|
|
@ -257,6 +267,7 @@ def install_classicstart_skin():
|
|||
os.makedirs(dest_path, exist_ok=True)
|
||||
shutil.copy(source, dest)
|
||||
|
||||
|
||||
def install_firefox_extensions():
|
||||
"""Install Firefox extensions for all users."""
|
||||
dist_path = r'{PROGRAMFILES}\Mozilla Firefox\distribution\extensions'.format(
|
||||
|
|
@ -277,6 +288,7 @@ def install_firefox_extensions():
|
|||
source_path]
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def install_ninite_bundle(mse=False):
|
||||
"""Run Ninite file(s) based on OS version."""
|
||||
if global_vars['OS']['Version'] in ('8', '8.1', '10'):
|
||||
|
|
@ -292,6 +304,7 @@ def install_ninite_bundle(mse=False):
|
|||
popen_program(r'{BaseDir}\Installers\Extras\Bundles\Legacy.exe'.format(
|
||||
**global_vars))
|
||||
|
||||
|
||||
def install_vcredists():
|
||||
"""Install all supported Visual C++ runtimes."""
|
||||
extract_item('_vcredists', silent=True)
|
||||
|
|
@ -307,16 +320,20 @@ def install_vcredists():
|
|||
|
||||
os.chdir(prev_dir)
|
||||
|
||||
|
||||
# Misc
|
||||
def open_device_manager():
|
||||
popen_program(['mmc', 'devmgmt.msc'])
|
||||
|
||||
|
||||
def open_windows_activation():
|
||||
popen_program(['slui'])
|
||||
|
||||
|
||||
def open_windows_updates():
|
||||
popen_program(['control', '/name', 'Microsoft.WindowsUpdate'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import ctypes
|
|||
|
||||
from functions.common import *
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
AUTORUNS_SETTINGS = {
|
||||
r'Software\Sysinternals\AutoRuns': {
|
||||
|
|
@ -26,6 +27,7 @@ AUTORUNS_SETTINGS = {
|
|||
},
|
||||
}
|
||||
|
||||
|
||||
def check_connection():
|
||||
"""Check if the system is online and optionally abort the script."""
|
||||
while True:
|
||||
|
|
@ -38,6 +40,7 @@ def check_connection():
|
|||
else:
|
||||
abort()
|
||||
|
||||
|
||||
def check_secure_boot_status(show_alert=False):
|
||||
"""Checks UEFI Secure Boot status via PowerShell."""
|
||||
boot_mode = get_boot_mode()
|
||||
|
|
@ -77,6 +80,7 @@ def check_secure_boot_status(show_alert=False):
|
|||
show_alert_box('Secure Boot ERROR')
|
||||
raise GenericError
|
||||
|
||||
|
||||
def get_boot_mode():
|
||||
"""Check if Windows is booted in UEFI or Legacy mode, returns str."""
|
||||
kernel = ctypes.windll.kernel32
|
||||
|
|
@ -98,6 +102,7 @@ def get_boot_mode():
|
|||
|
||||
return type_str
|
||||
|
||||
|
||||
def run_autoruns():
|
||||
"""Run AutoRuns in the background with VirusTotal checks enabled."""
|
||||
extract_item('Autoruns', filter='autoruns*', silent=True)
|
||||
|
|
@ -109,6 +114,7 @@ def run_autoruns():
|
|||
winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, value)
|
||||
popen_program(global_vars['Tools']['AutoRuns'], minimized=True)
|
||||
|
||||
|
||||
def run_hwinfo_sensors():
|
||||
"""Run HWiNFO sensors."""
|
||||
path = r'{BinDir}\HWiNFO'.format(**global_vars)
|
||||
|
|
@ -122,12 +128,14 @@ def run_hwinfo_sensors():
|
|||
f.write('SummaryOnly=0\n')
|
||||
popen_program(global_vars['Tools']['HWiNFO'])
|
||||
|
||||
|
||||
def run_nircmd(*cmd):
|
||||
"""Run custom NirCmd."""
|
||||
extract_item('NirCmd', silent=True)
|
||||
cmd = [global_vars['Tools']['NirCmd'], *cmd]
|
||||
run_program(cmd, check=False)
|
||||
|
||||
|
||||
def run_xmplay():
|
||||
"""Run XMPlay to test audio."""
|
||||
extract_item('XMPlay', silent=True)
|
||||
|
|
@ -141,6 +149,7 @@ def run_xmplay():
|
|||
# Open XMPlay
|
||||
popen_program(cmd)
|
||||
|
||||
|
||||
def run_hitmanpro():
|
||||
"""Run HitmanPro in the background."""
|
||||
extract_item('HitmanPro', silent=True)
|
||||
|
|
@ -150,6 +159,7 @@ def run_hitmanpro():
|
|||
r'/log={LogDir}\Tools\HitmanPro.txt'.format(**global_vars)]
|
||||
popen_program(cmd)
|
||||
|
||||
|
||||
def run_process_killer():
|
||||
"""Kill most running processes skipping those in the whitelist.txt."""
|
||||
# borrowed from TronScript (reddit.com/r/TronScript)
|
||||
|
|
@ -160,6 +170,7 @@ def run_process_killer():
|
|||
run_program(['ProcessKiller.exe', '/silent'], check=False)
|
||||
os.chdir(prev_dir)
|
||||
|
||||
|
||||
def run_rkill():
|
||||
"""Run RKill and cleanup afterwards."""
|
||||
extract_item('RKill', silent=True)
|
||||
|
|
@ -180,11 +191,13 @@ def run_rkill():
|
|||
dest = non_clobber_rename(dest)
|
||||
shutil.move(item.path, dest)
|
||||
|
||||
|
||||
def show_alert_box(message, title='Wizard Kit Warning'):
|
||||
"""Show Windows alert box with message."""
|
||||
message_box = ctypes.windll.user32.MessageBoxW
|
||||
message_box(None, message, title, 0x00001030)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
from functions.common import *
|
||||
|
||||
|
||||
def create_file(filepath):
|
||||
"""Create file if it doesn't exist."""
|
||||
if not os.path.exists(filepath):
|
||||
with open(filepath, 'w') as f:
|
||||
f.write('')
|
||||
|
||||
|
||||
def tmux_get_pane_size(pane_id=None):
|
||||
"""Get target, or current, pane size, returns tuple."""
|
||||
x = -1
|
||||
|
|
@ -29,6 +31,7 @@ def tmux_get_pane_size(pane_id=None):
|
|||
|
||||
return (x, y)
|
||||
|
||||
|
||||
def tmux_kill_all_panes(pane_id=None):
|
||||
"""Kill all tmux panes except the active pane or pane_id if specified."""
|
||||
cmd = ['tmux', 'kill-pane', '-a']
|
||||
|
|
@ -36,12 +39,14 @@ def tmux_kill_all_panes(pane_id=None):
|
|||
cmd.extend(['-t', pane_id])
|
||||
run_program(cmd, check=False)
|
||||
|
||||
|
||||
def tmux_kill_pane(*panes):
|
||||
"""Kill tmux pane by id."""
|
||||
cmd = ['tmux', 'kill-pane', '-t']
|
||||
for pane_id in panes:
|
||||
run_program(cmd+[pane_id], check=False)
|
||||
|
||||
|
||||
def tmux_poll_pane(pane_id):
|
||||
"""Check if pane exists, returns bool."""
|
||||
cmd = ['tmux', 'list-panes', '-F', '#D']
|
||||
|
|
@ -49,6 +54,7 @@ def tmux_poll_pane(pane_id):
|
|||
panes = result.stdout.decode().splitlines()
|
||||
return pane_id in panes
|
||||
|
||||
|
||||
def tmux_resize_pane(pane_id=None, x=None, y=None, **kwargs):
|
||||
"""Resize pane to specific hieght or width."""
|
||||
if not x and not y:
|
||||
|
|
@ -65,6 +71,7 @@ def tmux_resize_pane(pane_id=None, x=None, y=None, **kwargs):
|
|||
|
||||
run_program(cmd, check=False)
|
||||
|
||||
|
||||
def tmux_split_window(
|
||||
lines=None, percent=None,
|
||||
behind=False, vertical=False,
|
||||
|
|
@ -115,6 +122,7 @@ def tmux_split_window(
|
|||
result = run_program(cmd)
|
||||
return result.stdout.decode().strip()
|
||||
|
||||
|
||||
def tmux_update_pane(
|
||||
pane_id, command=None, working_dir=None,
|
||||
text=None, watch=None, watch_cmd='cat'):
|
||||
|
|
@ -142,6 +150,7 @@ def tmux_update_pane(
|
|||
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from settings.launchers import *
|
|||
from settings.music import *
|
||||
from settings.sources import *
|
||||
|
||||
|
||||
def compress_and_remove_item(item):
|
||||
"""Compress and delete an item unless an error is encountered."""
|
||||
try:
|
||||
|
|
@ -17,6 +18,7 @@ def compress_and_remove_item(item):
|
|||
else:
|
||||
remove_item(item.path)
|
||||
|
||||
|
||||
def compress_item(item):
|
||||
"""Compress an item in a 7-Zip archive using the ARCHIVE_PASSWORD."""
|
||||
# Prep
|
||||
|
|
@ -42,6 +44,7 @@ def compress_item(item):
|
|||
# Done
|
||||
os.chdir(prev_dir)
|
||||
|
||||
|
||||
def download_generic(out_dir, out_name, source_url):
|
||||
"""Downloads a file using requests."""
|
||||
## Code based on this Q&A: https://stackoverflow.com/q/16694907
|
||||
|
|
@ -59,10 +62,12 @@ def download_generic(out_dir, out_name, source_url):
|
|||
except:
|
||||
raise GenericError('Failed to download file.')
|
||||
|
||||
|
||||
def download_to_temp(out_name, source_url):
|
||||
"""Download a file to the TmpDir."""
|
||||
download_generic(global_vars['TmpDir'], out_name, source_url)
|
||||
|
||||
|
||||
def extract_generic(source, dest, mode='x', sz_args=[]):
|
||||
"""Extract a file to a destination."""
|
||||
cmd = [
|
||||
|
|
@ -73,12 +78,14 @@ def extract_generic(source, dest, mode='x', sz_args=[]):
|
|||
cmd.extend(sz_args)
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def extract_temp_to_bin(source, item, mode='x', sz_args=[]):
|
||||
"""Extract a file to the .bin folder."""
|
||||
source = r'{}\{}'.format(global_vars['TmpDir'], source)
|
||||
dest = r'{}\{}'.format(global_vars['BinDir'], item)
|
||||
extract_generic(source, dest, mode, sz_args)
|
||||
|
||||
|
||||
def extract_temp_to_cbin(source, item, mode='x', sz_args=[]):
|
||||
"""Extract a file to the .cbin folder."""
|
||||
source = r'{}\{}'.format(global_vars['TmpDir'], source)
|
||||
|
|
@ -88,6 +95,7 @@ def extract_temp_to_cbin(source, item, mode='x', sz_args=[]):
|
|||
shutil.copytree(include_path, dest)
|
||||
extract_generic(source, dest, mode, sz_args)
|
||||
|
||||
|
||||
def generate_launcher(section, name, options):
|
||||
"""Generate a launcher script."""
|
||||
# Prep
|
||||
|
|
@ -125,6 +133,7 @@ def generate_launcher(section, name, options):
|
|||
# f.writelines(out_text)
|
||||
f.write('\n'.join(out_text))
|
||||
|
||||
|
||||
def remove_item(item_path):
|
||||
"""Delete a file or folder."""
|
||||
if os.path.exists(item_path):
|
||||
|
|
@ -133,6 +142,7 @@ def remove_item(item_path):
|
|||
else:
|
||||
os.remove(item_path)
|
||||
|
||||
|
||||
def remove_from_kit(item):
|
||||
"""Delete a file or folder from the .bin/.cbin folders."""
|
||||
item_locations = []
|
||||
|
|
@ -144,11 +154,13 @@ def remove_from_kit(item):
|
|||
for item_path in item_locations:
|
||||
remove_item(item_path)
|
||||
|
||||
|
||||
def remove_from_temp(item):
|
||||
"""Delete a file or folder from the TmpDir folder."""
|
||||
item_path = r'{}\{}'.format(global_vars['TmpDir'], item)
|
||||
remove_item(item_path)
|
||||
|
||||
|
||||
def resolve_dynamic_url(source_url, regex):
|
||||
"""Scan source_url for a url using the regex provided; returns str."""
|
||||
# Load the download page
|
||||
|
|
@ -170,6 +182,7 @@ def resolve_dynamic_url(source_url, regex):
|
|||
# Return
|
||||
return url
|
||||
|
||||
|
||||
def scan_for_net_installers(server, family_name, min_year):
|
||||
"""Scan network shares for installers."""
|
||||
if not server['Mounted']:
|
||||
|
|
@ -200,7 +213,8 @@ def scan_for_net_installers(server, family_name, min_year):
|
|||
}
|
||||
umount_network_share(server)
|
||||
|
||||
## Data Recovery ##
|
||||
|
||||
# Data Recovery
|
||||
def update_testdisk():
|
||||
# Stop running processes
|
||||
for exe in ['fidentify_win.exe', 'photorec_win.exe',
|
||||
|
|
@ -226,7 +240,8 @@ def update_testdisk():
|
|||
# Cleanup
|
||||
remove_from_temp('testdisk_wip.zip')
|
||||
|
||||
## Data Transfers ##
|
||||
|
||||
# Data Transfers
|
||||
def update_fastcopy():
|
||||
## NOTE: Lives in .bin uncompressed
|
||||
# Stop running processes
|
||||
|
|
@ -266,6 +281,7 @@ def update_fastcopy():
|
|||
os.remove(r'{}\setup.exe'.format(_path, _installer))
|
||||
remove_from_temp('FastCopy.zip')
|
||||
|
||||
|
||||
def update_wimlib():
|
||||
# Stop running processes
|
||||
kill_process('wimlib-imagex.exe')
|
||||
|
|
@ -289,6 +305,7 @@ def update_wimlib():
|
|||
remove_from_temp('wimlib32.zip')
|
||||
remove_from_temp('wimlib64.zip')
|
||||
|
||||
|
||||
def update_xyplorer():
|
||||
# Stop running processes
|
||||
kill_process('XYplorerFree.exe')
|
||||
|
|
@ -305,7 +322,8 @@ def update_xyplorer():
|
|||
# Cleanup
|
||||
remove_from_temp('xyplorer_free.zip')
|
||||
|
||||
## Diagnostics ##
|
||||
|
||||
# Diagnostics
|
||||
def update_aida64():
|
||||
# Stop running processes
|
||||
kill_process('notepadplusplus.exe')
|
||||
|
|
@ -322,6 +340,7 @@ def update_aida64():
|
|||
# Cleanup
|
||||
remove_from_temp('aida64.zip')
|
||||
|
||||
|
||||
def update_autoruns():
|
||||
# Stop running processes
|
||||
kill_process('Autoruns.exe')
|
||||
|
|
@ -339,6 +358,7 @@ def update_autoruns():
|
|||
# Cleanup
|
||||
remove_from_temp('Autoruns.zip')
|
||||
|
||||
|
||||
def update_bleachbit():
|
||||
# Stop running processes
|
||||
kill_process('bleachbit.exe')
|
||||
|
|
@ -370,6 +390,7 @@ def update_bleachbit():
|
|||
remove_from_temp('bleachbit.zip')
|
||||
remove_from_temp('Winapp2.zip')
|
||||
|
||||
|
||||
def update_bluescreenview():
|
||||
# Stop running processes
|
||||
for exe in ['BlueScreenView.exe', 'BlueScreenView64.exe']:
|
||||
|
|
@ -394,6 +415,7 @@ def update_bluescreenview():
|
|||
remove_from_temp('bluescreenview32.zip')
|
||||
remove_from_temp('bluescreenview64.zip')
|
||||
|
||||
|
||||
def update_erunt():
|
||||
# Stop running processes
|
||||
kill_process('ERUNT.EXE')
|
||||
|
|
@ -410,6 +432,7 @@ def update_erunt():
|
|||
# Cleanup
|
||||
remove_from_temp('erunt.zip')
|
||||
|
||||
|
||||
def update_hitmanpro():
|
||||
# Stop running processes
|
||||
for exe in ['HitmanPro.exe', 'HitmanPro64.exe']:
|
||||
|
|
@ -423,6 +446,7 @@ def update_hitmanpro():
|
|||
download_generic(dest, 'HitmanPro.exe', SOURCE_URLS['HitmanPro32'])
|
||||
download_generic(dest, 'HitmanPro64.exe', SOURCE_URLS['HitmanPro64'])
|
||||
|
||||
|
||||
def update_hwinfo():
|
||||
## NOTE: Lives in .bin uncompressed
|
||||
# Stop running processes
|
||||
|
|
@ -438,6 +462,7 @@ def update_hwinfo():
|
|||
# Cleanup
|
||||
remove_from_temp('HWiNFO.zip')
|
||||
|
||||
|
||||
def update_nircmd():
|
||||
# Stop running processes
|
||||
for exe in ['nircmdc.exe', 'nircmdc64.exe']:
|
||||
|
|
@ -461,6 +486,7 @@ def update_nircmd():
|
|||
remove_from_temp('nircmd32.zip')
|
||||
remove_from_temp('nircmd64.zip')
|
||||
|
||||
|
||||
def update_produkey():
|
||||
# Stop running processes
|
||||
for exe in ['ProduKey.exe', 'ProduKey64.exe']:
|
||||
|
|
@ -484,7 +510,8 @@ def update_produkey():
|
|||
remove_from_temp('produkey32.zip')
|
||||
remove_from_temp('produkey64.zip')
|
||||
|
||||
## Drivers ##
|
||||
|
||||
# Drivers
|
||||
def update_intel_rst():
|
||||
# Remove existing folders
|
||||
remove_from_kit('Intel RST')
|
||||
|
|
@ -500,6 +527,7 @@ def update_intel_rst():
|
|||
for name, url in RST_SOURCES.items():
|
||||
download_generic(dest, name, url)
|
||||
|
||||
|
||||
def update_intel_ssd_toolbox():
|
||||
# Remove existing folders
|
||||
remove_from_kit('Intel SSD Toolbox.exe')
|
||||
|
|
@ -510,6 +538,7 @@ def update_intel_ssd_toolbox():
|
|||
'Intel SSD Toolbox.exe',
|
||||
SOURCE_URLS['Intel SSD Toolbox'])
|
||||
|
||||
|
||||
def update_samsung_magician():
|
||||
# Remove existing folders
|
||||
remove_from_kit('Samsung Magician.exe')
|
||||
|
|
@ -528,6 +557,7 @@ def update_samsung_magician():
|
|||
# Cleanup
|
||||
remove_from_temp('Samsung Magician.zip')
|
||||
|
||||
|
||||
def update_sdi_origin():
|
||||
# Download aria2
|
||||
download_to_temp('aria2.zip', SOURCE_URLS['aria2'])
|
||||
|
|
@ -585,7 +615,8 @@ def update_sdi_origin():
|
|||
remove_from_temp('sdio.torrent')
|
||||
remove_from_temp('sdio_themes.zip')
|
||||
|
||||
## Installers ##
|
||||
|
||||
# Installers
|
||||
def update_adobe_reader_dc():
|
||||
# Prep
|
||||
dest = r'{}\Installers\Extras\Office'.format(
|
||||
|
|
@ -601,6 +632,7 @@ def update_adobe_reader_dc():
|
|||
download_generic(
|
||||
dest, 'Adobe Reader DC.exe', SOURCE_URLS['Adobe Reader DC'])
|
||||
|
||||
|
||||
def update_macs_fan_control():
|
||||
# Prep
|
||||
dest = r'{}\Installers'.format(
|
||||
|
|
@ -616,6 +648,7 @@ def update_macs_fan_control():
|
|||
download_generic(
|
||||
dest, 'Macs Fan Control.exe', SOURCE_URLS['Macs Fan Control'])
|
||||
|
||||
|
||||
def update_office():
|
||||
# Remove existing folders
|
||||
remove_from_kit('_Office')
|
||||
|
|
@ -644,6 +677,7 @@ def update_office():
|
|||
# Cleanup
|
||||
remove_from_temp('odt{}.exe'.format(year))
|
||||
|
||||
|
||||
def update_classic_start_skin():
|
||||
# Remove existing folders
|
||||
remove_from_kit('ClassicStartSkin')
|
||||
|
|
@ -654,6 +688,7 @@ def update_classic_start_skin():
|
|||
'Metro-Win10-Black.skin7',
|
||||
SOURCE_URLS['ClassicStartSkin'])
|
||||
|
||||
|
||||
def update_vcredists():
|
||||
# Remove existing folders
|
||||
remove_from_kit('_vcredists')
|
||||
|
|
@ -674,6 +709,7 @@ def update_vcredists():
|
|||
'vcredist.exe',
|
||||
VCREDIST_SOURCES[year][bit])
|
||||
|
||||
|
||||
def update_one_ninite(section, dest, name, url, indent=8, width=40):
|
||||
# Prep
|
||||
url = 'https://ninite.com/{}/ninite.exe'.format(url)
|
||||
|
|
@ -690,6 +726,7 @@ def update_one_ninite(section, dest, name, url, indent=8, width=40):
|
|||
remove_item(installer_dest)
|
||||
shutil.copy(r'{}\{}'.format(dest, name), installer_dest)
|
||||
|
||||
|
||||
def update_all_ninite(indent=8, width=40, other_results={}):
|
||||
print_info('{}Ninite'.format(' '*int(indent/2)))
|
||||
for section in sorted(NINITE_SOURCES.keys()):
|
||||
|
|
@ -700,7 +737,8 @@ def update_all_ninite(indent=8, width=40, other_results={}):
|
|||
other_results=other_results, indent=indent, width=width,
|
||||
section=section, dest=dest, name=name, url=url)
|
||||
|
||||
## Misc ##
|
||||
|
||||
# Misc
|
||||
def update_caffeine():
|
||||
# Stop running processes
|
||||
kill_process('caffeine.exe')
|
||||
|
|
@ -717,6 +755,7 @@ def update_caffeine():
|
|||
# Cleanup
|
||||
remove_from_temp('caffeine.zip')
|
||||
|
||||
|
||||
def update_du():
|
||||
# Stop running processes
|
||||
kill_process('du.exe')
|
||||
|
|
@ -734,6 +773,7 @@ def update_du():
|
|||
# Cleanup
|
||||
remove_from_temp('du.zip')
|
||||
|
||||
|
||||
def update_everything():
|
||||
# Stop running processes
|
||||
for exe in ['Everything.exe', 'Everything64.exe']:
|
||||
|
|
@ -758,6 +798,7 @@ def update_everything():
|
|||
remove_from_temp('everything32.zip')
|
||||
remove_from_temp('everything64.zip')
|
||||
|
||||
|
||||
def update_firefox_ublock_origin():
|
||||
# Remove existing folders
|
||||
remove_from_kit('FirefoxExtensions')
|
||||
|
|
@ -768,6 +809,7 @@ def update_firefox_ublock_origin():
|
|||
'ublock_origin.xpi',
|
||||
SOURCE_URLS['Firefox uBO'])
|
||||
|
||||
|
||||
def update_notepadplusplus():
|
||||
# Stop running processes
|
||||
kill_process('notepadplusplus.exe')
|
||||
|
|
@ -788,6 +830,7 @@ def update_notepadplusplus():
|
|||
# Cleanup
|
||||
remove_from_temp('npp.7z')
|
||||
|
||||
|
||||
def update_putty():
|
||||
# Stop running processes
|
||||
kill_process('PUTTY.EXE')
|
||||
|
|
@ -804,6 +847,7 @@ def update_putty():
|
|||
# Cleanup
|
||||
remove_from_temp('putty.zip')
|
||||
|
||||
|
||||
def update_wiztree():
|
||||
# Stop running processes
|
||||
for process in ['WizTree.exe', 'WizTree64.exe']:
|
||||
|
|
@ -822,6 +866,7 @@ def update_wiztree():
|
|||
# Cleanup
|
||||
remove_from_temp('wiztree.zip')
|
||||
|
||||
|
||||
def update_xmplay():
|
||||
# Stop running processes
|
||||
kill_process('xmplay.exe')
|
||||
|
|
@ -877,7 +922,8 @@ def update_xmplay():
|
|||
remove_from_temp('xmp-rar.zip')
|
||||
remove_from_temp('WAModern.zip')
|
||||
|
||||
## Repairs ##
|
||||
|
||||
# Repairs
|
||||
def update_adwcleaner():
|
||||
# Stop running processes
|
||||
kill_process('AdwCleaner.exe')
|
||||
|
|
@ -891,6 +937,7 @@ def update_adwcleaner():
|
|||
'AdwCleaner.exe',
|
||||
SOURCE_URLS['AdwCleaner'])
|
||||
|
||||
|
||||
def update_kvrt():
|
||||
# Stop running processes
|
||||
kill_process('KVRT.exe')
|
||||
|
|
@ -904,6 +951,7 @@ def update_kvrt():
|
|||
'KVRT.exe',
|
||||
SOURCE_URLS['KVRT'])
|
||||
|
||||
|
||||
def update_rkill():
|
||||
# Stop running processes
|
||||
kill_process('RKill.exe')
|
||||
|
|
@ -918,6 +966,7 @@ def update_rkill():
|
|||
download_generic(
|
||||
r'{}\RKill'.format(global_vars['CBinDir']), 'RKill.exe', url)
|
||||
|
||||
|
||||
def update_tdsskiller():
|
||||
# Stop running processes
|
||||
kill_process('TDSSKiller.exe')
|
||||
|
|
@ -931,7 +980,8 @@ def update_tdsskiller():
|
|||
'TDSSKiller.exe',
|
||||
SOURCE_URLS['TDSSKiller'])
|
||||
|
||||
## Uninstallers ##
|
||||
|
||||
# Uninstallers
|
||||
def update_iobit_uninstaller():
|
||||
# Stop running processes
|
||||
kill_process('IObitUninstallerPortable.exe')
|
||||
|
|
@ -954,6 +1004,7 @@ def update_iobit_uninstaller():
|
|||
# Cleanup
|
||||
remove_from_kit('IObitUninstallerPortable.exe')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
from functions.data import *
|
||||
from functions.disk import *
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
WINDOWS_VERSIONS = [
|
||||
{'Name': 'Windows 7 Home Basic',
|
||||
|
|
@ -35,6 +36,7 @@ WINDOWS_VERSIONS = [
|
|||
'Image Name': 'Windows 10 Pro'},
|
||||
]
|
||||
|
||||
|
||||
def find_windows_image(windows_version):
|
||||
"""Search for a Windows source image file, returns dict.
|
||||
|
||||
|
|
@ -85,6 +87,7 @@ def find_windows_image(windows_version):
|
|||
windows_version['Name']))
|
||||
raise GenericAbort
|
||||
|
||||
|
||||
def format_disk(disk, use_gpt):
|
||||
"""Format disk for use as a Windows OS disk."""
|
||||
if use_gpt:
|
||||
|
|
@ -92,6 +95,7 @@ def format_disk(disk, use_gpt):
|
|||
else:
|
||||
format_mbr(disk)
|
||||
|
||||
|
||||
def format_gpt(disk):
|
||||
"""Format disk for use as a Windows OS disk using the GPT layout."""
|
||||
script = [
|
||||
|
|
@ -126,6 +130,7 @@ def format_gpt(disk):
|
|||
# Run
|
||||
run_diskpart(script)
|
||||
|
||||
|
||||
def format_mbr(disk):
|
||||
"""Format disk for use as a Windows OS disk using the MBR layout."""
|
||||
script = [
|
||||
|
|
@ -155,6 +160,7 @@ def format_mbr(disk):
|
|||
# Run
|
||||
run_diskpart(script)
|
||||
|
||||
|
||||
def mount_windows_share():
|
||||
"""Mount the Windows images share unless already mounted."""
|
||||
if not WINDOWS_SERVER['Mounted']:
|
||||
|
|
@ -163,6 +169,7 @@ def mount_windows_share():
|
|||
# error by trying to mount the same server with multiple credentials.
|
||||
mount_network_share(WINDOWS_SERVER, read_write=True)
|
||||
|
||||
|
||||
def select_windows_version():
|
||||
"""Select Windows version from a menu, returns dict."""
|
||||
actions = [
|
||||
|
|
@ -180,6 +187,7 @@ def select_windows_version():
|
|||
elif selection == 'M':
|
||||
raise GenericAbort
|
||||
|
||||
|
||||
def setup_windows(windows_image, windows_version):
|
||||
"""Apply a Windows image to W:"""
|
||||
cmd = [
|
||||
|
|
@ -192,6 +200,7 @@ def setup_windows(windows_image, windows_version):
|
|||
cmd.extend(windows_image['Glob'])
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'):
|
||||
"""Setup the WinRE partition."""
|
||||
win = r'{}:\Windows'.format(windows_letter)
|
||||
|
|
@ -210,6 +219,7 @@ def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'):
|
|||
'/target', win]
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def update_boot_partition(system_letter='S', windows_letter='W', mode='ALL'):
|
||||
"""Setup the Windows boot partition."""
|
||||
cmd = [
|
||||
|
|
@ -220,6 +230,7 @@ def update_boot_partition(system_letter='S', windows_letter='W', mode='ALL'):
|
|||
'/f', mode]
|
||||
run_program(cmd)
|
||||
|
||||
|
||||
def wim_contains_image(filename, imagename):
|
||||
"""Check if an ESD/WIM contains the specified image, returns bool."""
|
||||
cmd = [
|
||||
|
|
@ -234,6 +245,7 @@ def wim_contains_image(filename, imagename):
|
|||
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from functions.backup import *
|
|||
from functions.disk import *
|
||||
from functions.windows_setup import *
|
||||
|
||||
|
||||
# STATIC VARIABLES
|
||||
FAST_COPY_PE_ARGS = [
|
||||
'/cmd=noexist_only',
|
||||
|
|
@ -50,6 +51,7 @@ PE_TOOLS = {
|
|||
},
|
||||
}
|
||||
|
||||
|
||||
def check_pe_tools():
|
||||
"""Fix tool paths for WinPE layout."""
|
||||
for k in PE_TOOLS.keys():
|
||||
|
|
@ -61,6 +63,7 @@ def check_pe_tools():
|
|||
global_vars['Tools']['wimlib-imagex'],
|
||||
re.IGNORECASE)
|
||||
|
||||
|
||||
def menu_backup():
|
||||
"""Take backup images of partition(s) in the WIM format."""
|
||||
errors = False
|
||||
|
|
@ -211,6 +214,7 @@ def menu_backup():
|
|||
sleep(30)
|
||||
pause('\nPress Enter to return to main menu... ')
|
||||
|
||||
|
||||
def menu_root():
|
||||
"""Main WinPE menu."""
|
||||
check_pe_tools()
|
||||
|
|
@ -249,6 +253,7 @@ def menu_root():
|
|||
else:
|
||||
sys.exit()
|
||||
|
||||
|
||||
def menu_setup():
|
||||
"""Format a disk, apply a Windows image, and create boot files."""
|
||||
errors = False
|
||||
|
|
@ -409,6 +414,7 @@ def menu_setup():
|
|||
sleep(30)
|
||||
pause('\nPress Enter to return to main menu... ')
|
||||
|
||||
|
||||
def menu_tools():
|
||||
"""Tool launcher menu."""
|
||||
tools = [{'Name': k} for k in sorted(PE_TOOLS.keys())]
|
||||
|
|
@ -438,6 +444,7 @@ def menu_tools():
|
|||
elif (selection == 'M'):
|
||||
break
|
||||
|
||||
|
||||
def select_minidump_path():
|
||||
"""Select BSOD minidump path from a menu."""
|
||||
dumps = []
|
||||
|
|
@ -467,6 +474,7 @@ def select_minidump_path():
|
|||
main_entries = dumps)
|
||||
return dumps[int(selection) - 1]['Name']
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("This file is not meant to be called directly.")
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,13 @@ os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
|||
sys.path.append(os.getcwd())
|
||||
from functions.network import *
|
||||
|
||||
|
||||
def check_connection():
|
||||
if not is_connected():
|
||||
# Raise to cause NS in try_and_print()
|
||||
raise Exception
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
# Prep
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ init_global_vars()
|
|||
|
||||
REGEX_DOC_FILES = re.compile(r'\.docx?$', re.IGNORECASE)
|
||||
|
||||
|
||||
def scan_for_docs(path):
|
||||
for entry in os.scandir(path):
|
||||
if entry.is_dir(follow_symlinks=False):
|
||||
|
|
@ -29,6 +30,7 @@ def scan_for_docs(path):
|
|||
elif entry.is_file and REGEX_DOC_FILES.search(entry.name):
|
||||
yield entry
|
||||
|
||||
|
||||
def scan_file(file_path, search):
|
||||
match = False
|
||||
try:
|
||||
|
|
@ -45,6 +47,7 @@ def scan_file(file_path, search):
|
|||
|
||||
return entry.path if match else None
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
# Prep
|
||||
|
|
|
|||
Loading…
Reference in a new issue