diff --git a/.bin/Scripts/Launch.cmd b/.bin/Scripts/Launch.cmd
index f7080adb..0a0330c6 100644
--- a/.bin/Scripts/Launch.cmd
+++ b/.bin/Scripts/Launch.cmd
@@ -279,9 +279,9 @@ rem Create VB script
mkdir "%bin%\tmp" 2>nul
echo Set UAC = CreateObject^("Shell.Application"^) > "%bin%\tmp\Elevate.vbs"
if defined L_NCMD (
- echo UAC.ShellExecute "%PYTHON%", """%script%""", "", "runas", 3 >> "%bin%\tmp\Elevate.vbs"
+ echo UAC.ShellExecute "%PYTHON%", """%script%"" %L_ARGS%", "", "runas", 3 >> "%bin%\tmp\Elevate.vbs"
) else (
- echo UAC.ShellExecute "%CON%", "-run ""%PYTHON%"" ""%script%"" -new_console:n", "", "runas", 1 >> "%bin%\tmp\Elevate.vbs"
+ echo UAC.ShellExecute "%CON%", "-run ""%PYTHON%"" ""%script%"" %L_ARGS% -new_console:n", "", "runas", 1 >> "%bin%\tmp\Elevate.vbs"
)
rem Run
@@ -290,9 +290,9 @@ goto Exit
:LaunchPyScriptUser
if defined L_NCMD (
- start "" "%PYTHON%" "%script%" || goto ErrorUnknown
+ start "" "%PYTHON%" "%script%" %L_ARGS% || goto ErrorUnknown
) else (
- start "" "%CON%" -run "%PYTHON%" "%script%" -new_console:n || goto ErrorUnknown
+ start "" "%CON%" -run "%PYTHON%" "%script%" %L_ARGS% -new_console:n || goto ErrorUnknown
)
goto Exit
@@ -332,7 +332,7 @@ echo. Executable Working Dir Program Args [L_7ZIP] [L_ELEV] [L__CLI]
echo. Folder Folder '.' [L_7ZIP]
echo. Office Year Product [L_7ZIP]
echo. PSScript Scripts Script [L_7ZIP] [L_ELEV] [L_NCMD]
-echo. PyScript Scripts Script [L_7ZIP] [L_ELEV] [L_NCMD]
+echo. PyScript Scripts Script Args [L_7ZIP] [L_ELEV] [L_NCMD]
echo. QuickBooks Year Product [L_7ZIP]
echo.
echo.L_7ZIP: Extra arguments for 7-Zip (in the :ExtractCBin label)
diff --git a/.bin/Scripts/Launcher_Template.cmd b/.bin/Scripts/Launcher_Template.cmd
index 90b15482..01d1758d 100644
--- a/.bin/Scripts/Launcher_Template.cmd
+++ b/.bin/Scripts/Launcher_Template.cmd
@@ -17,7 +17,7 @@ call :SetTitle Launcher
rem EXTRA_CODE
:DefineLaunch
-:: See %bin%\SCripts\Launch.cmd for details under :Usage label
+:: See %bin%\Scripts\Launch.cmd for details under :Usage label
set L_TYPE=
set L_PATH=
set L_ITEM=
@@ -110,4 +110,4 @@ goto Exit
:: Cleanup and exit ::
:Exit
endlocal
-exit /b %errorlevel%
\ No newline at end of file
+exit /b %errorlevel%
diff --git a/.bin/Scripts/activate.py b/.bin/Scripts/activate.py
index 3555c46a..642e5edd 100644
--- a/.bin/Scripts/activate.py
+++ b/.bin/Scripts/activate.py
@@ -39,7 +39,7 @@ if __name__ == '__main__':
selection = menu_select(
'{}: Windows Activation Menu'.format(KIT_NAME_FULL),
main_entries=activation_methods, action_entries=actions)
-
+
if (selection.isnumeric()):
result = try_and_print(
message = activation_methods[int(selection)-1]['Name'],
diff --git a/.bin/Scripts/borrowed/sensors.py b/.bin/Scripts/borrowed/sensors.py
index 847f2619..39b00a4f 100644
--- a/.bin/Scripts/borrowed/sensors.py
+++ b/.bin/Scripts/borrowed/sensors.py
@@ -35,7 +35,7 @@ class feature(Structure):
_fields_ = [("name", c_char_p),
("number", c_int),
("type", c_int)]
-
+
# sensors_feature_type
IN = 0x00
FAN = 0x01
@@ -71,10 +71,10 @@ COMPUTE_MAPPING = 4
def init(cfg_file = None):
file = _libc.fopen(cfg_file.encode("utf-8"), "r") if cfg_file is not None else None
-
+
if _hdl.sensors_init(file) != 0:
raise Exception("sensors_init failed")
-
+
if file is not None:
_libc.fclose(file)
@@ -84,10 +84,10 @@ def cleanup():
def parse_chip_name(orig_name):
ret = chip_name()
err= _hdl.sensors_parse_chip_name(orig_name.encode("utf-8"), byref(ret))
-
+
if err < 0:
raise Exception(strerror(err))
-
+
return ret
def strerror(errnum):
@@ -101,10 +101,10 @@ def get_detected_chips(match, nr):
@return: (chip, next nr to query)
"""
_nr = c_int(nr)
-
+
if match is not None:
match = byref(match)
-
+
chip = _hdl.sensors_get_detected_chips(match, byref(_nr))
chip = chip.contents if bool(chip) else None
return chip, _nr.value
@@ -115,10 +115,10 @@ def chip_snprintf_name(chip, buffer_size=200):
"""
ret = create_string_buffer(buffer_size)
err = _hdl.sensors_snprintf_chip_name(ret, buffer_size, byref(chip))
-
+
if err < 0:
raise Exception(strerror(err))
-
+
return ret.value.decode("utf-8")
def do_chip_sets(chip):
@@ -128,7 +128,7 @@ def do_chip_sets(chip):
err = _hdl.sensors_do_chip_sets(byref(chip))
if err < 0:
raise Exception(strerror(err))
-
+
def get_adapter_name(bus):
return _hdl.sensors_get_adapter_name(byref(bus)).decode("utf-8")
@@ -177,60 +177,60 @@ class ChipIterator:
def __init__(self, match = None):
self.match = parse_chip_name(match) if match is not None else None
self.nr = 0
-
+
def __iter__(self):
return self
-
+
def __next__(self):
chip, self.nr = get_detected_chips(self.match, self.nr)
-
+
if chip is None:
raise StopIteration
-
+
return chip
-
+
def __del__(self):
if self.match is not None:
free_chip_name(self.match)
-
+
def next(self): # python2 compability
return self.__next__()
-
+
class FeatureIterator:
def __init__(self, chip):
self.chip = chip
self.nr = 0
-
+
def __iter__(self):
return self
-
+
def __next__(self):
feature, self.nr = get_features(self.chip, self.nr)
-
+
if feature is None:
raise StopIteration
-
+
return feature
def next(self): # python2 compability
return self.__next__()
-
+
class SubFeatureIterator:
def __init__(self, chip, feature):
self.chip = chip
self.feature = feature
self.nr = 0
-
+
def __iter__(self):
return self
-
+
def __next__(self):
subfeature, self.nr = get_all_subfeatures(self.chip, self.feature, self.nr)
-
+
if subfeature is None:
raise StopIteration
-
+
return subfeature
-
+
def next(self): # python2 compability
return self.__next__()
diff --git a/.bin/Scripts/cbs_fix.py b/.bin/Scripts/cbs_fix.py
index a3b40a8d..9a8ff10c 100644
--- a/.bin/Scripts/cbs_fix.py
+++ b/.bin/Scripts/cbs_fix.py
@@ -10,7 +10,7 @@ from functions.cleanup import *
from functions.data import *
init_global_vars()
os.system('title {}: CBS Cleanup'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\CBS Cleanup.log'.format(**global_vars)
+set_log_file('CBS Cleanup.log')
if __name__ == '__main__':
try:
@@ -20,18 +20,18 @@ if __name__ == '__main__':
folder_path = r'{}\Backups'.format(KIT_NAME_SHORT)
dest = select_destination(folder_path=folder_path,
prompt='Which disk are we using for temp data and backup?')
-
+
# Show details
print_info('{}: CBS Cleanup Tool\n'.format(KIT_NAME_FULL))
show_data('Backup / Temp path:', dest)
print_standard('\n')
if (not ask('Proceed with CBS cleanup?')):
abort()
-
+
# Run Cleanup
try_and_print(message='Running cleanup...', function=cleanup_cbs,
cs='Done', dest_folder=dest)
-
+
# Done
print_standard('\nDone.')
pause("Press Enter to exit...")
diff --git a/.bin/Scripts/check_disk.py b/.bin/Scripts/check_disk.py
index 734319f0..7e59fb2b 100644
--- a/.bin/Scripts/check_disk.py
+++ b/.bin/Scripts/check_disk.py
@@ -9,7 +9,7 @@ sys.path.append(os.getcwd())
from functions.repairs import *
init_global_vars()
os.system('title {}: Check Disk Tool'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\Check Disk.log'.format(**global_vars)
+set_log_file('Check Disk.log')
if __name__ == '__main__':
try:
@@ -45,7 +45,7 @@ if __name__ == '__main__':
cs=cs, other_results=other_results, repair=repair)
else:
abort()
-
+
# Done
print_success('Done.')
pause("Press Enter to exit...")
diff --git a/.bin/Scripts/dism.py b/.bin/Scripts/dism.py
index 1c88e51b..e49a9512 100644
--- a/.bin/Scripts/dism.py
+++ b/.bin/Scripts/dism.py
@@ -9,7 +9,7 @@ sys.path.append(os.getcwd())
from functions.repairs import *
init_global_vars()
os.system('title {}: DISM helper Tool'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\DISM helper tool.log'.format(**global_vars)
+set_log_file('DISM Helper.log')
if __name__ == '__main__':
try:
@@ -46,7 +46,7 @@ if __name__ == '__main__':
other_results=other_results, repair=repair)
else:
abort()
-
+
# Done
print_success('Done.')
pause("Press Enter to exit...")
diff --git a/.bin/Scripts/functions/activation.py b/.bin/Scripts/functions/activation.py
index f54d1dca..24436418 100644
--- a/.bin/Scripts/functions/activation.py
+++ b/.bin/Scripts/functions/activation.py
@@ -59,7 +59,7 @@ def windows_is_activated():
['cscript', '//nologo', SLMGR, '/xpr'], check=False,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
activation_string = activation_string.stdout.decode()
-
+
return bool(activation_string and 'permanent' in activation_string)
if __name__ == '__main__':
diff --git a/.bin/Scripts/functions/backup.py b/.bin/Scripts/functions/backup.py
index e33cea2c..d872c4d0 100644
--- a/.bin/Scripts/functions/backup.py
+++ b/.bin/Scripts/functions/backup.py
@@ -16,7 +16,7 @@ def backup_partition(disk, par):
"""Create a backup image of a partition."""
if par.get('Image Exists', False) or par['Number'] in disk['Bad Partitions']:
raise GenericAbort
-
+
cmd = [
global_vars['Tools']['wimlib-imagex'],
'capture',
@@ -48,7 +48,7 @@ def get_volume_display_name(mountpoint):
serial_number = None
max_component_length = None
file_system_flags = None
-
+
vol_info = kernel32.GetVolumeInformationW(
ctypes.c_wchar_p(mountpoint),
vol_name_buffer,
@@ -59,16 +59,16 @@ def get_volume_display_name(mountpoint):
fs_name_buffer,
ctypes.sizeof(fs_name_buffer)
)
-
+
name = '{} "{}"'.format(name, vol_name_buffer.value)
except:
pass
-
+
return name
def prep_disk_for_backup(destination, disk, backup_prefix):
"""Gather details about the disk and its partitions.
-
+
This includes partitions that can't be backed up,
whether backups already exist on the BACKUP_SERVER,
partition names/sizes/used space, etc."""
@@ -83,7 +83,7 @@ def prep_disk_for_backup(destination, disk, backup_prefix):
if disk['Valid Partitions'] <= 0:
print_error('ERROR: No partitions can be backed up for this disk')
raise GenericAbort
-
+
# Prep partitions
for par in disk['Partitions']:
display = '{size} {fs}'.format(
@@ -91,7 +91,7 @@ def prep_disk_for_backup(destination, disk, backup_prefix):
width = width,
size = par['Size'],
fs = par['FileSystem'])
-
+
if par['Number'] in disk['Bad Partitions']:
# Set display string using partition description & OS type
display = '* {display}\t\t{q}{name}{q}\t{desc} ({os})'.format(
@@ -120,7 +120,7 @@ def prep_disk_for_backup(destination, disk, backup_prefix):
display = '+ {}'.format(display)
else:
display = ' {}'.format(display)
-
+
# Append rest of Display String for valid/clobber partitions
display += ' (Used: {used})\t{q}{name}{q}'.format(
used = par['Used Space'],
@@ -128,7 +128,7 @@ def prep_disk_for_backup(destination, disk, backup_prefix):
name = par['Name'])
# For all partitions
par['Display String'] = display
-
+
# Set description for bad partitions
warnings = '\n'
if disk['Bad Partitions']:
@@ -148,7 +148,7 @@ def select_backup_destination(auto_select=True):
actions = [
{'Name': 'Main Menu', 'Letter': 'M'},
]
-
+
# Add local disks
for d in psutil.disk_partitions():
if re.search(r'^{}'.format(global_vars['Env']['SYSTEMDRIVE']), d.mountpoint, re.IGNORECASE):
@@ -161,7 +161,7 @@ def select_backup_destination(auto_select=True):
get_volume_display_name(d.mountpoint)),
'Letter': re.sub(r'^(\w):\\.*$', r'\1', d.mountpoint),
})
-
+
# Size check
for dest in destinations:
if 'IP' in dest:
@@ -175,11 +175,11 @@ def select_backup_destination(auto_select=True):
if not destinations:
print_warning('No backup destinations found.')
raise GenericAbort
-
+
# Skip menu?
if len(destinations) == 1 and auto_select:
return destinations[0]
-
+
selection = menu_select(
title = 'Where are we backing up to?',
main_entries = destinations,
diff --git a/.bin/Scripts/functions/browsers.py b/.bin/Scripts/functions/browsers.py
index 99086f18..143d018d 100644
--- a/.bin/Scripts/functions/browsers.py
+++ b/.bin/Scripts/functions/browsers.py
@@ -2,6 +2,8 @@
from functions.common import *
+from operator import itemgetter
+
# Define other_results for later try_and_print
browser_data = {}
other_results = {
@@ -101,16 +103,63 @@ SUPPORTED_BROWSERS = {
},
}
+def archive_all_users():
+ """Create backups for all browsers for all users."""
+ users_root = r'{}\Users'.format(global_vars['Env']['SYSTEMDRIVE'])
+ user_envs = []
+
+ # Build list of valid users
+ for user_name in os.listdir(users_root):
+ valid_user = True
+ if user_name in ('Default', 'Default User'):
+ # Skip default users
+ continue
+ user_path = os.path.join(users_root, user_name)
+ appdata_local = os.path.join(user_path, r'AppData\Local')
+ appdata_roaming = os.path.join(user_path, r'AppData\Roaming')
+ valid_user &= os.path.exists(appdata_local)
+ valid_user &= os.path.exists(appdata_roaming)
+ if valid_user:
+ user_envs.append({
+ 'USERNAME': user_name,
+ 'USERPROFILE': user_path,
+ 'APPDATA': appdata_roaming,
+ 'LOCALAPPDATA': appdata_local})
+
+ # Backup browsers for all valid users
+ print_info('Backing up browsers')
+ for fake_env in sorted(user_envs, key=itemgetter('USERPROFILE')):
+ print_standard(' {}'.format(fake_env['USERNAME']))
+ for b_k, b_v in sorted(SUPPORTED_BROWSERS.items()):
+ if b_k == 'Mozilla Firefox Dev':
+ continue
+ source_path = b_v['user_data_path'].format(**fake_env)
+ if not os.path.exists(source_path):
+ continue
+ source_items = source_path + '*'
+ archive_path = r'{BackupDir}\Browsers ({USERNAME})\{Date}'.format(
+ **global_vars, **fake_env)
+ os.makedirs(archive_path, exist_ok=True)
+ archive_path += r'\{}.7z'.format(b_k)
+ cmd = [
+ global_vars['Tools']['SevenZip'],
+ 'a', '-aoa', '-bso0', '-bse0', '-mx=1',
+ archive_path, source_items]
+ try_and_print(message='{}...'.format(b_k),
+ 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'])
- dest = r'{BackupDir}\Browsers ({USERNAME})'.format(
+ dest = r'{BackupDir}\Browsers ({USERNAME})\{Date}'.format(
**global_vars, **global_vars['Env'])
archive = r'{}\{}.7z'.format(dest, name)
os.makedirs(dest, exist_ok=True)
cmd = [
global_vars['Tools']['SevenZip'],
'a', '-aoa', '-bso0', '-bse0', '-mx=1',
+ '-mhe=on', '-p{}'.format(ARCHIVE_PASSWORD),
archive, source]
run_program(cmd)
@@ -138,7 +187,7 @@ def clean_chromium_profile(profile):
def clean_internet_explorer(**kwargs):
"""Uses the built-in function to reset IE and sets the homepage.
-
+
NOTE: kwargs set but unused as a workaround."""
kill_process('iexplore.exe')
run_program(['rundll32.exe', 'inetcpl.cpl,ResetIEtoDefaults'], check=False)
@@ -182,11 +231,11 @@ def clean_mozilla_profile(profile):
def get_browser_details(name):
"""Get installation status and profile details for all supported browsers."""
browser = SUPPORTED_BROWSERS[name].copy()
-
+
# Update user_data_path
browser['user_data_path'] = browser['user_data_path'].format(
**global_vars['Env'])
-
+
# Find executable (if multiple files are found, the last one is used)
exe_path = None
num_installs = 0
@@ -197,7 +246,7 @@ def get_browser_details(name):
if os.path.exists(test_path):
num_installs += 1
exe_path = test_path
-
+
# Find profile(s)
profiles = []
if browser['base'] == 'ie':
@@ -225,12 +274,12 @@ def get_browser_details(name):
profiles.extend(
get_mozilla_profiles(
search_path=browser['user_data_path'], dev=dev))
-
+
elif 'Opera' in name:
if os.path.exists(browser['user_data_path']):
profiles.append(
{'name': 'Default', 'path': browser['user_data_path']})
-
+
# Get homepages
if browser['base'] == 'ie':
# IE is set to only have one profile above
@@ -239,14 +288,14 @@ def get_browser_details(name):
for profile in profiles:
prefs_path = r'{path}\prefs.js'.format(**profile)
profile['homepages'] = get_mozilla_homepages(prefs_path=prefs_path)
-
+
# Add to browser_data
browser_data[name] = browser
browser_data[name].update({
'exe_path': exe_path,
'profiles': profiles,
})
-
+
# Raise installation warnings (if any)
if num_installs == 0:
raise NotInstalledError
@@ -305,7 +354,7 @@ def get_mozilla_homepages(prefs_path):
homepages = search.group(1).split('|')
except Exception:
pass
-
+
return homepages
def get_mozilla_profiles(search_path, dev=False):
@@ -332,9 +381,11 @@ def get_mozilla_profiles(search_path, dev=False):
return profiles
-def install_adblock(indent=8, width=32):
+def install_adblock(indent=8, width=32, just_firefox=False):
"""Install adblock for all supported browsers."""
for browser in sorted(browser_data):
+ if just_firefox and browser_data[browser]['base'] != 'mozilla':
+ continue
exe_path = browser_data[browser].get('exe_path', None)
function=run_program
if not exe_path:
@@ -362,7 +413,7 @@ def install_adblock(indent=8, width=32):
winreg.QueryValue(HKLM, UBO_EXTRA_CHROME_REG)
except FileNotFoundError:
urls.append(UBO_EXTRA_CHROME)
-
+
if len(urls) == 0:
urls = ['chrome://extensions']
elif 'Opera' in browser:
@@ -370,7 +421,7 @@ def install_adblock(indent=8, width=32):
else:
urls.append(UBO_CHROME)
urls.append(UBO_EXTRA_CHROME)
-
+
elif browser_data[browser]['base'] == 'mozilla':
# Check for system extensions
try:
@@ -383,11 +434,11 @@ def install_adblock(indent=8, width=32):
urls = ['about:addons']
else:
urls = [UBO_MOZILLA]
-
+
elif browser_data[browser]['base'] == 'ie':
urls.append(IE_GALLERY)
function=popen_program
-
+
# By using check=False we're skipping any return codes so
# it should only fail if the program can't be run
# (or can't be found).
@@ -400,7 +451,7 @@ def install_adblock(indent=8, width=32):
def list_homepages(indent=8, width=32):
"""List current homepages for reference."""
-
+
for browser in [k for k, v in sorted(browser_data.items()) if v['exe_path']]:
# Skip Chromium-based browsers
if browser_data[browser]['base'] == 'chromium':
@@ -410,7 +461,7 @@ def list_homepages(indent=8, width=32):
end='', flush=True)
print_warning('Not implemented', timestamp=False)
continue
-
+
# All other browsers
print_info('{indent}{browser:<{width}}'.format(
indent=' '*indent, width=width, browser=browser+'...'))
@@ -444,9 +495,11 @@ def reset_browsers(indent=8, width=32):
indent=indent, width=width, function=function,
other_results=other_results, profile=profile)
-def scan_for_browsers():
+def scan_for_browsers(just_firefox=False):
"""Scan system for any supported browsers."""
- for name in sorted(SUPPORTED_BROWSERS):
+ for name, details in sorted(SUPPORTED_BROWSERS.items()):
+ if just_firefox and details['base'] != 'mozilla':
+ continue
try_and_print(message='{}...'.format(name),
function=get_browser_details, cs='Detected',
other_results=other_results, name=name)
diff --git a/.bin/Scripts/functions/cleanup.py b/.bin/Scripts/functions/cleanup.py
index 1bac4c6c..d401b555 100644
--- a/.bin/Scripts/functions/cleanup.py
+++ b/.bin/Scripts/functions/cleanup.py
@@ -6,7 +6,7 @@ def cleanup_adwcleaner():
"""Move AdwCleaner folders into the ClientDir."""
source_path = r'{SYSTEMDRIVE}\AdwCleaner'.format(**global_vars['Env'])
source_quarantine = r'{}\Quarantine'.format(source_path)
-
+
# Quarantine
if os.path.exists(source_quarantine):
os.makedirs(global_vars['QuarantineDir'], exist_ok=True)
@@ -14,27 +14,24 @@ def cleanup_adwcleaner():
**global_vars)
dest_name = non_clobber_rename(dest_name)
shutil.move(source_quarantine, dest_name)
-
+
# Delete source folder if empty
- try:
- os.rmdir(source_path)
- except OSError:
- pass
-
+ delete_empty_folders(source_path)
+
# Main folder
if os.path.exists(source_path):
- os.makedirs(global_vars['ProgBackupDir'], exist_ok=True)
- dest_name = r'{ProgBackupDir}\AdwCleaner_{Date-Time}'.format(
+ os.makedirs(global_vars['LogDir'], exist_ok=True)
+ dest_name = r'{LogDir}\Tools\AdwCleaner'.format(
**global_vars)
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.
-
+
If a CbsPersist file is larger than 2 Gb then the auto archive feature
continually fails and will fill up the system drive with temp files.
-
+
This function moves the temp files and CbsPersist file to a temp folder,
compresses the CbsPersist files with 7-Zip, and then opens the temp folder
for the user to manually save the backup files and delete the temp files.
@@ -43,7 +40,7 @@ def cleanup_cbs(dest_folder):
temp_folder = r'{backup_folder}\Temp'.format(backup_folder=backup_folder)
os.makedirs(backup_folder, exist_ok=True)
os.makedirs(temp_folder, exist_ok=True)
-
+
# Move files into temp folder
cbs_path = r'{SYSTEMROOT}\Logs\CBS'.format(**global_vars['Env'])
for entry in os.scandir(cbs_path):
@@ -59,7 +56,7 @@ def cleanup_cbs(dest_folder):
dest_name = r'{}\{}'.format(temp_folder, entry.name)
dest_name = non_clobber_rename(dest_name)
shutil.move(entry.path, dest_name)
-
+
# Compress CbsPersist files with 7-Zip
cmd = [
global_vars['Tools']['SevenZip'],
@@ -70,9 +67,9 @@ def cleanup_cbs(dest_folder):
def cleanup_desktop():
"""Move known backup files and reports into the ClientDir."""
- dest_folder = r'{ProgBackupDir}\Desktop_{Date-Time}'.format(**global_vars)
+ dest_folder = r'{LogDir}\Tools'.format(**global_vars)
os.makedirs(dest_folder, exist_ok=True)
-
+
desktop_path = r'{USERPROFILE}\Desktop'.format(**global_vars['Env'])
for entry in os.scandir(desktop_path):
# JRT, RKill, Shortcut cleaner
@@ -80,12 +77,53 @@ def cleanup_desktop():
dest_name = r'{}\{}'.format(dest_folder, entry.name)
dest_name = non_clobber_rename(dest_name)
shutil.move(entry.path, dest_name)
-
+
# 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):
+ # Bail early (silently)
+ return
+
+ # Delete empty subfolders first
+ for item in os.scandir(folder_path):
+ if item.is_dir():
+ delete_empty_folders(item.path)
+
+ # Remove top folder
try:
- os.rmdir(dest_folder)
+ os.rmdir(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
+
+ try:
+ if recurse:
+ # Delete all subkeys first
+ with winreg.OpenKeyEx(hive, key, 0, access) as k:
+ key_info = winreg.QueryInfoKey(k)
+ for x in range(key_info[0]):
+ subkey = r'{}\{}'.format(key, winreg.EnumKey(k, 0))
+ delete_registry_key(hive, subkey)
+
+ # Delete key
+ winreg.DeleteKey(hive, key)
+ except FileNotFoundError:
+ # 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.")
+
+# vim: sts=4 sw=4 ts=4
diff --git a/.bin/Scripts/functions/common.py b/.bin/Scripts/functions/common.py
index dc427157..ae958645 100644
--- a/.bin/Scripts/functions/common.py
+++ b/.bin/Scripts/functions/common.py
@@ -32,7 +32,8 @@ COLORS = {
'BLUE': '\033[34m'
}
try:
- HKU = winreg.HKEY_USERS
+ HKU = winreg.HKEY_USERS
+ HKCR = winreg.HKEY_CLASSES_ROOT
HKCU = winreg.HKEY_CURRENT_USER
HKLM = winreg.HKEY_LOCAL_MACHINE
except NameError:
@@ -64,12 +65,24 @@ class NotInstalledError(Exception):
class NoProfilesError(Exception):
pass
+class OSInstalledLegacyError(Exception):
+ pass
+
class PathNotFoundError(Exception):
pass
class UnsupportedOSError(Exception):
pass
+class SecureBootDisabledError(Exception):
+ pass
+
+class SecureBootNotAvailError(Exception):
+ pass
+
+class SecureBootUnknownError(Exception):
+ pass
+
# General functions
def abort():
"""Abort script."""
@@ -155,14 +168,13 @@ def exit_script(return_value=0):
# Remove dirs (if empty)
for dir in ['BackupDir', 'LogDir', 'TmpDir']:
try:
- dir = global_vars[dir]
- os.rmdir(dir)
+ os.rmdir(global_vars[dir])
except Exception:
pass
# Open Log (if it exists)
log = global_vars.get('LogFile', '')
- if log and os.path.exists(log) and psutil.WINDOWS:
+ if log and os.path.exists(log) and psutil.WINDOWS and ENABLED_OPEN_LOGS:
try:
extract_item('NotepadPlusPlus', silent=True)
popen_program(
@@ -271,7 +283,7 @@ def human_readable_size(size, decimals=0):
units = 'Kb'
else:
units = ' b'
-
+
# Return
return '{size:>{width}.{decimals}f} {units}'.format(
size=size, width=width, decimals=decimals, units=units)
@@ -462,7 +474,7 @@ def run_program(cmd, args=[], check=True, pipe=True, shell=False):
def set_title(title='~Some Title~'):
"""Set title.
-
+
Used for window title and menu titles."""
global_vars['Title'] = title
os.system('title {}'.format(title))
@@ -487,6 +499,8 @@ def sleep(seconds=2):
def stay_awake():
"""Prevent the system from sleeping or hibernating."""
+ # DISABLED due to VCR2008 dependency
+ return
# Bail if caffeine is already running
for proc in psutil.process_iter():
if proc.name() == 'caffeine.exe':
@@ -494,7 +508,7 @@ def stay_awake():
# Extract and run
extract_item('Caffeine', silent=True)
try:
- popen_program(global_vars['Tools']['Caffeine'])
+ popen_program([global_vars['Tools']['Caffeine']])
except Exception:
print_error('ERROR: No caffeine available.')
print_warning('Please set the power setting to High Performance.')
@@ -566,7 +580,7 @@ def try_and_print(message='Trying...',
def upload_crash_details():
"""Upload log and runtime data to the CRASH_SERVER.
-
+
Intended for uploading to a public Nextcloud share."""
if not ENABLED_UPLOAD_DATA:
raise GenericError
@@ -589,9 +603,10 @@ global_vars: {}'''.format(f.read(), sys.argv, global_vars)
CRASH_SERVER['Url'],
global_vars.get('Date-Time', 'Unknown Date-Time'),
filename)
- r = requests.put(url, data=data,
- headers = {'X-Requested-With': 'XMLHttpRequest'},
- auth = (CRASH_SERVER['User'], CRASH_SERVER['Pass']))
+ r = requests.put(
+ url, data=data,
+ headers={'X-Requested-With': 'XMLHttpRequest'},
+ auth=(CRASH_SERVER['User'], CRASH_SERVER['Pass']))
# Raise exception if upload NS
if not r.ok:
raise Exception
@@ -648,7 +663,7 @@ def init_global_vars():
def check_os():
"""Set OS specific variables."""
tmp = {}
-
+
# Query registry
path = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion'
with winreg.OpenKey(HKLM, path) as key:
@@ -697,7 +712,7 @@ def check_os():
tmp['DisplayName'] = '{} x{}'.format(tmp['Name'], tmp['Arch'])
if tmp['Notes']:
tmp['DisplayName'] += ' ({})'.format(tmp['Notes'])
-
+
global_vars['OS'] = tmp
def check_tools():
@@ -714,7 +729,7 @@ def check_tools():
def clean_env_vars():
"""Remove conflicting global_vars and env variables.
-
+
This fixes an issue where both global_vars and
global_vars['Env'] are expanded at the same time."""
for key in global_vars.keys():
@@ -740,6 +755,9 @@ def make_tmp_dirs():
"""Make temp directories."""
os.makedirs(global_vars['BackupDir'], exist_ok=True)
os.makedirs(global_vars['LogDir'], exist_ok=True)
+ os.makedirs(r'{}\{}'.format(
+ global_vars['LogDir'], KIT_NAME_FULL), exist_ok=True)
+ os.makedirs(r'{}\Tools'.format(global_vars['LogDir']), exist_ok=True)
os.makedirs(global_vars['TmpDir'], exist_ok=True)
def set_common_vars():
@@ -755,11 +773,9 @@ def set_common_vars():
**global_vars)
global_vars['ClientDir'] = r'{SYSTEMDRIVE}\{prefix}'.format(
prefix=KIT_NAME_SHORT, **global_vars['Env'])
- global_vars['BackupDir'] = r'{ClientDir}\Backups\{Date}'.format(
+ global_vars['BackupDir'] = r'{ClientDir}\Backups'.format(
**global_vars)
- global_vars['LogDir'] = r'{ClientDir}\Info\{Date}'.format(
- **global_vars)
- global_vars['ProgBackupDir'] = r'{ClientDir}\Backups'.format(
+ global_vars['LogDir'] = r'{ClientDir}\Logs\{Date}'.format(
**global_vars)
global_vars['QuarantineDir'] = r'{ClientDir}\Quarantine'.format(
**global_vars)
@@ -768,7 +784,7 @@ def set_common_vars():
def set_linux_vars():
"""Set common variables in a Linux environment.
-
+
These assume we're running under a WK-Linux build."""
result = run_program(['mktemp', '-d'])
global_vars['TmpDir'] = result.stdout.decode().strip()
@@ -782,5 +798,12 @@ 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)
+ log_file = r'{}\{}'.format(folder_path, 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.")
diff --git a/.bin/Scripts/functions/data.py b/.bin/Scripts/functions/data.py
index c8eec384..9557ebdb 100644
--- a/.bin/Scripts/functions/data.py
+++ b/.bin/Scripts/functions/data.py
@@ -126,11 +126,11 @@ def cleanup_transfer(dest_path):
if not os.path.exists(dest_path):
# Bail if dest_path was empty and removed
raise Exception
-
+
# Fix attributes
cmd = ['attrib', '-a', '-h', '-r', '-s', dest_path]
run_program(cmd, check=False)
-
+
for root, dirs, files in os.walk(dest_path, topdown=False):
for name in dirs:
# Remove empty directories and junction points
@@ -153,7 +153,7 @@ def cleanup_transfer(dest_path):
except Exception:
pass
-def find_core_storage_volumes():
+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'
dmsetup_cmd_file = '{TmpDir}/dmsetup_command'.format(**global_vars)
@@ -162,6 +162,8 @@ def find_core_storage_volumes():
cmd = [
'lsblk', '--json', '--list', '--paths',
'--output', 'NAME,PARTTYPE']
+ if device_path:
+ cmd.append(device_path)
result = run_program(cmd)
json_data = json.loads(result.stdout.decode())
devs = json_data.get('blockdevices', [])
@@ -248,7 +250,9 @@ 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):
+def mount_volumes(
+ all_devices=True, device_path=None,
+ read_write=False, core_storage=True):
"""Mount all detected filesystems."""
report = {}
cmd = [
@@ -257,9 +261,10 @@ def mount_volumes(all_devices=True, device_path=None, read_write=False):
if not all_devices and device_path:
# Only mount volumes for specific device
cmd.append(device_path)
- else:
- # Check for Apple CoreStorage volumes first
- find_core_storage_volumes()
+
+ # Check for Apple CoreStorage volumes first
+ if core_storage:
+ find_core_storage_volumes(device_path)
# Get list of block devices
result = run_program(cmd)
@@ -269,11 +274,14 @@ def mount_volumes(all_devices=True, device_path=None, read_write=False):
# Get list of volumes
volumes = {}
for dev in devs:
+ if not dev.get('children', []):
+ volumes.update({dev['name']: dev})
for child in dev.get('children', []):
- volumes.update({child['name']: child})
+ if not child.get('children', []):
+ volumes.update({child['name']: child})
for grandchild in child.get('children', []):
volumes.update({grandchild['name']: grandchild})
-
+
# Get list of mounted volumes
mounted_volumes = get_mounted_volumes()
@@ -352,7 +360,7 @@ def mount_backup_shares(read_write=False):
if server['Mounted']:
print_warning(mounted_str)
continue
-
+
mount_network_share(server, read_write)
def mount_network_share(server, read_write=False):
@@ -364,12 +372,9 @@ def mount_network_share(server, read_write=False):
username = server['User']
password = server['Pass']
if psutil.WINDOWS:
- cmd = r'net use \\{ip}\{share} /user:{username} {password}'.format(
- ip = server['IP'],
- share = server['Share'],
- username = username,
- password = password)
- cmd = cmd.split(' ')
+ cmd = [
+ 'net', 'use', r'\\{IP}\{Share}'.format(**server),
+ '/user:{}'.format(username), password]
warning = r'Failed to mount \\{Name}\{Share}, {IP} unreachable.'.format(
**server)
error = r'Failed to mount \\{Name}\{Share} ({IP})'.format(**server)
@@ -414,12 +419,12 @@ def run_fast_copy(items, dest):
"""Copy items to dest using FastCopy."""
if not items:
raise Exception
-
+
cmd = [global_vars['Tools']['FastCopy'], *FAST_COPY_ARGS]
- cmd.append(r'/logfile={}\FastCopy.log'.format(global_vars['LogDir']))
+ cmd.append(r'/logfile={LogDir}\Tools\FastCopy.log'.format(**global_vars))
cmd.extend(items)
cmd.append('/to={}\\'.format(dest))
-
+
run_program(cmd)
def run_wimextract(source, items, dest):
@@ -486,7 +491,7 @@ def list_source_items(source_obj, rel_path=None):
def scan_source(source_obj, dest_path, rel_path='', interactive=True):
"""Scan source for files/folders to transfer, returns list.
-
+
This will scan the root and (recursively) any Windows.old folders."""
selected_items = []
win_olds = []
@@ -563,7 +568,7 @@ def scan_source(source_obj, dest_path, rel_path='', interactive=True):
'{}{}{}'.format(dest_path, os.sep, old.name),
rel_path=old.name,
interactive=False))
-
+
# Done
return selected_items
@@ -707,7 +712,7 @@ def select_source(backup_prefix):
item.name, # Image file
),
'Source': item})
-
+
# Check for local sources
print_standard('Scanning for local sources...')
set_thread_error_mode(silent=True) # Prevents "No disk" popups
@@ -747,7 +752,7 @@ def select_source(backup_prefix):
' Local', d.mountpoint, item.name),
'Sort': r'{}{}'.format(d.mountpoint, item.name),
'Source': item})
-
+
set_thread_error_mode(silent=False) # Return to normal
# Build Menu
@@ -775,7 +780,7 @@ def select_source(backup_prefix):
umount_backup_shares()
pause("Press Enter to exit...")
exit_script()
-
+
# Sanity check
if selected_source.is_file():
# Image-Based
@@ -783,7 +788,7 @@ def select_source(backup_prefix):
print_error('ERROR: Unsupported image: {}'.format(
selected_source.path))
raise GenericError
-
+
# Done
return selected_source
@@ -791,7 +796,7 @@ def select_volume(title='Select disk', auto_select=True):
"""Select disk from attached disks. returns dict."""
actions = [{'Name': 'Quit', 'Letter': 'Q'}]
disks = []
-
+
# Build list of disks
set_thread_error_mode(silent=True) # Prevents "No disk" popups
for d in psutil.disk_partitions():
@@ -812,11 +817,11 @@ def select_volume(title='Select disk', auto_select=True):
info['Display Name'] = '{} ({})'.format(info['Name'], free)
disks.append(info)
set_thread_error_mode(silent=False) # Return to normal
-
+
# Skip menu?
if len(disks) == 1 and auto_select:
return disks[0]
-
+
# Show menu
selection = menu_select(title, main_entries=disks, action_entries=actions)
if selection == 'Q':
@@ -826,12 +831,12 @@ def select_volume(title='Select disk', auto_select=True):
def set_thread_error_mode(silent=True):
"""Disable or Enable Windows error message dialogs.
-
+
Disable when scanning for disks to avoid popups for empty cardreaders, etc
"""
# Code borrowed from: https://stackoverflow.com/a/29075319
kernel32 = ctypes.WinDLL('kernel32')
-
+
if silent:
kernel32.SetThreadErrorMode(SEM_FAIL, ctypes.byref(SEM_NORMAL))
else:
diff --git a/.bin/Scripts/functions/ddrescue.py b/.bin/Scripts/functions/ddrescue.py
index cf518ea0..7f1fc7aa 100644
--- a/.bin/Scripts/functions/ddrescue.py
+++ b/.bin/Scripts/functions/ddrescue.py
@@ -219,6 +219,7 @@ class DevObj(BaseObj):
sep='_' if self.label else '',
c_label=self.label)
self.prefix = self.prefix.strip().replace(' ', '_')
+ self.prefix = self.prefix.strip().replace('/', '_')
class DirObj(BaseObj):
@@ -322,7 +323,7 @@ class RecoveryState():
elif not is_writable_filesystem(dest):
raise GenericError(
'Destination is mounted read-only, refusing to continue.')
-
+
# Safety checks passed
self.block_pairs.append(BlockPair(self.mode, source, dest))
@@ -391,7 +392,7 @@ class RecoveryState():
self.status_percent = get_formatted_status(
label='Recovered:', data=self.rescued_percent)
self.status_amount = get_formatted_status(
- label='', data=human_readable_size(self.rescued))
+ label='', data=human_readable_size(self.rescued, decimals=2))
# Functions
@@ -858,11 +859,14 @@ def run_ddrescue(state, pass_settings):
height_ddrescue = height - height_smart - height_journal
# Show SMART status
+ smart_dev = state.source_path
+ if state.source.parent:
+ smart_dev = state.source.parent
smart_pane = tmux_splitw(
'-bdvl', str(height_smart),
'-PF', '#D',
'watch', '--color', '--no-title', '--interval', '300',
- 'ddrescue-tui-smart-display', state.source_path)
+ 'ddrescue-tui-smart-display', smart_dev)
# Show systemd journal output
journal_pane = tmux_splitw(
@@ -1080,7 +1084,7 @@ def select_path(skip_device=None):
except OSError:
raise GenericError(
'Failed to create folder "{}"'.format(s_path))
-
+
# Create DirObj
selected_path = DirObj(s_path)
diff --git a/.bin/Scripts/functions/diags.py b/.bin/Scripts/functions/diags.py
index 220eaff3..e55f5b12 100644
--- a/.bin/Scripts/functions/diags.py
+++ b/.bin/Scripts/functions/diags.py
@@ -1,5 +1,7 @@
# Wizard Kit: Functions - Diagnostics
+import ctypes
+
from functions.common import *
# STATIC VARIABLES
@@ -30,12 +32,71 @@ def check_connection():
result = try_and_print(message='Ping test...', function=ping, cs='OK')
if result['CS']:
break
+ if not ask('ERROR: System appears offline, try again?'):
+ if ask('Continue anyway?'):
+ break
+ else:
+ abort()
+
+def check_secure_boot_status(show_alert=False):
+ """Checks UEFI Secure Boot status via PowerShell."""
+ boot_mode = get_boot_mode()
+ cmd = ['PowerShell', '-Command', 'Confirm-SecureBootUEFI']
+ result = run_program(cmd, check=False)
+
+ # Check results
+ if result.returncode == 0:
+ out = result.stdout.decode()
+ if 'True' in out:
+ # It's on, do nothing
+ return
+ elif 'False' in out:
+ if show_alert:
+ show_alert_box('Secure Boot DISABLED')
+ raise SecureBootDisabledError
else:
- if not ask('ERROR: System appears offline, try again?'):
- if ask('Continue anyway?'):
- break
- else:
- abort()
+ if show_alert:
+ show_alert_box('Secure Boot status UNKNOWN')
+ raise SecureBootUnknownError
+ else:
+ if boot_mode != 'UEFI':
+ if (show_alert and
+ global_vars['OS']['Version'] in ('8', '8.1', '10')):
+ # OS supports Secure Boot
+ show_alert_box('Secure Boot DISABLED\n\nOS installed LEGACY')
+ raise OSInstalledLegacyError
+ else:
+ # Check error message
+ err = result.stderr.decode()
+ if 'Cmdlet not supported' in err:
+ if show_alert:
+ show_alert_box('Secure Boot UNAVAILABLE?')
+ raise SecureBootNotAvailError
+ else:
+ if show_alert:
+ 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
+ firmware_type = ctypes.c_uint()
+
+ # Get value from kernel32 API
+ try:
+ kernel.GetFirmwareType(ctypes.byref(firmware_type))
+ except:
+ # Just set to zero
+ firmware_type = ctypes.c_uint(0)
+
+ # Set return value
+ type_str = 'Unknown'
+ if firmware_type.value == 1:
+ type_str = 'Legacy'
+ elif firmware_type.value == 2:
+ type_str = 'UEFI'
+
+ return type_str
def run_autoruns():
"""Run AutoRuns in the background with VirusTotal checks enabled."""
@@ -61,11 +122,23 @@ 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)
cmd = [global_vars['Tools']['XMPlay'],
r'{BinDir}\XMPlay\music.7z'.format(**global_vars)]
+
+ # Unmute audio first
+ extract_item('NirCmd', silent=True)
+ run_nircmd('mutesysvolume', '0')
+
+ # Open XMPlay
popen_program(cmd)
def run_hitmanpro():
@@ -74,7 +147,7 @@ def run_hitmanpro():
cmd = [
global_vars['Tools']['HitmanPro'],
'/quiet', '/noinstall', '/noupload',
- r'/log={LogDir}\hitman.xml'.format(**global_vars)]
+ r'/log={LogDir}\Tools\HitmanPro.txt'.format(**global_vars)]
popen_program(cmd)
def run_process_killer():
@@ -92,23 +165,25 @@ def run_rkill():
extract_item('RKill', silent=True)
cmd = [
global_vars['Tools']['RKill'],
- '-l', r'{LogDir}\RKill.log'.format(**global_vars),
+ '-s', '-l', r'{LogDir}\Tools\RKill.log'.format(**global_vars),
'-new_console:n', '-new_console:s33V']
run_program(cmd, check=False)
wait_for_process('RKill')
- kill_process('notepad.exe')
# RKill cleanup
desktop_path = r'{USERPROFILE}\Desktop'.format(**global_vars['Env'])
if os.path.exists(desktop_path):
for item in os.scandir(desktop_path):
if re.search(r'^RKill', item.name, re.IGNORECASE):
- dest = re.sub(r'^(.*)\.', '\1_{Date-Time}.'.format(
- **global_vars), item.name)
- dest = r'{ClientDir}\Info\{name}'.format(
+ dest = r'{LogDir}\Tools\{name}'.format(
name=dest, **global_vars)
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.")
diff --git a/.bin/Scripts/functions/disk.py b/.bin/Scripts/functions/disk.py
index 2d7cf0bb..75879ff8 100644
--- a/.bin/Scripts/functions/disk.py
+++ b/.bin/Scripts/functions/disk.py
@@ -14,13 +14,13 @@ 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()
-
+
# Write script
script = []
for vol in get_volumes():
script.append('select volume {}'.format(vol['Number']))
script.append('assign')
-
+
# Run
run_diskpart(script)
@@ -35,7 +35,7 @@ def get_boot_mode():
boot_mode = 'UEFI'
except:
boot_mode = 'Unknown'
-
+
return boot_mode
def get_disk_details(disk):
@@ -44,7 +44,7 @@ def get_disk_details(disk):
script = [
'select disk {}'.format(disk['Number']),
'detail disk']
-
+
# Run
try:
result = run_diskpart(script)
@@ -60,13 +60,13 @@ def get_disk_details(disk):
tmp = [s.split(':') for s in tmp if ':' in s]
# Add key/value pairs to the details variable and return dict
details.update({key.strip(): value.strip() for (key, value) in tmp})
-
+
return details
-
+
def get_disks():
"""Get list of attached disks using DiskPart."""
disks = []
-
+
try:
# Run script
result = run_diskpart(['list disk'])
@@ -79,7 +79,7 @@ def get_disks():
num = tmp[0]
size = human_readable_size(tmp[1])
disks.append({'Number': num, 'Size': size})
-
+
return disks
def get_partition_details(disk, partition):
@@ -89,7 +89,7 @@ def get_partition_details(disk, partition):
'select disk {}'.format(disk['Number']),
'select partition {}'.format(partition['Number']),
'detail partition']
-
+
# Diskpart details
try:
# Run script
@@ -111,14 +111,14 @@ def get_partition_details(disk, partition):
tmp = [s.split(':') for s in tmp if ':' in s]
# Add key/value pairs to the details variable and return dict
details.update({key.strip(): value.strip() for (key, value) in tmp})
-
+
# Get MBR type / GPT GUID for extra details on "Unknown" partitions
guid = partition_uids.lookup_guid(details.get('Type'))
if guid:
details.update({
'Description': guid.get('Description', '')[:29],
'OS': guid.get('OS', 'Unknown')[:27]})
-
+
if 'Letter' in details:
# Disk usage
try:
@@ -128,7 +128,7 @@ def get_partition_details(disk, partition):
details['Error'] = err.strerror
else:
details['Used Space'] = human_readable_size(tmp.used)
-
+
# fsutil details
cmd = [
'fsutil',
@@ -151,14 +151,14 @@ def get_partition_details(disk, partition):
tmp = [s.split(':') for s in tmp if ':' in s]
# Add key/value pairs to the details variable and return dict
details.update({key.strip(): value.strip() for (key, value) in tmp})
-
+
# Set Volume Name
details['Name'] = details.get('Volume Name', '')
-
+
# Set FileSystem Type
if details.get('FileSystem', '') not in ['RAW', 'Unknown']:
details['FileSystem'] = details.get('File System Name', 'Unknown')
-
+
return details
def get_partitions(disk):
@@ -167,7 +167,7 @@ def get_partitions(disk):
script = [
'select disk {}'.format(disk['Number']),
'list partition']
-
+
try:
# Run script
result = run_diskpart(script)
@@ -181,7 +181,7 @@ def get_partitions(disk):
num = tmp[0]
size = human_readable_size(tmp[1])
partitions.append({'Number': num, 'Size': size})
-
+
return partitions
def get_table_type(disk):
@@ -190,7 +190,7 @@ def get_table_type(disk):
script = [
'select disk {}'.format(disk['Number']),
'uniqueid disk']
-
+
try:
result = run_diskpart(script)
except subprocess.CalledProcessError:
@@ -203,7 +203,7 @@ def get_table_type(disk):
part_type = 'MBR'
elif REGEX_DISK_RAW.search(output):
part_type = 'RAW'
-
+
return part_type
def get_volumes():
@@ -218,7 +218,7 @@ def get_volumes():
output = result.stdout.decode().strip()
for tmp in re.findall(r'Volume (\d+)\s+([A-Za-z]?)\s+', output):
vols.append({'Number': tmp[0], 'Letter': tmp[1]})
-
+
return vols
def is_bad_partition(par):
@@ -229,7 +229,7 @@ def prep_disk_for_formatting(disk=None):
"""Gather details about the disk and its partitions."""
disk['Format Warnings'] = '\n'
width = len(str(len(disk['Partitions'])))
-
+
# Bail early
if disk is None:
raise Exception('Disk not provided.')
@@ -242,7 +242,7 @@ def prep_disk_for_formatting(disk=None):
else:
if (ask("Setup Windows to use BIOS/Legacy booting?")):
disk['Use GPT'] = False
-
+
# Set Display and Warning Strings
if len(disk['Partitions']) == 0:
disk['Format Warnings'] += 'No partitions found\n'
@@ -252,7 +252,7 @@ def prep_disk_for_formatting(disk=None):
width = width,
size = partition['Size'],
fs = partition['FileSystem'])
-
+
if is_bad_partition(partition):
# Set display string using partition description & OS type
display += '\t\t{q}{name}{q}\t{desc} ({os})'.format(
@@ -290,13 +290,13 @@ def remove_volume_letters(keep=None):
"""Remove all assigned volume letters using DiskPart."""
if not keep:
keep = ''
-
+
script = []
for vol in get_volumes():
if vol['Letter'].upper() != keep.upper():
script.append('select volume {}'.format(vol['Number']))
script.append('remove noerr')
-
+
# Run script
try:
run_diskpart(script)
@@ -306,12 +306,12 @@ def remove_volume_letters(keep=None):
def run_diskpart(script):
"""Run DiskPart script."""
tempfile = r'{}\diskpart.script'.format(global_vars['Env']['TMP'])
-
+
# Write script
with open(tempfile, 'w') as f:
for line in script:
f.write('{}\n'.format(line))
-
+
# Run script
cmd = [
r'{}\Windows\System32\diskpart.exe'.format(
@@ -335,7 +335,7 @@ def scan_disks():
# Get partition info for disk
disk['Partitions'] = get_partitions(disk)
-
+
for partition in disk['Partitions']:
# Get partition details
partition.update(get_partition_details(disk, partition))
@@ -364,12 +364,12 @@ def select_disk(title='Which disk?', disks=[]):
fs = partition['FileSystem'])
if partition['Name']:
p_name += '\t"{}"'.format(partition['Name'])
-
+
# Show unsupported partition(s)
if is_bad_partition(partition):
p_name = '{YELLOW}{p_name}{CLEAR}'.format(
p_name=p_name, **COLORS)
-
+
display_name += '\n\t\t\t{}'.format(p_name)
if not disk['Partitions']:
display_name += '\n\t\t\t{}No partitions found.{}'.format(
diff --git a/.bin/Scripts/functions/hw_diags.py b/.bin/Scripts/functions/hw_diags.py
index 3b8bd354..169eb337 100644
--- a/.bin/Scripts/functions/hw_diags.py
+++ b/.bin/Scripts/functions/hw_diags.py
@@ -8,37 +8,44 @@ from functions.common import *
# STATIC VARIABLES
ATTRIBUTES = {
'NVMe': {
- 'critical_warning': {'Error': 1},
- 'media_errors': {'Error': 1},
- 'power_on_hours': {'Warning': 12000, 'Error': 18000, 'Ignore': True},
+ 'critical_warning': {'Error': 1},
+ 'media_errors': {'Error': 1},
+ 'power_on_hours': {'Warning': 12000, 'Error': 18000, 'Ignore': True},
'unsafe_shutdowns': {'Warning': 1},
},
'SMART': {
- 5: {'Error': 1},
- 9: {'Warning': 12000, 'Error': 18000, 'Ignore': True},
- 10: {'Warning': 1},
- 184: {'Error': 1},
- 187: {'Warning': 1},
- 188: {'Warning': 1},
- 196: {'Warning': 1, 'Error': 10, 'Ignore': True},
- 197: {'Error': 1},
- 198: {'Error': 1},
- 199: {'Error': 1, 'Ignore': True},
- 201: {'Warning': 1},
+ 5: {'Hex': '05', 'Error': 1},
+ 9: {'Hex': '09', 'Warning': 12000, 'Error': 18000, 'Ignore': True},
+ 10: {'Hex': '0A', 'Error': 1},
+ 184: {'Hex': 'B8', 'Error': 1},
+ 187: {'Hex': 'BB', 'Error': 1},
+ 188: {'Hex': 'BC', 'Error': 1},
+ 196: {'Hex': 'C4', 'Error': 1},
+ 197: {'Hex': 'C5', 'Error': 1},
+ 198: {'Hex': 'C6', 'Error': 1},
+ 199: {'Hex': 'C7', 'Error': 1, 'Ignore': True},
+ 201: {'Hex': 'C9', 'Error': 1},
},
}
IO_VARS = {
'Block Size': 512*1024,
- 'Chunk Size': 16*1024**2,
+ 'Chunk Size': 32*1024**2,
'Minimum Dev Size': 8*1024**3,
'Minimum Test Size': 10*1024**3,
'Alt Test Size Factor': 0.01,
'Progress Refresh Rate': 5,
- 'Scale 16': [2**(0.6*x)+(16*x) for x in range(1,17)],
- 'Scale 32': [2**(0.6*x/2)+(16*x/2) for x in range(1,33)],
- 'Threshold Fail': 65*1024**2,
- 'Threshold Warn': 135*1024**2,
- 'Threshold Great': 750*1024**2,
+ 'Scale 8': [2**(0.56*(x+1))+(16*(x+1)) for x in range(8)],
+ 'Scale 16': [2**(0.56*(x+1))+(16*(x+1)) for x in range(16)],
+ 'Scale 32': [2**(0.56*(x+1)/2)+(16*(x+1)/2) for x in range(32)],
+ 'Threshold Graph Fail': 65*1024**2,
+ 'Threshold Graph Warn': 135*1024**2,
+ 'Threshold Graph Great': 750*1024**2,
+ 'Threshold HDD Min': 50*1024**2,
+ 'Threshold HDD High Avg': 75*1024**2,
+ 'Threshold HDD Low Avg': 65*1024**2,
+ 'Threshold SSD Min': 90*1024**2,
+ 'Threshold SSD High Avg': 135*1024**2,
+ 'Threshold SSD Low Avg': 100*1024**2,
'Graph Horizontal': ('▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'),
'Graph Horizontal Width': 40,
'Graph Vertical': (
@@ -59,6 +66,7 @@ TESTS = {
'NVMe/SMART': {
'Enabled': False,
'Quick': False,
+ 'Short Test': {},
'Status': {},
},
'badblocks': {
@@ -67,38 +75,63 @@ TESTS = {
'Status': {},
},
'iobenchmark': {
+ 'Data': {},
'Enabled': False,
'Results': {},
'Status': {},
},
}
-def generate_horizontal_graph(rates):
+def generate_horizontal_graph(rates, oneline=False):
"""Generate two-line horizontal graph from rates, returns str."""
- line_top = ''
- line_bottom = ''
+ line_1 = ''
+ line_2 = ''
+ line_3 = ''
+ line_4 = ''
for r in rates:
- step = get_graph_step(r, scale=16)
+ step = get_graph_step(r, scale=32)
+ if oneline:
+ step = get_graph_step(r, scale=8)
# Set color
r_color = COLORS['CLEAR']
- if r < IO_VARS['Threshold Fail']:
+ if r < IO_VARS['Threshold Graph Fail']:
r_color = COLORS['RED']
- elif r < IO_VARS['Threshold Warn']:
+ elif r < IO_VARS['Threshold Graph Warn']:
r_color = COLORS['YELLOW']
- elif r > IO_VARS['Threshold Great']:
+ elif r > IO_VARS['Threshold Graph Great']:
r_color = COLORS['GREEN']
# Build graph
- if step < 8:
- line_top += ' '
- line_bottom += '{}{}'.format(r_color, IO_VARS['Graph Horizontal'][step])
+ full_block = '{}{}'.format(r_color, IO_VARS['Graph Horizontal'][-1])
+ if step >= 24:
+ line_1 += '{}{}'.format(r_color, IO_VARS['Graph Horizontal'][step-24])
+ line_2 += full_block
+ line_3 += full_block
+ line_4 += full_block
+ elif step >= 16:
+ line_1 += ' '
+ line_2 += '{}{}'.format(r_color, IO_VARS['Graph Horizontal'][step-16])
+ line_3 += full_block
+ line_4 += full_block
+ elif step >= 8:
+ line_1 += ' '
+ line_2 += ' '
+ line_3 += '{}{}'.format(r_color, IO_VARS['Graph Horizontal'][step-8])
+ line_4 += full_block
else:
- line_top += '{}{}'.format(r_color, IO_VARS['Graph Horizontal'][step-8])
- line_bottom += '{}{}'.format(r_color, IO_VARS['Graph Horizontal'][-1])
- line_top += COLORS['CLEAR']
- line_bottom += COLORS['CLEAR']
- return '{}\n{}'.format(line_top, line_bottom)
+ line_1 += ' '
+ line_2 += ' '
+ line_3 += ' '
+ line_4 += '{}{}'.format(r_color, IO_VARS['Graph Horizontal'][step])
+ line_1 += COLORS['CLEAR']
+ line_2 += COLORS['CLEAR']
+ line_3 += COLORS['CLEAR']
+ line_4 += COLORS['CLEAR']
+ if oneline:
+ return line_4
+ else:
+ return '\n'.join([line_1, line_2, line_3, line_4])
def get_graph_step(rate, scale=16):
"""Get graph step based on rate and scale, returns int."""
@@ -144,7 +177,7 @@ def get_smart_value(smart_data, smart_id):
def get_status_color(s):
"""Get color based on status, returns str."""
color = COLORS['CLEAR']
- if s in ['Denied', 'NS', 'OVERRIDE']:
+ if s in ['Denied', 'ERROR', 'NS', 'OVERRIDE']:
color = COLORS['RED']
elif s in ['Aborted', 'Unknown', 'Working', 'Skipped']:
color = COLORS['YELLOW']
@@ -199,16 +232,21 @@ def menu_diags(*args):
action_entries = actions,
spacer = '──────────────────────────')
if selection.isnumeric():
+ ticket_number = None
if diag_modes[int(selection)-1]['Name'] != 'Quick drive test':
- # Save log for non-quick tests
+ clear_screen()
+ print_standard(' ')
ticket_number = get_ticket_number()
- global_vars['LogDir'] = '{}/Logs/{}'.format(
+ # Save log for non-quick tests
+ global_vars['Date-Time'] = time.strftime("%Y-%m-%d_%H%M_%z")
+ global_vars['LogDir'] = '{}/Logs/{}_{}'.format(
global_vars['Env']['HOME'],
- ticket_number if ticket_number else global_vars['Date-Time'])
+ ticket_number,
+ global_vars['Date-Time'])
os.makedirs(global_vars['LogDir'], exist_ok=True)
global_vars['LogFile'] = '{}/Hardware Diagnostics.log'.format(
global_vars['LogDir'])
- run_tests(diag_modes[int(selection)-1]['Tests'])
+ run_tests(diag_modes[int(selection)-1]['Tests'], ticket_number)
elif selection == 'A':
run_program(['hw-diags-audio'], check=False, pipe=False)
pause('Press Enter to return to main menu... ')
@@ -230,7 +268,7 @@ def menu_diags(*args):
elif selection == 'Q':
break
-def run_badblocks():
+def run_badblocks(ticket_number):
"""Run a read-only test for all detected disks."""
aborted = False
clear_screen()
@@ -292,7 +330,7 @@ def run_badblocks():
run_program('tmux kill-pane -a'.split(), check=False)
pass
-def run_iobenchmark():
+def run_iobenchmark(ticket_number):
"""Run a read-only test for all detected disks."""
aborted = False
clear_screen()
@@ -338,10 +376,10 @@ def run_iobenchmark():
dev_size = int(dev_size)
except:
# Failed to get dev size, requires manual testing instead
- TESTS['iobenchmark']['Status'][name] = 'Unknown'
+ TESTS['iobenchmark']['Status'][name] = 'ERROR'
continue
if dev_size < IO_VARS['Minimum Dev Size']:
- TESTS['iobenchmark']['Status'][name] = 'Unknown'
+ TESTS['iobenchmark']['Status'][name] = 'ERROR'
continue
# Calculate dd values
@@ -385,14 +423,16 @@ def run_iobenchmark():
# Run dd read tests
offset = 0
- read_rates = []
+ TESTS['iobenchmark']['Data'][name] = {
+ 'Graph': [],
+ 'Read Rates': []}
for i in range(test_chunks):
i += 1
s = skip_count
c = int(IO_VARS['Chunk Size'] / IO_VARS['Block Size'])
if skip_extra and i % skip_extra == 0:
s += 1
- cmd = 'sudo dd bs={b} skip={s} count={c} if=/dev/{n} of={o}'.format(
+ cmd = 'sudo dd bs={b} skip={s} count={c} if=/dev/{n} of={o} iflag=direct'.format(
b=IO_VARS['Block Size'],
s=offset+s,
c=c,
@@ -400,12 +440,18 @@ def run_iobenchmark():
o='/dev/null')
result = run_program(cmd.split())
result_str = result.stderr.decode().replace('\n', '')
- read_rates.append(get_read_rate(result_str))
+ cur_rate = get_read_rate(result_str)
+ TESTS['iobenchmark']['Data'][name]['Read Rates'].append(
+ cur_rate)
+ TESTS['iobenchmark']['Data'][name]['Graph'].append(
+ '{percent:0.1f} {rate}'.format(
+ percent=i/test_chunks*100,
+ rate=int(cur_rate/(1024**2))))
if i % IO_VARS['Progress Refresh Rate'] == 0:
# Update vertical graph
update_io_progress(
percent=i/test_chunks*100,
- rate=read_rates[-1],
+ rate=cur_rate,
progress_file=progress_file)
# Update offset
offset += s + c
@@ -415,25 +461,45 @@ def run_iobenchmark():
run_program(['tmux', 'kill-pane', '-t', bottom_pane])
# Build report
- h_graph_rates = []
+ avg_min_max = 'Average read speed: {:3.1f} MB/s (Min: {:3.1f}, Max: {:3.1f})'.format(
+ sum(TESTS['iobenchmark']['Data'][name]['Read Rates'])/len(
+ TESTS['iobenchmark']['Data'][name]['Read Rates'])/(1024**2),
+ min(TESTS['iobenchmark']['Data'][name]['Read Rates'])/(1024**2),
+ max(TESTS['iobenchmark']['Data'][name]['Read Rates'])/(1024**2))
+ TESTS['iobenchmark']['Data'][name]['Avg/Min/Max'] = avg_min_max
+ TESTS['iobenchmark']['Data'][name]['Merged Rates'] = []
pos = 0
width = int(test_chunks / IO_VARS['Graph Horizontal Width'])
for i in range(IO_VARS['Graph Horizontal Width']):
# Append average rate for WIDTH number of rates to new array
- h_graph_rates.append(sum(read_rates[pos:pos+width])/width)
+ TESTS['iobenchmark']['Data'][name]['Merged Rates'].append(sum(
+ TESTS['iobenchmark']['Data'][name]['Read Rates'][pos:pos+width])/width)
pos += width
- report = generate_horizontal_graph(h_graph_rates)
- report += '\nRead speed: {:3.1f} MB/s (Min: {:3.1f}, Max: {:3.1f})'.format(
- sum(read_rates)/len(read_rates)/(1024**2),
- min(read_rates)/(1024**2),
- max(read_rates)/(1024**2))
+ report = generate_horizontal_graph(
+ TESTS['iobenchmark']['Data'][name]['Merged Rates'])
+ report += '\n{}'.format(avg_min_max)
TESTS['iobenchmark']['Results'][name] = report
# Set CS/NS
- if min(read_rates) <= IO_VARS['Threshold Fail']:
+ min_read = min(TESTS['iobenchmark']['Data'][name]['Read Rates'])
+ avg_read = sum(
+ TESTS['iobenchmark']['Data'][name]['Read Rates'])/len(
+ TESTS['iobenchmark']['Data'][name]['Read Rates'])
+ dev_rotational = dev['lsblk'].get('rota', None)
+ if dev_rotational == "0":
+ # Use SSD scale
+ thresh_min = IO_VARS['Threshold SSD Min']
+ thresh_high_avg = IO_VARS['Threshold SSD High Avg']
+ thresh_low_avg = IO_VARS['Threshold SSD Low Avg']
+ else:
+ # Use HDD scale
+ thresh_min = IO_VARS['Threshold HDD Min']
+ thresh_high_avg = IO_VARS['Threshold HDD High Avg']
+ thresh_low_avg = IO_VARS['Threshold HDD Low Avg']
+ if min_read <= thresh_min and avg_read <= thresh_high_avg:
+ TESTS['iobenchmark']['Status'][name] = 'NS'
+ elif avg_read <= thresh_low_avg:
TESTS['iobenchmark']['Status'][name] = 'NS'
- elif min(read_rates) <= IO_VARS['Threshold Warn']:
- TESTS['iobenchmark']['Status'][name] = 'Unknown'
else:
TESTS['iobenchmark']['Status'][name] = 'CS'
@@ -441,15 +507,14 @@ def run_iobenchmark():
dest_filename = '{}/iobenchmark-{}.log'.format(global_vars['LogDir'], name)
shutil.move(progress_file, dest_filename)
with open(dest_filename.replace('.', '-raw.'), 'a') as f:
- for rate in read_rates:
- f.write('{} MB/s\n'.format(rate/(1024**2)))
+ f.write('\n'.join(TESTS['iobenchmark']['Data'][name]['Graph']))
update_progress()
# Done
run_program('tmux kill-pane -a'.split(), check=False)
pass
-def run_mprime():
+def run_mprime(ticket_number):
"""Run Prime95 for MPRIME_LIMIT minutes while showing the temps."""
aborted = False
print_log('\nStart Prime95 test')
@@ -463,19 +528,24 @@ def run_mprime():
TESTS['Progress Out']).split())
run_program('tmux split-window -bd watch -c -n1 -t hw-sensors'.split())
run_program('tmux resize-pane -y 3'.split())
-
+
# Start test
run_program(['apple-fans', 'max'])
try:
for i in range(int(MPRIME_LIMIT)):
clear_screen()
- print_standard('Running Prime95 ({} minutes left)'.format(
- int(MPRIME_LIMIT)-i))
+ min_left = int(MPRIME_LIMIT) - i
+ print_standard('Running Prime95 ({} minute{} left)'.format(
+ min_left,
+ 's' if min_left != 1 else ''))
print_warning('If running too hot, press CTRL+c to abort the test')
sleep(60)
except KeyboardInterrupt:
# Catch CTRL+C
aborted = True
+ TESTS['Prime95']['Status'] = 'Aborted'
+ print_warning('\nAborted.')
+ update_progress()
# Save "final" temps
run_program(
@@ -523,15 +593,7 @@ def run_mprime():
TESTS['Prime95']['CS'] = bool(r)
# Update status
- if aborted:
- TESTS['Prime95']['Status'] = 'Aborted'
- print_warning('\nAborted.')
- update_progress()
- if TESTS['NVMe/SMART']['Enabled'] or TESTS['badblocks']['Enabled']:
- if not ask('Proceed to next test?'):
- run_program('tmux kill-pane -a'.split())
- raise GenericError
- else:
+ if not aborted:
if TESTS['Prime95']['NS']:
TESTS['Prime95']['Status'] = 'NS'
elif TESTS['Prime95']['CS']:
@@ -540,10 +602,21 @@ def run_mprime():
TESTS['Prime95']['Status'] = 'Unknown'
update_progress()
+ if aborted:
+ if TESTS['NVMe/SMART']['Enabled'] or TESTS['badblocks']['Enabled']:
+ if not ask('Proceed to next test?'):
+ for name in TESTS['NVMe/SMART']['Devices'].keys():
+ for t in ['NVMe/SMART', 'badblocks', 'iobenchmark']:
+ cur_status = TESTS[t]['Status'][name]
+ if cur_status not in ['CS', 'Denied', 'NS']:
+ TESTS[t]['Status'][name] = 'Aborted'
+ run_program('tmux kill-pane -a'.split())
+ raise GenericError
+
# Done
run_program('tmux kill-pane -a'.split())
-def run_nvme_smart():
+def run_nvme_smart(ticket_number):
"""Run the built-in NVMe or SMART test for all detected disks."""
aborted = False
clear_screen()
@@ -565,6 +638,7 @@ def run_nvme_smart():
# Run
for name, dev in sorted(TESTS['NVMe/SMART']['Devices'].items()):
+ TESTS['NVMe/SMART']['Short Test'][name] = None
cur_status = TESTS['NVMe/SMART']['Status'][name]
if cur_status == 'OVERRIDE':
# Skipping test per user request
@@ -595,7 +669,7 @@ def run_nvme_smart():
run_program(
'sudo smartctl -t short /dev/{}'.format(name).split(),
check=False)
-
+
# Wait and show progress (in 10 second increments)
for iteration in range(int(test_length*60/10)):
# Update SMART data
@@ -630,18 +704,24 @@ def run_nvme_smart():
'passed', False)
if test_passed:
TESTS['NVMe/SMART']['Status'][name] = 'CS'
+ TESTS['NVMe/SMART']['Short Test'][name] = 'CS'
else:
TESTS['NVMe/SMART']['Status'][name] = 'NS'
+ TESTS['NVMe/SMART']['Short Test'][name] = 'NS'
update_progress()
print_standard('Done', timestamp=False)
# Done
run_program('tmux kill-pane -a'.split(), check=False)
-def run_tests(tests):
+def run_tests(tests, ticket_number=None):
"""Run selected hardware test(s)."""
- print_log('Starting Hardware Diagnostics')
- print_log('\nRunning tests: {}'.format(', '.join(tests)))
+ clear_screen()
+ print_standard('Starting Hardware Diagnostics')
+ if ticket_number:
+ print_standard(' For Ticket #{}'.format(ticket_number))
+ print_standard(' ')
+ print_standard('Running tests: {}'.format(', '.join(tests)))
# Enable selected tests
for t in ['Prime95', 'NVMe/SMART', 'badblocks', 'iobenchmark']:
TESTS[t]['Enabled'] = t in tests
@@ -650,7 +730,6 @@ def run_tests(tests):
# Initialize
if TESTS['NVMe/SMART']['Enabled'] or TESTS['badblocks']['Enabled'] or TESTS['iobenchmark']['Enabled']:
print_standard(' ')
- print_standard('Scanning disks...')
scan_disks()
update_progress()
@@ -658,22 +737,22 @@ def run_tests(tests):
mprime_aborted = False
if TESTS['Prime95']['Enabled']:
try:
- run_mprime()
+ run_mprime(ticket_number)
except GenericError:
mprime_aborted = True
if not mprime_aborted:
if TESTS['NVMe/SMART']['Enabled']:
- run_nvme_smart()
+ run_nvme_smart(ticket_number)
if TESTS['badblocks']['Enabled']:
- run_badblocks()
+ run_badblocks(ticket_number)
if TESTS['iobenchmark']['Enabled']:
- run_iobenchmark()
-
+ run_iobenchmark(ticket_number)
+
# Show results
show_results()
# Open log
- if not TESTS['NVMe/SMART']['Quick']:
+ if not TESTS['NVMe/SMART']['Quick'] and ENABLED_OPEN_LOGS:
try:
popen_program(['nohup', 'leafpad', global_vars['LogFile']], pipe=True)
except Exception:
@@ -683,7 +762,6 @@ def run_tests(tests):
def scan_disks(full_paths=False, only_path=None):
"""Scan for disks eligible for hardware testing."""
- clear_screen()
# Get eligible disk list
cmd = ['lsblk', '-J', '-O']
@@ -703,13 +781,18 @@ def scan_disks(full_paths=False, only_path=None):
TESTS['iobenchmark']['Status'][d['name']] = 'Pending'
else:
# Skip WizardKit devices
- wk_label = '{}_LINUX'.format(KIT_NAME_SHORT)
- if wk_label not in [c.get('label', '') for c in d.get('children', [])]:
+ skip_dev=False
+ wk_label_regex = r'{}_(LINUX|UFD)'.format(KIT_NAME_SHORT)
+ for c in d.get('children', []):
+ r = re.search(
+ wk_label_regex, c.get('label', ''), re.IGNORECASE)
+ skip_dev = bool(r)
+ if not skip_dev:
devs[d['name']] = {'lsblk': d}
TESTS['NVMe/SMART']['Status'][d['name']] = 'Pending'
TESTS['badblocks']['Status'][d['name']] = 'Pending'
TESTS['iobenchmark']['Status'][d['name']] = 'Pending'
-
+
for dev, data in devs.items():
# Get SMART attributes
run_program(
@@ -718,7 +801,7 @@ def scan_disks(full_paths=False, only_path=None):
dev).split(),
check = False)
data['smartctl'] = get_smart_details(dev)
-
+
# Get NVMe attributes
if data['lsblk']['tran'] == 'nvme':
cmd = 'sudo nvme smart-log /dev/{} -o json'.format(dev).split()
@@ -742,7 +825,12 @@ def scan_disks(full_paths=False, only_path=None):
]
if data.get('NVMe Disk', False):
crit_warn = data['nvme-cli'].get('critical_warning', 1)
- data['Quick Health OK'] = True if crit_warn == 0 else False
+ if crit_warn == 0:
+ dev_name = data['lsblk']['name']
+ data['Quick Health OK'] = True
+ TESTS['NVMe/SMART']['Status'][dev_name] = 'CS'
+ else:
+ data['Quick Health OK'] = False
elif set(wanted_smart_list).issubset(data['smartctl'].keys()):
data['SMART Pass'] = data['smartctl'].get('smart_status', {}).get(
'passed', False)
@@ -751,7 +839,7 @@ def scan_disks(full_paths=False, only_path=None):
else:
data['Quick Health OK'] = False
data['SMART Support'] = False
-
+
# Ask for manual overrides if necessary
if TESTS['badblocks']['Enabled'] or TESTS['iobenchmark']['Enabled']:
show_disk_details(data)
@@ -772,7 +860,7 @@ def scan_disks(full_paths=False, only_path=None):
if ask('Run tests on this device anyway?'):
TESTS['NVMe/SMART']['Status'][dev_name] = 'OVERRIDE'
else:
- TESTS['NVMe/SMART']['Status'][dev_name] = 'NS'
+ TESTS['NVMe/SMART']['Status'][dev_name] = 'Skipped'
TESTS['badblocks']['Status'][dev_name] = 'Denied'
TESTS['iobenchmark']['Status'][dev_name] = 'Denied'
print_standard(' ') # In case there's more than one "OVERRIDE" disk
@@ -949,13 +1037,13 @@ def update_io_progress(percent, rate, progress_file):
bar_color = COLORS['CLEAR']
rate_color = COLORS['CLEAR']
step = get_graph_step(rate, scale=32)
- if rate < IO_VARS['Threshold Fail']:
+ if rate < IO_VARS['Threshold Graph Fail']:
bar_color = COLORS['RED']
rate_color = COLORS['YELLOW']
- elif rate < IO_VARS['Threshold Warn']:
+ elif rate < IO_VARS['Threshold Graph Warn']:
bar_color = COLORS['YELLOW']
rate_color = COLORS['YELLOW']
- elif rate > IO_VARS['Threshold Great']:
+ elif rate > IO_VARS['Threshold Graph Great']:
bar_color = COLORS['GREEN']
rate_color = COLORS['GREEN']
line = ' {p:5.1f}% {b_color}{b:<4} {r_color}{r:6.1f} Mb/s{c}\n'.format(
diff --git a/.bin/Scripts/functions/info.py b/.bin/Scripts/functions/info.py
index b81a4922..7630a766 100644
--- a/.bin/Scripts/functions/info.py
+++ b/.bin/Scripts/functions/info.py
@@ -68,7 +68,8 @@ def backup_file_list():
def backup_power_plans():
"""Export current power plans."""
- os.makedirs(r'{BackupDir}\Power Plans'.format(**global_vars), exist_ok=True)
+ os.makedirs(r'{BackupDir}\Power Plans\{Date}'.format(
+ **global_vars), exist_ok=True)
plans = run_program(['powercfg', '/L'])
plans = plans.stdout.decode().splitlines()
plans = [p for p in plans if re.search(r'^Power Scheme', p)]
@@ -76,22 +77,24 @@ def backup_power_plans():
guid = re.sub(r'Power Scheme GUID:\s+([0-9a-f\-]+).*', r'\1', p)
name = re.sub(
r'Power Scheme GUID:\s+[0-9a-f\-]+\s+\(([^\)]+)\).*', r'\1', p)
- out = r'{BackupDir}\Power Plans\{name}.pow'.format(
+ out = r'{BackupDir}\Power Plans\{Date}\{name}.pow'.format(
name=name, **global_vars)
if not os.path.exists(out):
cmd = ['powercfg', '-export', out, guid]
run_program(cmd, check=False)
-def backup_registry():
+def backup_registry(overwrite=False):
"""Backup registry including user hives."""
extract_item('erunt', silent=True)
cmd = [
global_vars['Tools']['ERUNT'],
- r'{BackupDir}\Registry'.format(**global_vars),
+ r'{BackupDir}\Registry\{Date}'.format(**global_vars),
'sysreg',
'curuser',
'otherusers',
'/noprogresswindow']
+ if overwrite:
+ cmd.append('/noconfirmdelete')
run_program(cmd)
def get_folder_size(path):
@@ -162,7 +165,7 @@ def get_installed_office():
def get_shell_path(folder, user='current'):
"""Get shell path using SHGetKnownFolderPath via knownpaths, returns str.
-
+
NOTE: Only works for the current user.
Code based on https://gist.github.com/mkropat/7550097
"""
@@ -175,14 +178,14 @@ def get_shell_path(folder, user='current'):
except AttributeError:
# Unknown folder ID, ignore and return None
pass
-
+
if folderid:
try:
path = knownpaths.get_path(folderid, getattr(knownpaths.UserHandle, user))
except PathNotFoundError:
# Folder not found, ignore and return None
pass
-
+
return path
def get_user_data_paths(user):
@@ -196,7 +199,7 @@ def get_user_data_paths(user):
'Extra Folders': {},
}
unload_hive = False
-
+
if user['Name'] == global_vars['Env']['USERNAME']:
# We can use SHGetKnownFolderPath for the current user
paths['Profile']['Path'] = get_shell_path('Profile')
@@ -212,7 +215,7 @@ def get_user_data_paths(user):
except Exception:
# Profile path not found, leaving as None.
pass
-
+
# Shell folders (Prep)
if not reg_path_exists(HKU, hive_path) and paths['Profile']['Path']:
# User not logged-in, loading hive
@@ -226,7 +229,7 @@ def get_user_data_paths(user):
except subprocess.CalledProcessError:
# Failed to load user hive
pass
-
+
# Shell folders
shell_folders = r'{}\{}'.format(hive_path, REG_SHELL_FOLDERS)
if (reg_path_exists(HKU, hive_path)
@@ -252,7 +255,7 @@ def get_user_data_paths(user):
if (folder not in paths['Shell Folders']
and os.path.exists(folder_path)):
paths['Shell Folders'][folder] = {'Path': folder_path}
-
+
# Extra folders
if paths['Profile']['Path']:
for folder in EXTRA_FOLDERS:
@@ -260,12 +263,12 @@ def get_user_data_paths(user):
folder=folder, **paths['Profile'])
if os.path.exists(folder_path):
paths['Extra Folders'][folder] = {'Path': folder_path}
-
+
# Shell folders (cleanup)
if unload_hive:
cmd = ['reg', 'unload', r'HKU\{}'.format(TMP_HIVE_PATH)]
run_program(cmd, check=False)
-
+
# Done
return paths
@@ -277,7 +280,7 @@ def get_user_folder_sizes(users):
with winreg.OpenKey(HKCU,
r'Software\Sysinternals\Du', access=winreg.KEY_WRITE) as key:
winreg.SetValueEx(key, 'EulaAccepted', 0, winreg.REG_DWORD, 1)
-
+
for u in users:
u.update(get_user_data_paths(u))
if u['Profile']['Path']:
@@ -292,7 +295,7 @@ def get_user_folder_sizes(users):
def get_user_list():
"""Get user list via WMIC, returns list of dicts."""
users = []
-
+
# Get user info from WMI
cmd = ['wmic', 'useraccount', 'get', '/format:csv']
try:
@@ -300,10 +303,10 @@ def get_user_list():
except subprocess.CalledProcessError:
# Meh, return empty list to avoid a full crash
return users
-
+
entries = out.stdout.decode().splitlines()
entries = [e.strip().split(',') for e in entries if e.strip()]
-
+
# Add user(s) to dict
keys = entries[0]
for e in entries[1:]:
@@ -314,10 +317,10 @@ def get_user_list():
# Assume SIDs ending with 1000+ are "Standard" and others are "System"
e['Type'] = 'Standard' if re.search(r'-1\d+$', e['SID']) else 'System'
users.append(e)
-
+
# Sort list
users.sort(key=itemgetter('Name'))
-
+
# Done
return users
@@ -368,26 +371,38 @@ def run_aida64():
'/TEXT', '/SILENT', '/SAFEST']
run_program(cmd, check=False)
-def run_bleachbit():
+def run_bleachbit(cleaners=None, preview=True):
"""Run BleachBit preview and save log.
-
- This is a preview so no files should be deleted."""
- if not os.path.exists(global_vars['LogDir']+r'\BleachBit.log'):
- extract_item('BleachBit', silent=True)
- cmd = [global_vars['Tools']['BleachBit'], '--preview', '--preset']
- out = run_program(cmd, check=False)
- # Save stderr
- if out.stderr.decode().splitlines():
- with open(global_vars['LogDir']+r'\BleachBit.err', 'a',
- encoding='utf-8') as f:
- for line in out.stderr.decode().splitlines():
- f.write(line.strip() + '\n')
- # Save stdout
- with open(global_vars['LogDir']+r'\BleachBit.log', 'a',
- encoding='utf-8') as f:
- for line in out.stdout.decode().splitlines():
+
+ If preview is True then no files should be deleted."""
+ error_path = r'{}\Tools\BleachBit.err'.format(global_vars['LogDir'])
+ log_path = error_path.replace('err', 'log')
+ extract_item('BleachBit', silent=True)
+
+ # Safety check
+ if not cleaners:
+ # Disable cleaning and use preset config
+ cleaners = ['--preset']
+ preview = True
+
+ # Run
+ cmd = [
+ global_vars['Tools']['BleachBit'],
+ '--preview' if preview else '--clean']
+ cmd.extend(cleaners)
+ out = run_program(cmd, check=False)
+
+ # Save stderr
+ if out.stderr.decode().splitlines():
+ with open(error_path, 'a', encoding='utf-8') as f:
+ for line in out.stderr.decode().splitlines():
f.write(line.strip() + '\n')
+ # Save stdout
+ with open(log_path, 'a', encoding='utf-8') as f:
+ 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('/', ' ')),
@@ -459,7 +474,7 @@ def show_os_name():
def show_temp_files_size():
"""Show total size of temp files identified by BleachBit."""
size = None
- with open(r'{LogDir}\BleachBit.log'.format(**global_vars), 'r') as f:
+ with open(r'{LogDir}\Tools\BleachBit.log'.format(**global_vars), 'r') as f:
for line in f.readlines():
if re.search(r'^disk space to be recovered:', line, re.IGNORECASE):
size = re.sub(r'.*: ', '', line.strip())
diff --git a/.bin/Scripts/functions/network.py b/.bin/Scripts/functions/network.py
index d040e343..5735c486 100644
--- a/.bin/Scripts/functions/network.py
+++ b/.bin/Scripts/functions/network.py
@@ -26,7 +26,7 @@ def connect_to_network():
# Bail if currently connected
if is_connected():
return
-
+
# WiFi
if 'wl' in net_ifs:
cmd = [
@@ -37,7 +37,7 @@ def connect_to_network():
message = 'Connecting to {}...'.format(WIFI_SSID),
function = run_program,
cmd = cmd)
-
+
def is_connected():
"""Check for a valid private IP."""
devs = psutil.net_if_addrs()
diff --git a/.bin/Scripts/functions/product_keys.py b/.bin/Scripts/functions/product_keys.py
index 705f46e9..988d36fd 100644
--- a/.bin/Scripts/functions/product_keys.py
+++ b/.bin/Scripts/functions/product_keys.py
@@ -39,7 +39,7 @@ def extract_keys():
keys[product] = []
if key not in keys[product]:
keys[product].append(key)
-
+
# Done
return keys
diff --git a/.bin/Scripts/functions/repairs.py b/.bin/Scripts/functions/repairs.py
index e4d5e74f..589dccc3 100644
--- a/.bin/Scripts/functions/repairs.py
+++ b/.bin/Scripts/functions/repairs.py
@@ -24,11 +24,11 @@ def run_chkdsk_scan():
raise GenericError
# Save stderr
- with open(r'{LogDir}\CHKDSK.err'.format(**global_vars), 'a') as f:
+ with open(r'{LogDir}\Tools\CHKDSK.err'.format(**global_vars), 'a') as f:
for line in out.stderr.decode().splitlines():
f.write(line.strip() + '\n')
# Save stdout
- with open(r'{LogDir}\CHKDSK.log'.format(**global_vars), 'a') as f:
+ with open(r'{LogDir}\Tools\CHKDSK.log'.format(**global_vars), 'a') as f:
for line in out.stdout.decode().splitlines():
f.write(line.strip() + '\n')
@@ -50,7 +50,7 @@ def run_dism(repair=False):
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/RestoreHealth',
- r'/LogPath:"{LogDir}\DISM_RestoreHealth.log"'.format(
+ r'/LogPath:"{LogDir}\Tools\DISM_RestoreHealth.log"'.format(
**global_vars),
'-new_console:n', '-new_console:s33V']
else:
@@ -58,7 +58,7 @@ def run_dism(repair=False):
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/ScanHealth',
- r'/LogPath:"{LogDir}\DISM_ScanHealth.log"'.format(
+ r'/LogPath:"{LogDir}\Tools\DISM_ScanHealth.log"'.format(
**global_vars),
'-new_console:n', '-new_console:s33V']
run_program(cmd, pipe=False, check=False, shell=True)
@@ -67,7 +67,7 @@ def run_dism(repair=False):
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/CheckHealth',
- r'/LogPath:"{LogDir}\DISM_CheckHealth.log"'.format(**global_vars)]
+ r'/LogPath:"{LogDir}\Tools\DISM_CheckHealth.log"'.format(**global_vars)]
result = run_program(cmd, shell=True).stdout.decode()
# Check result
if 'no component store corruption detected' not in result.lower():
@@ -93,11 +93,11 @@ def run_sfc_scan():
'/scannow']
out = run_program(cmd, check=False)
# Save stderr
- with open(r'{LogDir}\SFC.err'.format(**global_vars), 'a') as f:
+ with open(r'{LogDir}\Tools\SFC.err'.format(**global_vars), 'a') as f:
for line in out.stderr.decode('utf-8', 'ignore').splitlines():
f.write(line.strip() + '\n')
# Save stdout
- with open(r'{LogDir}\SFC.log'.format(**global_vars), 'a') as f:
+ with open(r'{LogDir}\Tools\SFC.log'.format(**global_vars), 'a') as f:
for line in out.stdout.decode('utf-8', 'ignore').splitlines():
f.write(line.strip() + '\n')
# Check result
@@ -116,7 +116,7 @@ def run_tdsskiller():
**global_vars), exist_ok=True)
cmd = [
global_vars['Tools']['TDSSKiller'],
- '-l', r'{LogDir}\TDSSKiller.log'.format(**global_vars),
+ '-l', r'{LogDir}\Tools\TDSSKiller.log'.format(**global_vars),
'-qpath', r'{QuarantineDir}\TDSSKiller'.format(**global_vars),
'-accepteula', '-accepteulaksn',
'-dcexact', '-tdlfs']
diff --git a/.bin/Scripts/functions/setup.py b/.bin/Scripts/functions/setup.py
index 4fca0303..4e1e2ee7 100644
--- a/.bin/Scripts/functions/setup.py
+++ b/.bin/Scripts/functions/setup.py
@@ -1,8 +1,11 @@
# Wizard Kit: Functions - Setup
from functions.common import *
+from functions.update import *
# STATIC VARIABLES
+HKU = winreg.HKEY_USERS
+HKCR = winreg.HKEY_CLASSES_ROOT
HKCU = winreg.HKEY_CURRENT_USER
HKLM = winreg.HKEY_LOCAL_MACHINE
MOZILLA_FIREFOX_UBO_PATH = r'{}\{}\ublock_origin.xpi'.format(
@@ -29,15 +32,22 @@ SETTINGS_CLASSIC_START = {
},
}
SETTINGS_EXPLORER_SYSTEM = {
+ # Disable Location Tracking
+ r'Software\Microsoft\Windows NT\CurrentVersion\Sensor\Overrides\{BFA794E4-F964-4FDB-90F6-51056BFE4B44}': {
+ 'DWORD Items': {'SensorPermissionState': 0},
+ },
+ r'System\CurrentControlSet\Services\lfsvc\Service\Configuration': {
+ 'Status': {'Value': 0},
+ },
# Disable Telemetry
- r'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection': {
+ r'Software\Microsoft\Windows\CurrentVersion\Policies\DataCollection': {
'DWORD Items': {'AllowTelemetry': 0},
},
- r'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection': {
+ r'Software\Microsoft\Windows\CurrentVersion\Policies\DataCollection': {
'DWORD Items': {'AllowTelemetry': 0},
'WOW64_32': True,
},
- r'SOFTWARE\Policies\Microsoft\Windows\DataCollection': {
+ r'Software\Policies\Microsoft\Windows\DataCollection': {
'DWORD Items': {'AllowTelemetry': 0},
},
# Disable Wi-Fi Sense
@@ -47,27 +57,19 @@ SETTINGS_EXPLORER_SYSTEM = {
r'Software\Microsoft\PolicyManager\default\WiFi\AllowAutoConnectToWiFiSenseHotspots': {
'DWORD Items': {'Value': 0},
},
- # Disable Location Tracking
- r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Sensor\Overrides\{BFA794E4-F964-4FDB-90F6-51056BFE4B44}': {
- 'DWORD Items': {'SensorPermissionState': 0},
- },
- r'System\CurrentControlSet\Services\lfsvc\Service\Configuration': {
- 'Status': {'Value': 0},
- },
}
SETTINGS_EXPLORER_USER = {
- # Disable Cortana
- r'Software\Microsoft\Personalization\Settings': {
- 'DWORD Items': {'AcceptedPrivacyPolicy': 0},
+ # Disable silently installed apps
+ r'Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager': {
+ 'DWORD Items': {'SilentInstalledAppsEnabled': 0},
},
- r'Software\Microsoft\InputPersonalization': {
- 'DWORD Items': {
- 'RestrictImplicitTextCollection': 1,
- 'RestrictImplicitInkCollection': 1
- },
+ # Disable Tips and Tricks
+ r'Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager': {
+ 'DWORD Items': {'SoftLandingEnabled ': 0},
},
- r'Software\Microsoft\InputPersonalization\TrainedDataStore': {
- 'DWORD Items': {'HarvestContacts': 1},
+ # Hide People bar
+ r'Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People': {
+ 'DWORD Items': {'PeopleBand': 0},
},
# Hide Search button / box
r'Software\Microsoft\Windows\CurrentVersion\Search': {
@@ -104,10 +106,6 @@ SETTINGS_MOZILLA_FIREFOX_64 = {
},
}
VCR_REDISTS = [
- {'Name': 'Visual C++ 2008 SP1 x32...',
- 'Cmd': [r'2008sp1\x32\vcredist.exe', '/qb! /norestart']},
- {'Name': 'Visual C++ 2008 SP1 x64...',
- 'Cmd': [r'2008sp1\x64\vcredist.exe', '/qb! /norestart']},
{'Name': 'Visual C++ 2010 x32...',
'Cmd': [r'2010sp1\x32\vcredist.exe', '/passive', '/norestart']},
{'Name': 'Visual C++ 2010 x64...',
@@ -182,25 +180,6 @@ def config_classicstart():
sleep(1)
popen_program(cs_exe)
-def write_registry_settings(settings, all_users=False):
- """Write registry values from custom dict of dicts."""
- hive = HKCU
- if all_users:
- hive = HKLM
- for k, v in settings.items():
- # CreateKey
- access = winreg.KEY_WRITE
- if 'WOW64_32' in v:
- access = access | winreg.KEY_WOW64_32KEY
- winreg.CreateKeyEx(hive, k, 0, access)
-
- # Create values
- with winreg.OpenKeyEx(hive, k, 0, access) as key:
- for name, value in v.get('DWORD Items', {}).items():
- winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, value)
- for name, value in v.get('SZ Items', {}).items():
- winreg.SetValueEx(key, name, 0, winreg.REG_SZ, value)
-
def config_explorer_system():
"""Configure Windows Explorer for all users via Registry settings."""
write_registry_settings(SETTINGS_EXPLORER_SYSTEM, all_users=True)
@@ -209,6 +188,15 @@ def config_explorer_user():
"""Configure Windows Explorer for current user via Registry settings."""
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)
+ cmd = [
+ r'{BinDir}\ShutUp10\OOSU10.exe'.format(**global_vars),
+ r'{BinDir}\ShutUp10\1201.cfg'.format(**global_vars),
+ '/quiet']
+ run_program(cmd)
+
def update_clock():
"""Set Timezone and sync clock."""
run_program(['tzutil' ,'/s', WINDOWS_TIME_ZONE], check=False)
@@ -221,6 +209,25 @@ 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
+ if all_users:
+ hive = HKLM
+ for k, v in settings.items():
+ # CreateKey
+ access = winreg.KEY_WRITE
+ if 'WOW64_32' in v:
+ access = access | winreg.KEY_WOW64_32KEY
+ winreg.CreateKeyEx(hive, k, 0, access)
+
+ # Create values
+ with winreg.OpenKeyEx(hive, k, 0, access) as key:
+ for name, value in v.get('DWORD Items', {}).items():
+ winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, value)
+ 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."""
@@ -261,7 +268,7 @@ def install_firefox_extensions():
# Update registry
write_registry_settings(SETTINGS_MOZILLA_FIREFOX_32, all_users=True)
write_registry_settings(SETTINGS_MOZILLA_FIREFOX_64, all_users=True)
-
+
# Extract extension(s) to distribution folder
cmd = [
global_vars['Tools']['SevenZip'], 'e', '-aos', '-bso0', '-bse0',
diff --git a/.bin/Scripts/functions/update.py b/.bin/Scripts/functions/update.py
index 9c9cfec0..b4068c22 100644
--- a/.bin/Scripts/functions/update.py
+++ b/.bin/Scripts/functions/update.py
@@ -28,7 +28,7 @@ def compress_item(item):
wd = os.path.abspath(r'{}\{}'.format(wd, os.path.pardir))
include_str = item.name
os.chdir(wd)
-
+
# Compress
cmd = [
global_vars['Tools']['SevenZip'],
@@ -38,7 +38,7 @@ def compress_item(item):
include_str,
]
run_program(cmd)
-
+
# Done
os.chdir(prev_dir)
@@ -96,7 +96,7 @@ def generate_launcher(section, name, options):
dest = global_vars['BaseDir']
full_path = r'{}\{}.cmd'.format(dest, name)
template = r'{}\Scripts\Launcher_Template.cmd'.format(global_vars['BinDir'])
-
+
# Format options
f_options = {}
for opt in options.keys():
@@ -106,7 +106,7 @@ def generate_launcher(section, name, options):
elif re.search(r'^L_\w+', opt, re.IGNORECASE):
new_opt = 'set {}='.format(opt)
f_options[new_opt] = ['set {}={}'.format(opt, options[opt])]
-
+
# Read template and update using f_options
out_text = []
with open(template, 'r') as f:
@@ -118,7 +118,7 @@ def generate_launcher(section, name, options):
out_text.extend(f_options[line])
else:
out_text.append(line)
-
+
# Write file
os.makedirs(dest, exist_ok=True)
with open(full_path, 'w') as f:
@@ -138,7 +138,9 @@ def remove_from_kit(item):
item_locations = []
for p in [global_vars['BinDir'], global_vars['CBinDir']]:
item_locations.append(r'{}\{}'.format(p, item))
+ item_locations.append(r'{}\{}.7z'.format(p, item))
item_locations.append(r'{}\_Drivers\{}'.format(p, item))
+ item_locations.append(r'{}\_Drivers\{}.7z'.format(p, item))
for item_path in item_locations:
remove_item(item_path)
@@ -172,7 +174,7 @@ def scan_for_net_installers(server, family_name, min_year):
"""Scan network shares for installers."""
if not server['Mounted']:
mount_network_share(server)
-
+
if server['Mounted']:
for year in os.scandir(r'\\{IP}\{Share}'.format(**server)):
try:
@@ -204,13 +206,13 @@ def update_testdisk():
for exe in ['fidentify_win.exe', 'photorec_win.exe',
'qphotorec_win.exe', 'testdisk_win.exe']:
kill_process(exe)
-
+
# Remove existing folders
remove_from_kit('TestDisk')
-
+
# Download
download_to_temp('testdisk_wip.zip', SOURCE_URLS['TestDisk'])
-
+
# Extract files
extract_temp_to_cbin('testdisk_wip.zip', 'TestDisk')
dest = r'{}\TestDisk'.format(global_vars['CBinDir'])
@@ -220,7 +222,7 @@ def update_testdisk():
shutil.move(item.path, dest_item)
shutil.rmtree(
r'{}\TestDisk\testdisk-7.1-WIP'.format(global_vars['CBinDir']))
-
+
# Cleanup
remove_from_temp('testdisk_wip.zip')
@@ -230,10 +232,10 @@ def update_fastcopy():
# Stop running processes
for process in ['FastCopy.exe', 'FastCopy64.exe']:
kill_process(process)
-
+
# Remove existing folders
remove_from_kit('FastCopy')
-
+
# Download
download_to_temp('FastCopy.zip', SOURCE_URLS['FastCopy'])
@@ -267,14 +269,14 @@ def update_fastcopy():
def update_wimlib():
# Stop running processes
kill_process('wimlib-imagex.exe')
-
+
# Remove existing folders
remove_from_kit('wimlib')
-
+
# Download
download_to_temp('wimlib32.zip', SOURCE_URLS['wimlib32'])
download_to_temp('wimlib64.zip', SOURCE_URLS['wimlib64'])
-
+
# Extract
extract_generic(
r'{}\wimlib32.zip'.format(global_vars['TmpDir']),
@@ -282,7 +284,7 @@ def update_wimlib():
extract_generic(
r'{}\wimlib64.zip'.format(global_vars['TmpDir']),
r'{}\wimlib\x64'.format(global_vars['CBinDir']))
-
+
# Cleanup
remove_from_temp('wimlib32.zip')
remove_from_temp('wimlib64.zip')
@@ -290,16 +292,16 @@ def update_wimlib():
def update_xyplorer():
# Stop running processes
kill_process('XYplorerFree.exe')
-
+
# Remove existing folders
remove_from_kit('XYplorerFree')
-
+
# Download
download_to_temp('xyplorer_free.zip', SOURCE_URLS['XYplorerFree'])
-
+
# Extract files
extract_temp_to_cbin('xyplorer_free.zip', 'XYplorerFree')
-
+
# Cleanup
remove_from_temp('xyplorer_free.zip')
@@ -307,16 +309,16 @@ def update_xyplorer():
def update_aida64():
# Stop running processes
kill_process('notepadplusplus.exe')
-
+
# Remove existing folders
remove_from_kit('AIDA64')
-
+
# Download
download_to_temp('aida64.zip', SOURCE_URLS['AIDA64'])
-
+
# Extract files
extract_temp_to_cbin('aida64.zip', 'AIDA64')
-
+
# Cleanup
remove_from_temp('aida64.zip')
@@ -324,37 +326,37 @@ def update_autoruns():
# Stop running processes
kill_process('Autoruns.exe')
kill_process('Autoruns64.exe')
-
+
# Remove existing folders
remove_from_kit('Autoruns')
-
+
# Download
download_to_temp('Autoruns.zip', SOURCE_URLS['Autoruns'])
-
+
# Extract files
extract_temp_to_cbin('Autoruns.zip', 'Autoruns')
-
+
# Cleanup
remove_from_temp('Autoruns.zip')
def update_bleachbit():
# Stop running processes
kill_process('bleachbit.exe')
-
+
# Remove existing folders
remove_from_kit('BleachBit')
-
+
# Download
download_to_temp('bleachbit.zip', SOURCE_URLS['BleachBit'])
download_to_temp('Winapp2.zip', SOURCE_URLS['Winapp2'])
-
+
# Extract files
extract_temp_to_cbin('bleachbit.zip', 'BleachBit')
extract_generic(
r'{}\Winapp2.zip'.format(global_vars['TmpDir']),
r'{}\BleachBit\cleaners'.format(global_vars['CBinDir']),
mode='e', sz_args=[r'Winapp2-master\Non-CCleaner\Winapp2.ini'])
-
+
# Move files into place
dest = r'{}\BleachBit'.format(global_vars['CBinDir'])
for item in os.scandir(r'{}\BleachBit-Portable'.format(dest)):
@@ -363,7 +365,7 @@ def update_bleachbit():
shutil.move(item.path, dest_item)
shutil.rmtree(
r'{}\BleachBit\BleachBit-Portable'.format(global_vars['CBinDir']))
-
+
# Cleanup
remove_from_temp('bleachbit.zip')
remove_from_temp('Winapp2.zip')
@@ -372,21 +374,21 @@ def update_bluescreenview():
# Stop running processes
for exe in ['BlueScreenView.exe', 'BlueScreenView64.exe']:
kill_process(exe)
-
+
# Remove existing folders
remove_from_kit('BlueScreenView')
-
+
# Download
download_to_temp('bluescreenview32.zip', SOURCE_URLS['BlueScreenView32'])
download_to_temp('bluescreenview64.zip', SOURCE_URLS['BlueScreenView64'])
-
+
# Extract files
extract_temp_to_cbin('bluescreenview64.zip', 'BlueScreenView', sz_args=['BlueScreenView.exe'])
shutil.move(
r'{}\BlueScreenView\BlueScreenView.exe'.format(global_vars['CBinDir']),
r'{}\BlueScreenView\BlueScreenView64.exe'.format(global_vars['CBinDir']))
extract_temp_to_cbin('bluescreenview32.zip', 'BlueScreenView')
-
+
# Cleanup
remove_from_temp('bluescreenview32.zip')
remove_from_temp('bluescreenview64.zip')
@@ -394,16 +396,16 @@ def update_bluescreenview():
def update_erunt():
# Stop running processes
kill_process('ERUNT.EXE')
-
+
# Remove existing folders
remove_from_kit('ERUNT')
-
+
# Download
download_to_temp('erunt.zip', SOURCE_URLS['ERUNT'])
-
+
# Extract files
extract_temp_to_cbin('erunt.zip', 'ERUNT')
-
+
# Cleanup
remove_from_temp('erunt.zip')
@@ -411,10 +413,10 @@ def update_hitmanpro():
# Stop running processes
for exe in ['HitmanPro.exe', 'HitmanPro64.exe']:
kill_process(exe)
-
+
# Remove existing folders
remove_from_kit('HitmanPro')
-
+
# Download
dest = r'{}\HitmanPro'.format(global_vars['CBinDir'])
download_generic(dest, 'HitmanPro.exe', SOURCE_URLS['HitmanPro32'])
@@ -425,35 +427,58 @@ def update_hwinfo():
# Stop running processes
for exe in ['HWiNFO32.exe', 'HWiNFO64.exe']:
kill_process(exe)
-
+
# Download
download_to_temp('HWiNFO.zip', SOURCE_URLS['HWiNFO'])
-
+
# Extract files
extract_temp_to_bin('HWiNFO.zip', 'HWiNFO')
-
+
# Cleanup
remove_from_temp('HWiNFO.zip')
+def update_nircmd():
+ # Stop running processes
+ for exe in ['nircmdc.exe', 'nircmdc64.exe']:
+ kill_process(exe)
+
+ # Remove existing folders
+ remove_from_kit('NirCmd')
+
+ # Download
+ download_to_temp('nircmd32.zip', SOURCE_URLS['NirCmd32'])
+ download_to_temp('nircmd64.zip', SOURCE_URLS['NirCmd64'])
+
+ # Extract files
+ extract_temp_to_cbin('nircmd64.zip', 'NirCmd', sz_args=['nircmdc.exe'])
+ shutil.move(
+ r'{}\NirCmd\nircmdc.exe'.format(global_vars['CBinDir']),
+ r'{}\NirCmd\nircmdc64.exe'.format(global_vars['CBinDir']))
+ extract_temp_to_cbin('nircmd32.zip', 'NirCmd', sz_args=['nircmdc.exe'])
+
+ # Cleanup
+ remove_from_temp('nircmd32.zip')
+ remove_from_temp('nircmd64.zip')
+
def update_produkey():
# Stop running processes
for exe in ['ProduKey.exe', 'ProduKey64.exe']:
kill_process(exe)
-
+
# Remove existing folders
remove_from_kit('ProduKey')
-
+
# Download
download_to_temp('produkey32.zip', SOURCE_URLS['ProduKey32'])
download_to_temp('produkey64.zip', SOURCE_URLS['ProduKey64'])
-
+
# Extract files
extract_temp_to_cbin('produkey64.zip', 'ProduKey', sz_args=['ProduKey.exe'])
shutil.move(
r'{}\ProduKey\ProduKey.exe'.format(global_vars['CBinDir']),
r'{}\ProduKey\ProduKey64.exe'.format(global_vars['CBinDir']))
extract_temp_to_cbin('produkey32.zip', 'ProduKey')
-
+
# Cleanup
remove_from_temp('produkey32.zip')
remove_from_temp('produkey64.zip')
@@ -462,14 +487,14 @@ def update_produkey():
def update_intel_rst():
# Remove existing folders
remove_from_kit('Intel RST')
-
+
# Prep
dest = r'{}\_Drivers\Intel RST'.format(global_vars['CBinDir'])
include_path = r'{}\_include\_Drivers\Intel RST'.format(
global_vars['CBinDir'])
if os.path.exists(include_path):
shutil.copytree(include_path, dest)
-
+
# Download
for name, url in RST_SOURCES.items():
download_generic(dest, name, url)
@@ -477,7 +502,7 @@ def update_intel_rst():
def update_intel_ssd_toolbox():
# Remove existing folders
remove_from_kit('Intel SSD Toolbox.exe')
-
+
# Download
download_generic(
r'{}\_Drivers\Intel SSD Toolbox'.format(global_vars['CBinDir']),
@@ -487,7 +512,7 @@ def update_intel_ssd_toolbox():
def update_samsung_magician():
# Remove existing folders
remove_from_kit('Samsung Magician.exe')
-
+
# Download
download_to_temp('Samsung Magician.zip', SOURCE_URLS['Samsung Magician'])
@@ -509,7 +534,7 @@ def update_sdi_origin():
aria_dest = r'{}\aria2'.format(global_vars['TmpDir'])
aria = r'{}\aria2c.exe'.format(aria_dest)
extract_generic(aria_source, aria_dest, mode='e')
-
+
# Prep for torrent download
download_to_temp('sdio.torrent', SOURCE_URLS['SDIO Torrent'])
sdio_torrent = r'{}\sdio.torrent'.format(global_vars['TmpDir'])
@@ -520,7 +545,7 @@ def update_sdi_origin():
if r and not re.search(r'(\.(bat|inf)|Video|Server|Printer|XP)', line, re.IGNORECASE):
indexes.append(int(r.group(1)))
indexes = [str(i) for i in sorted(indexes)]
-
+
# Download SDI Origin
cmd = [
aria,
@@ -533,13 +558,13 @@ def update_sdi_origin():
run_program(cmd, pipe=False, check=False, shell=True)
sleep(1)
wait_for_process('aria2c')
-
+
# Download SDI Origin extra themes
download_to_temp('sdio_themes.zip', SOURCE_URLS['SDIO Themes'])
theme_source = r'{}\sdio_themes.zip'.format(global_vars['TmpDir'])
theme_dest = r'{}\SDIO_Update\tools\SDI\themes'.format(aria_dest)
extract_generic(theme_source, theme_dest)
-
+
# Move files into place
for item in os.scandir(r'{}\SDIO_Update'.format(aria_dest)):
dest_item = '{}\_Drivers\SDIO\{}'.format(
@@ -551,7 +576,7 @@ def update_sdi_origin():
if (not os.path.exists(dest_item)
and not re.search(r'\.(inf|bat)$', item.name, re.IGNORECASE)):
shutil.move(item.path, dest_item)
-
+
# Cleanup
remove_from_temp('aria2')
remove_from_temp('aria2.zip')
@@ -563,27 +588,42 @@ def update_adobe_reader_dc():
# Prep
dest = r'{}\Installers\Extras\Office'.format(
global_vars['BaseDir'])
-
+
# Remove existing installer
try:
os.remove(r'{}\Adobe Reader DC.exe'.format(dest))
except FileNotFoundError:
pass
-
+
# Download
download_generic(
dest, 'Adobe Reader DC.exe', SOURCE_URLS['Adobe Reader DC'])
+def update_macs_fan_control():
+ # Prep
+ dest = r'{}\Installers'.format(
+ global_vars['BaseDir'])
+
+ # Remove existing installer
+ try:
+ os.remove(r'{}\Macs Fan Control.exe'.format(dest))
+ except FileNotFoundError:
+ pass
+
+ # Download
+ download_generic(
+ dest, 'Macs Fan Control.exe', SOURCE_URLS['Macs Fan Control'])
+
def update_office():
# Remove existing folders
remove_from_kit('_Office')
-
+
# Prep
dest = r'{}\_Office'.format(global_vars['CBinDir'])
include_path = r'{}\_include\_Office'.format(global_vars['CBinDir'])
if os.path.exists(include_path):
shutil.copytree(include_path, dest)
-
+
for year in ['2016']:
# Download and extract
name = 'odt{}.exe'.format(year)
@@ -598,14 +638,14 @@ def update_office():
shutil.move(
r'{}\{}'.format(global_vars['TmpDir'], year),
r'{}\_Office\{}'.format(global_vars['CBinDir'], year))
-
+
# Cleanup
remove_from_temp('odt{}.exe'.format(year))
def update_classic_start_skin():
# Remove existing folders
remove_from_kit('ClassicStartSkin')
-
+
# Download
download_generic(
r'{}\ClassicStartSkin'.format(global_vars['CBinDir']),
@@ -615,13 +655,13 @@ def update_classic_start_skin():
def update_vcredists():
# Remove existing folders
remove_from_kit('_vcredists')
-
+
# Prep
dest = r'{}\_vcredists'.format(global_vars['CBinDir'])
include_path = r'{}\_include\_vcredists'.format(global_vars['CBinDir'])
if os.path.exists(include_path):
shutil.copytree(include_path, dest)
-
+
# Download
for year in VCREDIST_SOURCES.keys():
for bit in ['32', '64']:
@@ -635,10 +675,10 @@ def update_vcredists():
def update_one_ninite(section, dest, name, url, indent=8, width=40):
# Prep
url = 'https://ninite.com/{}/ninite.exe'.format(url)
-
+
# Download
download_generic(out_dir=dest, out_name=name, source_url=url)
-
+
# Copy to Installers folder
installer_parent = r'{}\Installers\Extras\{}'.format(
global_vars['BaseDir'], section)
@@ -662,16 +702,16 @@ def update_all_ninite(indent=8, width=40, other_results={}):
def update_caffeine():
# Stop running processes
kill_process('caffeine.exe')
-
+
# Remove existing folders
remove_from_kit('Caffeine')
-
+
# Download
download_to_temp('caffeine.zip', SOURCE_URLS['Caffeine'])
-
+
# Extract files
extract_temp_to_cbin('caffeine.zip', 'Caffeine')
-
+
# Cleanup
remove_from_temp('caffeine.zip')
@@ -679,16 +719,16 @@ def update_du():
# Stop running processes
kill_process('du.exe')
kill_process('du64.exe')
-
+
# Remove existing folders
remove_from_kit('Du')
-
+
# Download
download_to_temp('du.zip', SOURCE_URLS['Du'])
-
+
# Extract files
extract_temp_to_cbin('du.zip', 'Du')
-
+
# Cleanup
remove_from_temp('du.zip')
@@ -696,21 +736,21 @@ def update_everything():
# Stop running processes
for exe in ['Everything.exe', 'Everything64.exe']:
kill_process(exe)
-
+
# Remove existing folders
remove_from_kit('Everything')
-
+
# Download
download_to_temp('everything32.zip', SOURCE_URLS['Everything32'])
download_to_temp('everything64.zip', SOURCE_URLS['Everything64'])
-
+
# Extract files
extract_temp_to_cbin('everything64.zip', 'Everything', sz_args=['Everything.exe'])
shutil.move(
r'{}\Everything\Everything.exe'.format(global_vars['CBinDir']),
r'{}\Everything\Everything64.exe'.format(global_vars['CBinDir']))
extract_temp_to_cbin('everything32.zip', 'Everything')
-
+
# Cleanup
remove_from_temp('everything32.zip')
remove_from_temp('everything64.zip')
@@ -718,7 +758,7 @@ def update_everything():
def update_firefox_ublock_origin():
# Remove existing folders
remove_from_kit('FirefoxExtensions')
-
+
# Download
download_generic(
r'{}\FirefoxExtensions'.format(global_vars['CBinDir']),
@@ -728,36 +768,36 @@ def update_firefox_ublock_origin():
def update_notepadplusplus():
# Stop running processes
kill_process('notepadplusplus.exe')
-
+
# Remove existing folders
remove_from_kit('NotepadPlusPlus')
-
+
# Download
download_to_temp('npp.7z', SOURCE_URLS['NotepadPlusPlus'])
-
+
# Extract files
extract_temp_to_cbin('npp.7z', 'NotepadPlusPlus')
shutil.move(
r'{}\NotepadPlusPlus\notepad++.exe'.format(global_vars['CBinDir']),
r'{}\NotepadPlusPlus\notepadplusplus.exe'.format(global_vars['CBinDir'])
)
-
+
# Cleanup
remove_from_temp('npp.7z')
def update_putty():
# Stop running processes
kill_process('PUTTY.EXE')
-
+
# Remove existing folders
remove_from_kit('PuTTY')
-
+
# Download
download_to_temp('putty.zip', SOURCE_URLS['PuTTY'])
-
+
# Extract files
extract_temp_to_cbin('putty.zip', 'PuTTY')
-
+
# Cleanup
remove_from_temp('putty.zip')
@@ -765,34 +805,34 @@ def update_wiztree():
# Stop running processes
for process in ['WizTree.exe', 'WizTree64.exe']:
kill_process(process)
-
+
# Remove existing folders
remove_from_kit('WizTree')
-
+
# Download
download_to_temp(
'wiztree.zip', SOURCE_URLS['WizTree'])
-
+
# Extract files
extract_temp_to_cbin('wiztree.zip', 'WizTree')
-
+
# Cleanup
remove_from_temp('wiztree.zip')
def update_xmplay():
# Stop running processes
kill_process('xmplay.exe')
-
+
# Remove existing folders
remove_from_kit('XMPlay')
-
+
# Download
download_to_temp('xmplay.zip', SOURCE_URLS['XMPlay'])
download_to_temp('xmp-7z.zip', SOURCE_URLS['XMPlay 7z'])
download_to_temp('xmp-gme.zip', SOURCE_URLS['XMPlay Game'])
download_to_temp('xmp-rar.zip', SOURCE_URLS['XMPlay RAR'])
download_to_temp('WAModern.zip', SOURCE_URLS['XMPlay WAModern'])
-
+
# Extract files
extract_temp_to_cbin('xmplay.zip', 'XMPlay',
mode='e', sz_args=['xmplay.exe', 'xmplay.txt'])
@@ -804,7 +844,7 @@ def update_xmplay():
r'{}\{}.zip'.format(global_vars['TmpDir'], item),
r'{}\XMPlay\plugins'.format(global_vars['CBinDir']),
mode='e', sz_args=filter)
-
+
# Download Music
dest = r'{}\XMPlay\music_tmp\MOD'.format(global_vars['CBinDir'])
for mod in MUSIC_MOD:
@@ -816,7 +856,7 @@ def update_xmplay():
name = '{}.rsn'.format(game)
url = 'http://snesmusic.org/v2/download.php?spcNow={}'.format(game)
download_generic(dest, name, url)
-
+
# Compress Music
cmd = [
global_vars['Tools']['SevenZip'],
@@ -825,7 +865,7 @@ def update_xmplay():
r'{}\XMPlay\music_tmp\*'.format(global_vars['CBinDir']),
]
run_program(cmd)
-
+
# Cleanup
remove_item(r'{}\XMPlay\music_tmp'.format(global_vars['CBinDir']))
remove_from_temp('xmplay.zip')
@@ -838,10 +878,10 @@ def update_xmplay():
def update_adwcleaner():
# Stop running processes
kill_process('AdwCleaner.exe')
-
+
# Remove existing folders
remove_from_kit('AdwCleaner')
-
+
# Download
download_generic(
r'{}\AdwCleaner'.format(global_vars['CBinDir']),
@@ -851,10 +891,10 @@ def update_adwcleaner():
def update_kvrt():
# Stop running processes
kill_process('KVRT.exe')
-
+
# Remove existing folders
remove_from_kit('KVRT')
-
+
# Download
download_generic(
r'{}\KVRT'.format(global_vars['CBinDir']),
@@ -864,10 +904,10 @@ def update_kvrt():
def update_rkill():
# Stop running processes
kill_process('RKill.exe')
-
+
# Remove existing folders
remove_from_kit('RKill')
-
+
# Download
url = resolve_dynamic_url(
SOURCE_URLS['RKill'],
@@ -878,10 +918,10 @@ def update_rkill():
def update_tdsskiller():
# Stop running processes
kill_process('TDSSKiller.exe')
-
+
# Remove existing folders
remove_from_kit('TDSSKiller')
-
+
# Download
download_generic(
r'{}\TDSSKiller'.format(global_vars['CBinDir']),
@@ -892,22 +932,22 @@ def update_tdsskiller():
def update_iobit_uninstaller():
# Stop running processes
kill_process('IObitUninstallerPortable.exe')
-
+
# Remove existing folders
remove_from_kit('IObitUninstallerPortable')
-
+
# Download
download_generic(
global_vars['CBinDir'],
'IObitUninstallerPortable.exe',
SOURCE_URLS['IOBit_Uninstaller'])
-
+
# "Install"
cmd = r'{}\IObitUninstallerPortable.exe'.format(global_vars['CBinDir'])
popen_program(cmd)
sleep(1)
wait_for_process('IObitUninstallerPortable')
-
+
# Cleanup
remove_from_kit('IObitUninstallerPortable.exe')
diff --git a/.bin/Scripts/functions/windows_setup.py b/.bin/Scripts/functions/windows_setup.py
index cd7f8444..0952e64d 100644
--- a/.bin/Scripts/functions/windows_setup.py
+++ b/.bin/Scripts/functions/windows_setup.py
@@ -17,7 +17,7 @@ WINDOWS_VERSIONS = [
{'Name': 'Windows 7 Ultimate',
'Image File': 'Win7',
'Image Name': 'Windows 7 ULTIMATE'},
-
+
{'Name': 'Windows 8.1',
'Image File': 'Win8',
'Image Name': 'Windows 8.1',
@@ -25,7 +25,7 @@ WINDOWS_VERSIONS = [
{'Name': 'Windows 8.1 Pro',
'Image File': 'Win8',
'Image Name': 'Windows 8.1 Pro'},
-
+
{'Name': 'Windows 10 Home',
'Image File': 'Win10',
'Image Name': 'Windows 10 Home',
@@ -75,7 +75,7 @@ def find_windows_image(windows_version):
image['Glob'] = '--ref="{}*.swm"'.format(
image['Path'][:-4])
break
-
+
# Display image to be used (if any) and return
if image:
print_info('Using image: {}'.format(image['Path']))
@@ -122,7 +122,7 @@ def format_gpt(disk):
'set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"',
'gpt attributes=0x8000000000000001',
]
-
+
# Run
run_diskpart(script)
@@ -151,7 +151,7 @@ def format_mbr(disk):
'assign letter="T"',
'set id=27',
]
-
+
# Run
run_diskpart(script)
@@ -197,11 +197,11 @@ def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'):
win = r'{}:\Windows'.format(windows_letter)
winre = r'{}\System32\Recovery\WinRE.wim'.format(win)
dest = r'{}:\Recovery\WindowsRE'.format(tools_letter)
-
+
# Copy WinRE.wim
os.makedirs(dest, exist_ok=True)
shutil.copy(winre, r'{}\WinRE.wim'.format(dest))
-
+
# Set location
cmd = [
r'{}\System32\ReAgentc.exe'.format(win),
@@ -231,7 +231,7 @@ def wim_contains_image(filename, imagename):
run_program(cmd)
except subprocess.CalledProcessError:
return False
-
+
return True
if __name__ == '__main__':
diff --git a/.bin/Scripts/functions/winpe_menus.py b/.bin/Scripts/functions/winpe_menus.py
index 64ffb666..1c732eca 100644
--- a/.bin/Scripts/functions/winpe_menus.py
+++ b/.bin/Scripts/functions/winpe_menus.py
@@ -90,7 +90,7 @@ def menu_backup():
message = 'Assigning letters...',
function = assign_volume_letters,
other_results = other_results)
-
+
# Mount backup shares
mount_backup_shares(read_write=True)
@@ -107,12 +107,12 @@ def menu_backup():
else:
print_error('ERROR: No disks found.')
raise GenericAbort
-
+
# Select disk to backup
disk = select_disk('For which disk are we creating backups?', disks)
if not disk:
raise GenericAbort
-
+
# "Prep" disk
prep_disk_for_backup(destination, disk, backup_prefix)
@@ -150,7 +150,7 @@ def menu_backup():
# Ask to proceed
if (not ask('Proceed with backup?')):
raise GenericAbort
-
+
# Backup partition(s)
print_info('\n\nStarting task.\n')
for par in disk['Partitions']:
@@ -163,7 +163,7 @@ def menu_backup():
if not result['CS'] and not isinstance(result['Error'], GenericAbort):
errors = True
par['Error'] = result['Error']
-
+
# Verify backup(s)
if disk['Valid Partitions']:
print_info('\n\nVerifying backup images(s)\n')
@@ -270,7 +270,7 @@ def menu_setup():
# Select the version of Windows to apply
windows_version = select_windows_version()
-
+
# Find Windows image
# NOTE: Reassign volume letters to ensure all devices are scanned
try_and_print(
@@ -289,12 +289,12 @@ def menu_setup():
else:
print_error('ERROR: No disks found.')
raise GenericAbort
-
+
# Select disk to use as the OS disk
dest_disk = select_disk('To which disk are we installing Windows?', disks)
if not dest_disk:
raise GenericAbort
-
+
# "Prep" disk
prep_disk_for_formatting(dest_disk)
@@ -323,10 +323,10 @@ def menu_setup():
data = par['Display String'],
warning = True)
print_warning(dest_disk['Format Warnings'])
-
+
if (not ask('Is this correct?')):
raise GenericAbort
-
+
# Safety check
print_standard('\nSAFETY CHECK')
print_warning('All data will be DELETED from the '
@@ -342,7 +342,7 @@ def menu_setup():
function = remove_volume_letters,
other_results = other_results,
keep=windows_image['Letter'])
-
+
# Assign new letter for local source if necessary
if windows_image['Local'] and windows_image['Letter'] in ['S', 'T', 'W']:
new_letter = try_and_print(
@@ -377,13 +377,13 @@ def menu_setup():
# We need to crash as the disk is in an unknown state
print_error('ERROR: Failed to apply image.')
raise GenericAbort
-
+
# Create Boot files
try_and_print(
message = 'Updating boot files...',
function = update_boot_partition,
other_results = other_results)
-
+
# Setup WinRE
try_and_print(
message = 'Updating recovery tools...',
@@ -392,8 +392,8 @@ def menu_setup():
windows_version = windows_version)
# Copy WinPE log(s)
- source = r'{}\Info'.format(global_vars['ClientDir'])
- dest = r'W:\{}\Info'.format(KIT_NAME_SHORT)
+ source = r'{}\Logs'.format(global_vars['ClientDir'])
+ dest = r'W:\{}\Logs\WinPE'.format(KIT_NAME_SHORT)
shutil.copytree(source, dest)
# Print summary
diff --git a/.bin/Scripts/hw-sensors b/.bin/Scripts/hw-sensors
index 2a1a46e0..f251c589 100755
--- a/.bin/Scripts/hw-sensors
+++ b/.bin/Scripts/hw-sensors
@@ -67,7 +67,11 @@ def get_feature_string(chip, feature):
for sf in sfs:
name = sf.name[skipname:].decode("utf-8").strip()
- val = sensors.get_value(chip, sf.number)
+ try:
+ val = sensors.get_value(chip, sf.number)
+ except Exception:
+ # Ignore upstream sensor bugs and lie instead
+ val = -123456789
if 'alarm' in name:
# Skip
continue
diff --git a/.bin/Scripts/init_client_dir.cmd b/.bin/Scripts/init_client_dir.cmd
index 4d73e7ab..302b27d1 100644
--- a/.bin/Scripts/init_client_dir.cmd
+++ b/.bin/Scripts/init_client_dir.cmd
@@ -33,7 +33,7 @@ for /f "tokens=* usebackq" %%f in (`findstr KIT_NAME_SHORT "%SETTINGS%"`) do (
set "KIT_NAME_SHORT=!_v:~0,-1!"
)
set "client_dir=%systemdrive%\%KIT_NAME_SHORT%"
-set "log_dir=%client_dir%\Info\%iso_date%"
+set "log_dir=%client_dir%\Logs\%iso_date%"
:Flags
set _backups=
@@ -45,7 +45,7 @@ set _transfer=
for %%f in (%*) do (
if /i "%%f" == "/DEBUG" (@echo on)
if /i "%%f" == "/Backups" set _backups=True
- if /i "%%f" == "/Info" set _info=True
+ if /i "%%f" == "/Logs" set _logs=True
if /i "%%f" == "/Office" set _office=True
if /i "%%f" == "/Quarantine" set _quarantine=True
if /i "%%f" == "/QuickBooks" set _quickbooks=True
@@ -54,7 +54,9 @@ for %%f in (%*) do (
:CreateDirs
if defined _backups mkdir "%client_dir%\Backups">nul 2>&1
-if defined _info mkdir "%client_dir%\Info">nul 2>&1
+if defined _logs (
+ mkdir "%log_dir%\%KIT_NAME_FULL%">nul 2>&1
+ mkdir "%log_dir%\Tools">nul 2>&1)
if defined _office mkdir "%client_dir%\Office">nul 2>&1
if defined _quarantine mkdir "%client_dir%\Quarantine">nul 2>&1
if defined _quickbooks mkdir "%client_dir%\QuickBooks">nul 2>&1
diff --git a/.bin/Scripts/install_sw_bundle.py b/.bin/Scripts/install_sw_bundle.py
index d98eb8d2..5ee1a8f3 100644
--- a/.bin/Scripts/install_sw_bundle.py
+++ b/.bin/Scripts/install_sw_bundle.py
@@ -9,7 +9,7 @@ sys.path.append(os.getcwd())
from functions.setup import *
init_global_vars()
os.system('title {}: SW Bundle Tool'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\Install SW Bundle.log'.format(**global_vars)
+set_log_file('Install SW Bundle.log')
if __name__ == '__main__':
try:
@@ -34,7 +34,7 @@ if __name__ == '__main__':
answer_mse = ask('Install MSE?')
else:
answer_mse = False
-
+
print_info('Installing Programs')
if answer_adobe_reader:
try_and_print(message='Adobe Reader DC...',
@@ -62,3 +62,5 @@ if __name__ == '__main__':
pass
except:
major_exception()
+
+# vim: sts=4 sw=4 ts=4
diff --git a/.bin/Scripts/install_vcredists.py b/.bin/Scripts/install_vcredists.py
index 4a1f53ea..fd953551 100644
--- a/.bin/Scripts/install_vcredists.py
+++ b/.bin/Scripts/install_vcredists.py
@@ -9,7 +9,7 @@ sys.path.append(os.getcwd())
from functions.setup import *
init_global_vars()
os.system('title {}: Install Visual C++ Runtimes'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\Install Visual C++ Runtimes.log'.format(**global_vars)
+set_log_file('Install Visual C++ Runtimes.log')
if __name__ == '__main__':
try:
@@ -20,12 +20,12 @@ if __name__ == '__main__':
'Error': {
'CalledProcessError': 'Unknown Error',
}}
-
+
if ask('Install Visual C++ Runtimes?'):
install_vcredists()
else:
abort()
-
+
print_standard('\nDone.')
exit_script()
except SystemExit:
diff --git a/.bin/Scripts/mount-backup-shares b/.bin/Scripts/mount-backup-shares
index 9706a0a5..9f3612b6 100755
--- a/.bin/Scripts/mount-backup-shares
+++ b/.bin/Scripts/mount-backup-shares
@@ -22,7 +22,7 @@ if __name__ == '__main__':
# Mount
if is_connected():
- mount_backup_shares()
+ mount_backup_shares(read_write=True)
else:
# Couldn't connect
print_error('ERROR: No network connectivity.')
diff --git a/.bin/Scripts/pacinit b/.bin/Scripts/pacinit
new file mode 100755
index 00000000..eda3f960
--- /dev/null
+++ b/.bin/Scripts/pacinit
@@ -0,0 +1,15 @@
+#!/bin/bash
+#
+## Wizard Kit: Update pacman settings to usage in live sessions
+
+# Disable custom repo (used at build-time)
+sudo sed -i -r "s/^(\[custom\])/#\1/" /etc/pacman.conf
+sudo sed -i -r "s/^(SigLevel = Optional TrustAll)/#\1/" /etc/pacman.conf
+sudo sed -i -r "s/^(Server = )/#\1/" /etc/pacman.conf
+
+# Disable signature checks
+sudo sed -i -r "s/^SigLevel.*/SigLevel = Never/" /etc/pacman.conf
+
+# Refresh package databases
+sudo pacman -Sy
+
diff --git a/.bin/Scripts/photorec-sort b/.bin/Scripts/photorec-sort
new file mode 100755
index 00000000..6f11b0a6
--- /dev/null
+++ b/.bin/Scripts/photorec-sort
@@ -0,0 +1,150 @@
+#!/bin/bash
+#
+## sort photorec results into something usefull
+
+## Set paths
+recup_dir="${1%/}"
+[ -n "$recup_dir" ] || recup_dir="."
+recup_dir="$(realpath "$recup_dir")"
+out_dir="$recup_dir/Recovered"
+bad_dir="$recup_dir/Corrupt"
+
+## Test path before starting (using current dir if not specified)
+for d in $recup_dir/recup*; do
+ ### Source: http://stackoverflow.com/a/6364244
+ ## Check if the glob gets expanded to existing files.
+ ## If not, f here will be exactly the pattern above
+ ## and the exists test will evaluate to false.
+ [ -e "$d" ] && echo "Found recup folder(s)" || {
+ echo "ERROR: No recup folders found"
+ echo "Usage: $0 recup_dir"
+ exit 1
+ }
+
+ ## This is all we needed to know, so we can break after the first iteration
+ break
+done
+
+# Hard link files into folders by type
+for d in $recup_dir/recup*; do
+ if [ -d "$d" ]; then
+ echo "Linking $d"
+ pushd $d >/dev/null
+ find -type f | while read k; do
+ file="$(basename "$k")"
+ src="$(realpath "$k")"
+ ext="$(echo "${file##*.}" | tr '[:upper:]' '[:lower:]')"
+ ext_dir="$out_dir/$ext"
+ if [ "${file##*.}" = "$file" ]; then
+ ext_dir="$out_dir/_MISC_"
+ elif [ "$ext" = "jpg" ] && [ "${file:0:1}" = "t" ]; then
+ ext_dir="$out_dir/jpg-thumbnail"
+ fi
+ #echo " $file -> $ext_dir"
+ [ -d "$ext_dir" ] || mkdir -p "$ext_dir"
+ ln "$src" "$ext_dir"
+ done
+ popd >/dev/null
+ else
+ echo "ERROR: '$d' not a directory"
+ fi
+done
+
+## Check the files output by photorec for corruption
+pushd "$out_dir" >/dev/null
+
+# Check archives with 7-Zip
+#for d in 7z bz2 gz lzh lzo rar tar xz zip; do
+# if [ -d "$d" ]; then
+# echo "Checking $d files"
+# pushd "$d" >/dev/null
+# for f in *; do
+# if ! 7z t "$f" >/dev/null 2>&1; then
+# #echo " BAD: $f"
+# [ -d "$bad_dir/$d" ] || mkdir -p "$bad_dir/$d"
+# mv -n "$f" "$bad_dir/$d/$f"
+# fi
+# done
+# popd >/dev/null
+# fi
+#done
+
+# Check Audio/Video files with ffprobe
+for d in avi flac flv m4a m4p m4v mkv mid mov mp2 mp3 mp4 mpg mpg2 ogg ts vob wav; do
+ if [ -d "$d" ]; then
+ echo "Checking $d files"
+ pushd "$d" >/dev/null
+ for f in *; do
+ if ! ffprobe "$f" >/dev/null 2>&1; then
+ #echo " BAD: $f"
+ [ -d "$bad_dir/$d" ] || mkdir -p "$bad_dir/$d"
+ mv -n "$f" "$bad_dir/$d/$f"
+ fi
+ done
+ popd >/dev/null
+ fi
+done
+
+# Check .doc files with antiword
+if [ -d "doc" ]; then
+ echo "Checking doc files"
+ pushd "doc" >/dev/null
+ for f in *doc; do
+ if ! antiword "$f" >/dev/null 2>&1; then
+ #echo " BAD: $f"
+ [ -d "$bad_dir/doc" ] || mkdir -p "$bad_dir/doc"
+ mv -n "$f" "$bad_dir/doc/$f"
+ fi
+ done
+ popd >/dev/null
+fi
+
+# Check .docx files with 7z and grep
+if [ -d "docx" ]; then
+ echo "Checking docx files"
+ pushd "docx" >/dev/null
+ for f in *docx; do
+ if ! 7z l "$f" | grep -q -s "word/document.xml"; then
+ #echo " BAD: $f"
+ [ -d "$bad_dir/docx" ] || mkdir -p "$bad_dir/docx"
+ mv -n "$f" "$bad_dir/docx/$f"
+ fi
+ done
+ popd >/dev/null
+fi
+
+# Sort pictures by date (only for common camera formats)
+for d in jpg mrw orf raf raw rw2 tif x3f; do
+ if [ -d "$d" ]; then
+ echo "Sorting $d files by date"
+ pushd "$d" >/dev/null
+ for f in *; do
+ date_dir="$(date -d "$(stat -c %y "$f")" +"%F")"
+ [ -d "$date_dir" ] || mkdir "$date_dir"
+ mv -n "$f" "$date_dir/"
+ done
+ popd >/dev/null
+ fi
+done
+
+# Sort mov files by encoded date
+if [ -d "mov" ]; then
+ echo "Sorting mov files by date"
+ pushd "mov" >/dev/null
+ for f in *mov; do
+ enc_date="$(mediainfo "$f" | grep -i "Encoded date" | head -1 | sed -r 's/.*: //')"
+ date_dir="$(date -d "$enc_date" +"%F")"
+ echo "$date_dir" | grep -E -q -s '^[0-9]{4}-[0-9]{2}-[0-9]{2}$' || date_dir="Unknown Date"
+ [ -d "$date_dir" ] || mkdir "$date_dir"
+ mv -n "$f" "$date_dir/"
+ done
+ popd >/dev/null
+fi
+
+## sort audio files by tags
+
+## sort matroska files by metadata
+
+## return to original dir
+popd >/dev/null
+
diff --git a/.bin/Scripts/remount-rw b/.bin/Scripts/remount-rw
index 4a0b833e..1ba4b41d 100755
--- a/.bin/Scripts/remount-rw
+++ b/.bin/Scripts/remount-rw
@@ -18,6 +18,4 @@ if udevil mount $DEVICE; then
else
echo "Failed"
fi
-
-sleep 2s
exit 0
diff --git a/.bin/Scripts/safemode_enter.py b/.bin/Scripts/safemode_enter.py
index c3213cb9..cce7e28a 100644
--- a/.bin/Scripts/safemode_enter.py
+++ b/.bin/Scripts/safemode_enter.py
@@ -17,16 +17,16 @@ if __name__ == '__main__':
other_results = {
'Error': {'CalledProcessError': 'Unknown Error'},
'Warning': {}}
-
+
if not ask('Enable booting to SafeMode (with Networking)?'):
abort()
-
+
# Configure SafeMode
try_and_print(message='Set BCD option...',
function=enable_safemode, other_results=other_results)
try_and_print(message='Enable MSI in SafeMode...',
function=enable_safemode_msi, other_results=other_results)
-
+
# Done
print_standard('\nDone.')
pause('Press Enter to reboot...')
diff --git a/.bin/Scripts/safemode_exit.py b/.bin/Scripts/safemode_exit.py
index 1449cff5..af66222e 100644
--- a/.bin/Scripts/safemode_exit.py
+++ b/.bin/Scripts/safemode_exit.py
@@ -17,16 +17,16 @@ if __name__ == '__main__':
other_results = {
'Error': {'CalledProcessError': 'Unknown Error'},
'Warning': {}}
-
+
if not ask('Disable booting to SafeMode?'):
abort()
-
+
# Configure SafeMode
try_and_print(message='Remove BCD option...',
function=disable_safemode, other_results=other_results)
try_and_print(message='Disable MSI in SafeMode...',
function=disable_safemode_msi, other_results=other_results)
-
+
# Done
print_standard('\nDone.')
pause('Press Enter to reboot...')
diff --git a/.bin/Scripts/settings/launchers.py b/.bin/Scripts/settings/launchers.py
index a125a1f8..43e8e158 100644
--- a/.bin/Scripts/settings/launchers.py
+++ b/.bin/Scripts/settings/launchers.py
@@ -54,7 +54,7 @@ LAUNCHERS = {
'L_PATH': 'FastCopy',
'L_ITEM': 'FastCopy.exe',
'L_ARGS': (
- r' /logfile=%log_dir%\FastCopy.log'
+ r' /logfile=%log_dir%\Tools\FastCopy.log'
r' /cmd=noexist_only'
r' /utf8'
r' /skip_empty_dir'
@@ -94,7 +94,7 @@ LAUNCHERS = {
),
'L_ELEV': 'True',
'Extra Code': [
- r'call "%bin%\Scripts\init_client_dir.cmd" /Info /Transfer',
+ r'call "%bin%\Scripts\init_client_dir.cmd" /Logs /Transfer',
],
},
'FastCopy': {
@@ -102,7 +102,7 @@ LAUNCHERS = {
'L_PATH': 'FastCopy',
'L_ITEM': 'FastCopy.exe',
'L_ARGS': (
- r' /logfile=%log_dir%\FastCopy.log'
+ r' /logfile=%log_dir%\Tools\FastCopy.log'
r' /cmd=noexist_only'
r' /utf8'
r' /skip_empty_dir'
@@ -141,7 +141,7 @@ LAUNCHERS = {
r' /to=%client_dir%\Transfer_%iso_date%\ '
),
'Extra Code': [
- r'call "%bin%\Scripts\init_client_dir.cmd" /Info /Transfer',
+ r'call "%bin%\Scripts\init_client_dir.cmd" /Logs /Transfer',
],
},
'KVRT': {
@@ -212,7 +212,6 @@ LAUNCHERS = {
r')',
],
},
- },
r'Diagnostics\Extras': {
'AIDA64': {
'L_TYPE': 'Executable',
@@ -251,10 +250,10 @@ LAUNCHERS = {
'L_TYPE': 'Executable',
'L_PATH': 'erunt',
'L_ITEM': 'ERUNT.EXE',
- 'L_ARGS': '%client_dir%\Backups\%iso_date%\Registry sysreg curuser otherusers',
+ 'L_ARGS': '%client_dir%\Backups\Registry\%iso_date% sysreg curuser otherusers',
'L_ELEV': 'True',
'Extra Code': [
- r'call "%bin%\Scripts\init_client_dir.cmd" /Info',
+ r'call "%bin%\Scripts\init_client_dir.cmd" /Logs',
],
},
'HitmanPro': {
@@ -262,7 +261,7 @@ LAUNCHERS = {
'L_PATH': 'HitmanPro',
'L_ITEM': 'HitmanPro.exe',
'Extra Code': [
- r'call "%bin%\Scripts\init_client_dir.cmd" /Info',
+ r'call "%bin%\Scripts\init_client_dir.cmd" /Logs',
],
},
'HWiNFO (Sensors)': {
@@ -455,11 +454,6 @@ LAUNCHERS = {
'L_ITEM': 'WizTree.exe',
'L_ELEV': 'True',
},
- 'Update Kit': {
- 'L_TYPE': 'PyScript',
- 'L_PATH': 'Scripts',
- 'L_ITEM': 'update_kit.py',
- },
'XMPlay': {
'L_TYPE': 'Executable',
'L_PATH': 'XMPlay',
@@ -524,8 +518,10 @@ LAUNCHERS = {
'L_TYPE': 'Executable',
'L_PATH': 'RKill',
'L_ITEM': 'RKill.exe',
+ 'L_ARGS': '-s -l %log_dir%\Tools\RKill.log',
+ 'L_ELEV': 'True',
'Extra Code': [
- r'call "%bin%\Scripts\init_client_dir.cmd" /Info',
+ r'call "%bin%\Scripts\init_client_dir.cmd" /Logs',
],
},
'SFC Scan': {
@@ -539,7 +535,7 @@ LAUNCHERS = {
'L_PATH': 'TDSSKiller',
'L_ITEM': 'TDSSKiller.exe',
'L_ARGS': (
- r' -l %log_dir%\TDSSKiller.log'
+ r' -l %log_dir%\Tools\TDSSKiller.log'
r' -qpath %q_dir%'
r' -accepteula'
r' -accepteulaksn'
@@ -560,7 +556,8 @@ LAUNCHERS = {
'L_ITEM': 'IObitUninstallerPortable.exe',
},
},
- }
+ },
+}
if __name__ == '__main__':
print("This file is not meant to be called directly.")
diff --git a/.bin/Scripts/settings/main.py b/.bin/Scripts/settings/main.py
index c49da96e..75fef0fd 100644
--- a/.bin/Scripts/settings/main.py
+++ b/.bin/Scripts/settings/main.py
@@ -1,14 +1,15 @@
# Wizard Kit: Settings - Main / Branding
# Features
-ENABLED_UPLOAD_DATA = False
+ENABLED_OPEN_LOGS = False
ENABLED_TICKET_NUMBERS = False
+ENABLED_UPLOAD_DATA = False
# STATIC VARIABLES (also used by BASH and BATCH files)
## NOTE: There are no spaces around the = for easier parsing in BASH and BATCH
# Main Kit
ARCHIVE_PASSWORD='Abracadabra'
-KIT_NAME_FULL='Wizard Kit'
+KIT_NAME_FULL='WizardKit'
KIT_NAME_SHORT='WK'
SUPPORT_MESSAGE='Please let 2Shirt know by opening an issue on GitHub'
# Live Linux
@@ -19,10 +20,10 @@ TECH_PASSWORD='Abracadabra'
OFFICE_SERVER_IP='10.0.0.10'
QUICKBOOKS_SERVER_IP='10.0.0.10'
# Time Zones
-LINUX_TIME_ZONE='America/Los_Angeles' # See 'timedatectl list-timezones' for valid values
-WINDOWS_TIME_ZONE='Pacific Standard Time' # See 'tzutil /l' for valid values
+LINUX_TIME_ZONE='America/Denver' # See 'timedatectl list-timezones' for valid values
+WINDOWS_TIME_ZONE='Mountain Standard Time' # See 'tzutil /l' for valid values
# WiFi
-WIFI_SSID='SomeWifi'
+WIFI_SSID='SomeWiFi'
WIFI_PASSWORD='Abracadabra'
# SERVER VARIABLES
diff --git a/.bin/Scripts/settings/sources.py b/.bin/Scripts/settings/sources.py
index 903c46fb..9f4350db 100644
--- a/.bin/Scripts/settings/sources.py
+++ b/.bin/Scripts/settings/sources.py
@@ -23,6 +23,9 @@ SOURCE_URLS = {
'Intel SSD Toolbox': r'https://downloadmirror.intel.com/27656/eng/Intel%20SSD%20Toolbox%20-%20v3.5.2.exe',
'IOBit_Uninstaller': 'https://portableapps.duckduckgo.com/IObitUninstallerPortable_7.5.0.7.paf.exe',
'KVRT': 'http://devbuilds.kaspersky-labs.com/devbuilds/KVRT/latest/full/KVRT.exe',
+ 'Macs Fan Control': 'https://www.crystalidea.com/downloads/macsfancontrol_setup.exe',
+ 'NirCmd32': 'https://www.nirsoft.net/utils/nircmd.zip',
+ 'NirCmd64': 'https://www.nirsoft.net/utils/nircmd-x64.zip',
'NotepadPlusPlus': 'https://notepad-plus-plus.org/repository/7.x/7.5.8/npp.7.5.8.bin.minimalist.7z',
'Office Deployment Tool 2016': 'https://download.microsoft.com/download/2/7/A/27AF1BE6-DD20-4CB4-B154-EBAB8A7D4A7E/officedeploymenttool_10810.33603.exe',
'ProduKey32': 'http://www.nirsoft.net/utils/produkey.zip',
@@ -193,6 +196,7 @@ RST_SOURCES = {
'SetupRST_16.5.exe': 'https://downloadmirror.intel.com/27984/eng/SetupRST.exe',
}
-
if __name__ == '__main__':
print("This file is not meant to be called directly.")
+
+# vim: sts=4 sw=4 ts=4 tw=0 nowrap
diff --git a/.bin/Scripts/settings/tools.py b/.bin/Scripts/settings/tools.py
index bb2cda60..b470603c 100644
--- a/.bin/Scripts/settings/tools.py
+++ b/.bin/Scripts/settings/tools.py
@@ -30,6 +30,9 @@ TOOLS = {
'64': r'HWiNFO\HWiNFO64.exe'},
'KVRT': {
'32': r'KVRT\KVRT.exe'},
+ 'NirCmd': {
+ '32': r'NirCmd\nircmdc.exe',
+ '64': r'NirCmd\nircmdc64.exe'},
'NotepadPlusPlus': {
'32': r'NotepadPlusPlus\notepadplusplus.exe'},
'ProduKey': {
diff --git a/.bin/Scripts/settings/windows_builds.py b/.bin/Scripts/settings/windows_builds.py
index bdac8bf4..2db18b6f 100644
--- a/.bin/Scripts/settings/windows_builds.py
+++ b/.bin/Scripts/settings/windows_builds.py
@@ -6,16 +6,16 @@ WINDOWS_BUILDS = {
'6000': ( 'Vista', 'RTM', 'Longhorn', None, 'unsupported'),
'6001': ( 'Vista', 'SP1', 'Longhorn', None, 'unsupported'),
'6002': ( 'Vista', 'SP2', 'Longhorn', None, 'unsupported'),
-
+
'7600': ( '7', 'RTM', 'Vienna', None, 'unsupported'),
'7601': ( '7', 'SP1', 'Vienna', None, 'outdated'),
-
+
#9199 is a fake build since Win 8 is 6.2.9200 but that collides with Win 8.1 (6.3.9200)
'9199': ( '8', 'RTM', None, None, 'unsupported'),
'9200': ( '8.1', None, 'Blue', None, 'outdated'),
'9600': ( '8.1', None, 'Update', None, None),
-
+
'9841': ( '10', None, 'Threshold 1', None, 'preview build'),
'9860': ( '10', None, 'Threshold 1', None, 'preview build'),
'9879': ( '10', None, 'Threshold 1', None, 'preview build'),
@@ -149,6 +149,36 @@ WINDOWS_BUILDS = {
'17655': ( '10', None, 'Redstone 5', None, 'preview build'),
'17661': ( '10', None, 'Redstone 5', None, 'preview build'),
'17666': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17677': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17682': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17686': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17692': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17704': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17711': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17713': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17723': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17728': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17730': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17733': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17735': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17738': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17741': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17744': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17746': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17751': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17754': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17755': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17758': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17760': ( '10', None, 'Redstone 5', None, 'preview build'),
+ '17763': ( '10', 'v1809', 'Redstone 5', 'October 2018 Update', 'preview build'),
+ '18204': ( '10', None, '19H1', None, 'preview build'),
+ '18214': ( '10', None, '19H1', None, 'preview build'),
+ '18219': ( '10', None, '19H1', None, 'preview build'),
+ '18234': ( '10', None, '19H1', None, 'preview build'),
+ '18237': ( '10', None, '19H1', None, 'preview build'),
+ '18242': ( '10', None, '19H1', None, 'preview build'),
+ '18247': ( '10', None, '19H1', None, 'preview build'),
+ '18252': ( '10', None, '19H1', None, 'preview build'),
}
if __name__ == '__main__':
diff --git a/.bin/Scripts/sfc_scan.py b/.bin/Scripts/sfc_scan.py
index 81211747..d7a3d3fc 100644
--- a/.bin/Scripts/sfc_scan.py
+++ b/.bin/Scripts/sfc_scan.py
@@ -9,7 +9,7 @@ sys.path.append(os.getcwd())
from functions.repairs import *
init_global_vars()
os.system('title {}: SFC Tool'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\SFC Tool.log'.format(**global_vars)
+set_log_file('SFC Tool.log')
if __name__ == '__main__':
try:
@@ -28,7 +28,7 @@ if __name__ == '__main__':
function=run_sfc_scan, other_results=other_results)
else:
abort()
-
+
# Done
print_standard('\nDone.')
pause('Press Enter to exit...')
diff --git a/.bin/Scripts/system_checklist.py b/.bin/Scripts/system_checklist.py
index 73410d92..a76433ee 100644
--- a/.bin/Scripts/system_checklist.py
+++ b/.bin/Scripts/system_checklist.py
@@ -14,7 +14,7 @@ from functions.product_keys import *
from functions.setup import *
init_global_vars()
os.system('title {}: System Checklist Tool'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\System Checklist.log'.format(**global_vars)
+set_log_file('System Checklist.log')
if __name__ == '__main__':
try:
@@ -24,11 +24,17 @@ if __name__ == '__main__':
ticket_number = get_ticket_number()
other_results = {
'Error': {
- 'CalledProcessError': 'Unknown Error',
- 'BIOSKeyNotFoundError': 'BIOS key not found',
- 'FileNotFoundError': 'File not found',
+ 'BIOSKeyNotFoundError': 'BIOS key not found',
+ 'CalledProcessError': 'Unknown Error',
+ 'FileNotFoundError': 'File not found',
+ 'GenericError': 'Unknown Error',
+ 'SecureBootDisabledError': 'Disabled',
},
- 'Warning': {}}
+ 'Warning': {
+ 'OSInstalledLegacyError': 'OS installed Legacy',
+ 'SecureBootNotAvailError': 'Not available',
+ 'SecureBootUnknownError': 'Unknown',
+ }}
if ENABLED_TICKET_NUMBERS:
print_info('Starting System Checklist for Ticket #{}\n'.format(
ticket_number))
@@ -43,10 +49,13 @@ if __name__ == '__main__':
# Cleanup
print_info('Cleanup')
- try_and_print(message='Desktop...',
- function=cleanup_desktop, cs='Done')
try_and_print(message='AdwCleaner...',
function=cleanup_adwcleaner, cs='Done', other_results=other_results)
+ try_and_print(message='Desktop...',
+ function=cleanup_desktop, cs='Done')
+ try_and_print(message='{}...'.format(KIT_NAME_FULL),
+ function=delete_empty_folders, cs='Done',
+ folder_path=global_vars['ClientDir'])
# Export system info
print_info('Backup System Information')
@@ -76,6 +85,8 @@ if __name__ == '__main__':
try_and_print(message='BIOS Activation:',
function=activate_with_bios,
other_results=other_results)
+ try_and_print(message='Secure Boot Status:',
+ function=check_secure_boot_status, other_results=other_results)
try_and_print(message='Installed RAM:',
function=show_installed_ram, ns='Unknown', silent_function=False)
show_free_space()
@@ -99,6 +110,11 @@ if __name__ == '__main__':
sleep(3)
try_and_print(message='Running XMPlay...',
function=run_xmplay, cs='Started', other_results=other_results)
+ try:
+ check_secure_boot_status(show_alert=True)
+ except:
+ # Only trying to open alert message boxes
+ pass
# Done
print_standard('\nDone.')
@@ -108,3 +124,5 @@ if __name__ == '__main__':
pass
except:
major_exception()
+
+# vim: sts=4 sw=4 ts=4
diff --git a/.bin/Scripts/system_diagnostics.py b/.bin/Scripts/system_diagnostics.py
index 9a6e1c0b..bbeb2d11 100644
--- a/.bin/Scripts/system_diagnostics.py
+++ b/.bin/Scripts/system_diagnostics.py
@@ -13,8 +13,54 @@ from functions.product_keys import *
from functions.repairs import *
init_global_vars()
os.system('title {}: System Diagnostics Tool'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\System Diagnostics.log'.format(
- **global_vars)
+set_log_file('System Diagnostics.log')
+
+# 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',
+ ),
+}
if __name__ == '__main__':
try:
@@ -34,19 +80,17 @@ if __name__ == '__main__':
if ENABLED_TICKET_NUMBERS:
print_info('Starting System Diagnostics for Ticket #{}\n'.format(
ticket_number))
-
+
# Sanitize Environment
print_info('Sanitizing Environment')
- # try_and_print(message='Killing processes...',
- # function=run_process_killer, cs='Done')
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
print_info('Starting Background Scans')
check_connection()
@@ -54,7 +98,7 @@ if __name__ == '__main__':
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')
try_and_print(
@@ -64,17 +108,23 @@ if __name__ == '__main__':
function=run_sfc_scan, other_results=other_results)
try_and_print(message='DISM CheckHealth...',
function=run_dism, other_results=other_results, repair=False)
-
+
# 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='Done', other_results=other_results,
+ cleaners=v, preview=True)
+
# Export system info
print_info('Backup System Information')
try_and_print(message='AIDA64 reports...',
function=run_aida64, cs='Done', other_results=other_results)
- try_and_print(message='BleachBit report...',
- function=run_bleachbit, cs='Done', other_results=other_results)
backup_browsers()
try_and_print(message='File listing...',
function=backup_file_list, cs='Done', other_results=other_results)
@@ -84,7 +134,7 @@ if __name__ == '__main__':
function=run_produkey, cs='Done', other_results=other_results)
try_and_print(message='Registry...',
function=backup_registry, cs='Done', other_results=other_results)
-
+
# Summary
print_info('Summary')
try_and_print(message='Operating System:',
@@ -104,14 +154,14 @@ if __name__ == '__main__':
other_results=other_results, print_return=True)
try_and_print(message='Product Keys:',
function=get_product_keys, ns='Unknown', print_return=True)
-
+
# User data
print_info('User Data')
try:
show_user_data_summary()
except Exception:
print_error(' Unknown error.')
-
+
# Done
print_standard('\nDone.')
pause('Press Enter to exit...')
@@ -120,3 +170,5 @@ if __name__ == '__main__':
pass
except:
major_exception()
+
+# vim: sts=4 sw=4 ts=4
diff --git a/.bin/Scripts/transferred_keys.py b/.bin/Scripts/transferred_keys.py
index 9829207e..b95ff3c9 100644
--- a/.bin/Scripts/transferred_keys.py
+++ b/.bin/Scripts/transferred_keys.py
@@ -9,7 +9,7 @@ sys.path.append(os.getcwd())
from functions.product_keys import *
init_global_vars()
os.system('title {}: Transferred Key Finder'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\Transferred Keys.log'.format(**global_vars)
+set_log_file('Transferred Keys.log')
if __name__ == '__main__':
try:
@@ -18,7 +18,7 @@ if __name__ == '__main__':
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()
diff --git a/.bin/Scripts/update_kit.py b/.bin/Scripts/update_kit.py
index 7f9b251d..67949d93 100644
--- a/.bin/Scripts/update_kit.py
+++ b/.bin/Scripts/update_kit.py
@@ -18,34 +18,35 @@ if __name__ == '__main__':
'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='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='BlueScreenView...', function=update_bluescreenview, 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='HitmanPro...', function=update_hitmanpro, 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)
@@ -53,41 +54,42 @@ if __name__ == '__main__':
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='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)
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='FirefoxExtensions...', function=update_firefox_ublock_origin, 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='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='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='TDSSKiller...', function=update_tdsskiller, other_results=other_results, width=40)
-
+ try_and_print(message='TDSS Killer...', function=update_tdsskiller, other_results=other_results, width=40)
+
# Uninstallers
print_info(' Uninstallers')
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')
@@ -108,12 +110,12 @@ if __name__ == '__main__':
other_results = other_results,
width=40,
item = item)
-
+
## Search for network Office/QuickBooks installers & add to LAUNCHERS
print_success('Scanning for network installers')
scan_for_net_installers(OFFICE_SERVER, 'Office', min_year=2010)
scan_for_net_installers(QUICKBOOKS_SERVER, 'QuickBooks', min_year=2015)
-
+
## Generate Launchers
print_success('Generating launchers')
for section in sorted(LAUNCHERS.keys()):
@@ -122,7 +124,7 @@ if __name__ == '__main__':
try_and_print(message=name, function=generate_launcher,
section=section, name=name, options=options,
other_results=other_results, width=40)
-
+
# Rename "Copy WizardKit.cmd" (if necessary)
source = r'{}\Scripts\Copy WizardKit.cmd'.format(global_vars['BinDir'])
dest = r'{}\Copy {}.cmd'.format(global_vars['BaseDir'], KIT_NAME_FULL)
@@ -132,7 +134,7 @@ if __name__ == '__main__':
except Exception:
print_error(' Failed to rename "{}.cmd" to "{}.cmd"'.format(
'Copy WizardKit', KIT_NAME_FULL))
-
+
# Done
print_standard('\nDone.')
pause("Press Enter to exit...")
diff --git a/.bin/Scripts/user_checklist.py b/.bin/Scripts/user_checklist.py
index 72697af7..fd348dec 100644
--- a/.bin/Scripts/user_checklist.py
+++ b/.bin/Scripts/user_checklist.py
@@ -11,8 +11,7 @@ from functions.cleanup import *
from functions.setup import *
init_global_vars()
os.system('title {}: User Checklist Tool'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\User Checklist ({USERNAME}).log'.format(
- **global_vars, **global_vars['Env'])
+set_log_file('User Checklist ({USERNAME}).log'.format(**global_vars['Env']))
if __name__ == '__main__':
try:
@@ -31,29 +30,29 @@ if __name__ == '__main__':
if global_vars['OS']['Version'] == '10':
answer_config_classicshell = ask('Configure ClassicShell?')
answer_config_explorer_user = ask('Configure Explorer?')
-
+
# Cleanup
print_info('Cleanup')
try_and_print(message='Desktop...',
function=cleanup_desktop, cs='Done')
-
+
# Scan for supported browsers
print_info('Scanning for browsers')
scan_for_browsers()
-
+
# Homepages
print_info('Current homepages')
list_homepages()
-
+
# Backup
print_info('Backing up browsers')
backup_browsers()
-
+
# Reset
if answer_config_browsers and answer_reset_browsers:
print_info('Resetting browsers')
reset_browsers()
-
+
# Configure
print_info('Configuring programs')
if answer_config_browsers:
@@ -75,7 +74,7 @@ if __name__ == '__main__':
# Run speedtest
popen_program(['start', '', 'https://fast.com'], shell=True)
-
+
# Done
print_standard('\nDone.')
pause('Press Enter to exit...')
@@ -84,3 +83,5 @@ if __name__ == '__main__':
pass
except:
major_exception()
+
+# vim: sts=4 sw=4 ts=4
diff --git a/.bin/Scripts/user_data_transfer.py b/.bin/Scripts/user_data_transfer.py
index ce572f69..981e235a 100644
--- a/.bin/Scripts/user_data_transfer.py
+++ b/.bin/Scripts/user_data_transfer.py
@@ -10,7 +10,7 @@ from functions.data import *
from functions.repairs import *
init_global_vars()
os.system('title {}: User Data Transfer Tool'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\User Data Transfer.log'.format(**global_vars)
+set_log_file('User Data Transfer.log')
if __name__ == '__main__':
try:
@@ -18,7 +18,7 @@ if __name__ == '__main__':
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:
@@ -26,16 +26,16 @@ if __name__ == '__main__':
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')
@@ -43,17 +43,17 @@ if __name__ == '__main__':
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')
diff --git a/.bin/Scripts/winpe_root_menu.py b/.bin/Scripts/winpe_root_menu.py
index 03c763af..743d987b 100644
--- a/.bin/Scripts/winpe_root_menu.py
+++ b/.bin/Scripts/winpe_root_menu.py
@@ -11,7 +11,7 @@ from functions.winpe_menus import *
TOOLS['SevenZip'].pop('64')
init_global_vars()
set_title('{}: Root Menu'.format(KIT_NAME_FULL))
-global_vars['LogFile'] = r'{LogDir}\WinPE.log'.format(**global_vars)
+set_log_file('WinPE.log')
if __name__ == '__main__':
try:
diff --git a/.cbin/_include/NotepadPlusPlus/config.xml b/.cbin/_include/NotepadPlusPlus/config.xml
index c2dd100c..1975e9a7 100644
--- a/.cbin/_include/NotepadPlusPlus/config.xml
+++ b/.cbin/_include/NotepadPlusPlus/config.xml
@@ -4,8 +4,8 @@
standard
- hide
-
+ show
+
vertical
hide
@@ -18,7 +18,7 @@
no
yes
-
+
yes
@@ -29,7 +29,7 @@
- hide
+ show
@@ -37,10 +37,10 @@
-
+
yes
-
+
diff --git a/.linux_items/.gitignore b/.linux_items/.gitignore
deleted file mode 100644
index 5495eced..00000000
--- a/.linux_items/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-wk_tmp
-wk-repo
diff --git a/.linux_items/include/EFI/boot/refind.conf b/.linux_items/include/EFI/boot/refind.conf
index de83e78c..1406ac73 100644
--- a/.linux_items/include/EFI/boot/refind.conf
+++ b/.linux_items/include/EFI/boot/refind.conf
@@ -22,14 +22,15 @@ menuentry "MemTest86" {
menuentry "Linux" {
icon /EFI/boot/icons/wk_arch.png
loader /arch/boot/x86_64/vmlinuz
- initrd /arch/boot/intel_ucode.img
+ initrd /arch/boot/intel_ucode.img
+ initrd /arch/boot/amd_ucode.img
initrd /arch/boot/x86_64/archiso.img
- options "archisobasedir=arch archisolabel=%ARCHISO_LABEL% quiet copytoram loglevel=3"
+ options "archisobasedir=arch archisolabel=%ARCHISO_LABEL% copytoram loglevel=3"
submenuentry "Linux (i3)" {
add_options "i3"
}
submenuentry "Linux (CLI)" {
- add_options "nox"
+ add_options "loglevel=4 nomodeset nox"
}
}
#UFD#menuentry "WindowsPE" {
diff --git a/.linux_items/include/airootfs/etc/modprobe.d/broadcom.conf b/.linux_items/include/airootfs/etc/modprobe.d/broadcom.conf
deleted file mode 100644
index 1c85cd7b..00000000
--- a/.linux_items/include/airootfs/etc/modprobe.d/broadcom.conf
+++ /dev/null
@@ -1 +0,0 @@
-softdep tg3 pre: broadcom
diff --git a/.linux_items/include/airootfs/etc/skel/.aliases b/.linux_items/include/airootfs/etc/skel/.aliases
index 03d15315..d6486258 100644
--- a/.linux_items/include/airootfs/etc/skel/.aliases
+++ b/.linux_items/include/airootfs/etc/skel/.aliases
@@ -10,13 +10,11 @@ alias du='du -sch --apparent-size'
alias fix-perms='find -type d -exec chmod 755 "{}" \; && find -type f -exec chmod 644 "{}" \;'
alias hexedit='hexedit --color'
alias hw-info='sudo hw-info | less -S'
-alias inxi='echo -e "\e[33mWARNING: inxi is being replaced and will be removed in a future WizardKit release\e[0m"; echo -e " \e[32mReplacements include:\e[0m 'hw-drive-info', 'hw-info', & 'hw-sensors'"; echo ""; inxi'
alias less='less -S'
alias ls='ls --color=auto'
alias mkdir='mkdir -p'
alias mount='sudo mount'
alias mv='mv -nv'
-alias pacinit='sudo sed -i -r "s/^SigLevel.*/SigLevel = Never/" /etc/pacman.conf; sudo pacman -Sy'
alias photorec-sort='sudo photorec-sort'
alias photorec='sudo photorec'
alias q1='clear && ls -1'
diff --git a/.linux_items/include/airootfs/etc/skel/.config/i3/config b/.linux_items/include/airootfs/etc/skel/.config/i3/config
index cf09a2ca..ca1a5439 100644
--- a/.linux_items/include/airootfs/etc/skel/.config/i3/config
+++ b/.linux_items/include/airootfs/etc/skel/.config/i3/config
@@ -319,3 +319,5 @@ bar {
status_command i3status
height 26
}
+
+exec --no-startup-id /home/tech/.update_x
diff --git a/.linux_items/include/airootfs/etc/skel/.config/openbox/autostart b/.linux_items/include/airootfs/etc/skel/.config/openbox/autostart
old mode 100644
new mode 100755
index 6eaa6cc3..13b9088c
--- a/.linux_items/include/airootfs/etc/skel/.config/openbox/autostart
+++ b/.linux_items/include/airootfs/etc/skel/.config/openbox/autostart
@@ -1,20 +1,3 @@
-#
-# These things are run when an Openbox X Session is started.
-# You may place a similar script in $HOME/.config/openbox/autostart
-# to run user-specific things.
-#
+#openbox-autostart
-# If you want to use GNOME config tools...
-#
-#if test -x /usr/lib/openbox/gnome-settings-daemon >/dev/null; then
-# /usr/lib/openbox/gnome-settings-daemon &
-#elif which gnome-settings-daemon >/dev/null 2>&1; then
-# gnome-settings-daemon &
-#fi
-
-# If you want to use XFCE config tools...
-#
-#xfce-mcs-manager &
-
-tint2 &
-cbatticon --hide-notification &
+$HOME/.update_x &
diff --git a/.linux_items/include/airootfs/etc/skel/.update_hostname b/.linux_items/include/airootfs/etc/skel/.update_hostname
deleted file mode 100755
index 3c1bd7c2..00000000
--- a/.linux_items/include/airootfs/etc/skel/.update_hostname
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-IP="$(ip a show scope global \
- | grep inet \
- | head -1 \
- | sed -r 's#.*inet ([0-9]+.[0-9]+.[0-9]+.[0-9]+.)/.*#\1#')"
-HOSTNAME="$(dig +noall +answer +short -x "$IP" \
- | head -1 \
- | sed 's/\.$//')"
-
-# Set hostname and renew DHCP lease
-sudo hostnamectl set-hostname "${HOSTNAME}"
-sudo dhclient -r
-sleep 1
-sudo dhclient
-
diff --git a/.linux_items/include/airootfs/etc/skel/.update_network b/.linux_items/include/airootfs/etc/skel/.update_network
new file mode 100755
index 00000000..e7119a37
--- /dev/null
+++ b/.linux_items/include/airootfs/etc/skel/.update_network
@@ -0,0 +1,23 @@
+## .update_network ##
+#!/bin/env bash
+#
+## Connect to network and update hostname
+
+# Connect
+connect-to-network
+sleep 2s
+
+IP="$(ip a show scope global \
+ | grep inet \
+ | head -1 \
+ | sed -r 's#.*inet ([0-9]+.[0-9]+.[0-9]+.[0-9]+.)/.*#\1#')"
+HOSTNAME="$(dig +noall +answer +short -x "$IP" \
+ | grep -v ';' \
+ | head -1 \
+ | sed 's/\.$//')"
+
+# Set hostname
+if [[ "${HOSTNAME:+x}" ]]; then
+ sudo hostnamectl set-hostname "${HOSTNAME}"
+fi
+
diff --git a/.linux_items/include/airootfs/etc/skel/.update_dpi_settings b/.linux_items/include/airootfs/etc/skel/.update_x
similarity index 80%
rename from .linux_items/include/airootfs/etc/skel/.update_dpi_settings
rename to .linux_items/include/airootfs/etc/skel/.update_x
index 2287508c..4763a175 100755
--- a/.linux_items/include/airootfs/etc/skel/.update_dpi_settings
+++ b/.linux_items/include/airootfs/etc/skel/.update_x
@@ -1,6 +1,6 @@
#!/bin/env bash
#
-## Calculate DPI and adjust display settings if necesary
+## Calculate DPI, update settings if necessary, then start desktop apps
REGEX_XRANDR='^.* ([0-9]+)x([0-9]+)\+[0-9]+\+[0-9]+.* ([0-9]+)mm x ([0-9]+)mm.*$'
REGEX_URXVT='(URxvt.geometry:\s+).*'
@@ -66,3 +66,29 @@ fi
# Update URxvt (Always)
urxvt_geometry="${width_urxvt}x${height_urxvt}+${offset_urxvt}+${offset_urxvt}"
sed -i -r "s/${REGEX_URXVT}/\1${urxvt_geometry}/" "${HOME}/.Xresources"
+
+# Update X
+xset s off
+xset -dpms
+xrdb -merge $HOME/.Xresources
+
+# Start common desktop apps
+feh --bg-fill "$HOME/.wallpaper"
+compton --backend xrender --xrender-sync --xrender-sync-fence &
+sleep 1s
+x0vncserver -display :0 -passwordfile $HOME/.vnc/passwd -AlwaysShared &
+conky &
+nm-applet &
+volumeicon &
+
+# Start WM specific apps
+if fgrep -q "i3" /proc/cmdline; then
+ # i3
+ i3-msg restart
+else
+ # openbox
+ openbox --restart
+ tint2 &
+ cbatticon --hide-notification &
+fi
+
diff --git a/.linux_items/include/airootfs/etc/skel/.xinitrc b/.linux_items/include/airootfs/etc/skel/.xinitrc
index abb71f45..7085a4df 100755
--- a/.linux_items/include/airootfs/etc/skel/.xinitrc
+++ b/.linux_items/include/airootfs/etc/skel/.xinitrc
@@ -1,19 +1,7 @@
#!/bin/sh
dbus-update-activation-environment --systemd DISPLAY
-$HOME/.update_dpi_settings
-xrdb -merge $HOME/.Xresources
-xset s off
-xset -dpms
eval $(ssh-agent)
export SSH_AUTH_SOCK
-compton --backend xrender --xrender-sync --xrender-sync-fence &
-sleep 1s
-conky -d
-nm-applet &
-volumeicon &
-connect-to-network &
-$HOME/.update_hostname &
-feh --bg-fill "$HOME/.wallpaper" &
-x0vncserver -display :0 -passwordfile $HOME/.vnc/passwd -AlwaysShared &
exec openbox-session
+
diff --git a/.linux_items/include/airootfs/etc/skel/.zlogin b/.linux_items/include/airootfs/etc/skel/.zlogin
index 0898d1e2..bd736280 100644
--- a/.linux_items/include/airootfs/etc/skel/.zlogin
+++ b/.linux_items/include/airootfs/etc/skel/.zlogin
@@ -1,5 +1,8 @@
-setterm -blank 0 -powerdown 0
+setterm -blank 0 -powerdown 0 2>/dev/null
if [ "$(fgconsole 2>/dev/null)" -eq "1" ]; then
+ # Connect to network and update hostname
+ $HOME/.update_network
+
# Update settings if using i3
if fgrep -q "i3" /proc/cmdline; then
sed -i -r 's/#(own_window_type override)/\1/' ~/.conkyrc
@@ -16,4 +19,3 @@ if [ "$(fgconsole 2>/dev/null)" -eq "1" ]; then
hw-diags cli
fi
fi
-
diff --git a/.linux_items/include/syslinux/wk.cfg b/.linux_items/include/syslinux/wk.cfg
index b9163e25..f37655df 100644
--- a/.linux_items/include/syslinux/wk.cfg
+++ b/.linux_items/include/syslinux/wk.cfg
@@ -2,7 +2,10 @@ DEFAULT select
LABEL select
COM32 boot/syslinux/whichsys.c32
-APPEND -pxe- pxe -sys- sys -iso- sys
+APPEND -pxe- pxe -sys- sys -iso- iso
+
+LABEL iso
+CONFIG boot/syslinux/wk_iso.cfg
LABEL pxe
CONFIG boot/syslinux/wk_pxe.cfg
diff --git a/.linux_items/include/syslinux/wk_iso.cfg b/.linux_items/include/syslinux/wk_iso.cfg
new file mode 100644
index 00000000..fa35a1b6
--- /dev/null
+++ b/.linux_items/include/syslinux/wk_iso.cfg
@@ -0,0 +1,6 @@
+INCLUDE boot/syslinux/wk_head.cfg
+
+INCLUDE boot/syslinux/wk_iso_linux.cfg
+#DISABLED_UPSTREAM_BUG#INCLUDE boot/syslinux/wk_hdt.cfg
+
+INCLUDE boot/syslinux/wk_tail.cfg
diff --git a/.linux_items/include/syslinux/wk_iso_linux.cfg b/.linux_items/include/syslinux/wk_iso_linux.cfg
new file mode 100644
index 00000000..fef9a9e1
--- /dev/null
+++ b/.linux_items/include/syslinux/wk_iso_linux.cfg
@@ -0,0 +1,31 @@
+LABEL wk_iso_linux
+TEXT HELP
+A live Linux environment
+ * HW diagnostics, file-based backups, data recovery, etc
+ENDTEXT
+MENU LABEL Linux
+LINUX boot/x86_64/vmlinuz
+INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
+APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% loglevel=3
+
+LABEL wk_iso_linux_i3
+TEXT HELP
+A live Linux environment (i3)
+ * HW diagnostics, file-based backups, data recovery, etc
+ENDTEXT
+MENU LABEL Linux (i3)
+LINUX boot/x86_64/vmlinuz
+INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
+APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% loglevel=3 i3
+SYSAPPEND 3
+
+LABEL wk_iso_linux_cli
+TEXT HELP
+A live Linux environment (CLI)
+ * HW diagnostics, file-based backups, data recovery, etc
+ENDTEXT
+MENU LABEL Linux (CLI)
+LINUX boot/x86_64/vmlinuz
+INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
+APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% loglevel=4 nomodeset nox
+SYSAPPEND 3
diff --git a/.linux_items/include/syslinux/wk_pxe.cfg b/.linux_items/include/syslinux/wk_pxe.cfg
index 92af00e3..f8a78220 100644
--- a/.linux_items/include/syslinux/wk_pxe.cfg
+++ b/.linux_items/include/syslinux/wk_pxe.cfg
@@ -3,6 +3,6 @@ MENU BACKGROUND pxelinux.png
INCLUDE boot/syslinux/wk_pxe_linux.cfg
#UFD#INCLUDE boot/syslinux/wk_pxe_winpe.cfg
-INCLUDE boot/syslinux/wk_pxe_extras_entry.cfg
+#DISABLED_UPSTREAM_BUG#INCLUDE boot/syslinux/wk_hdt.cfg
INCLUDE boot/syslinux/wk_tail.cfg
diff --git a/.linux_items/include/syslinux/wk_pxe_extras.cfg b/.linux_items/include/syslinux/wk_pxe_extras.cfg
deleted file mode 100644
index d677b4b0..00000000
--- a/.linux_items/include/syslinux/wk_pxe_extras.cfg
+++ /dev/null
@@ -1,9 +0,0 @@
-INCLUDE boot/syslinux/wk_head.cfg
-MENU BACKGROUND pxelinux.png
-
-INCLUDE boot/syslinux/wk_pxe_linux.cfg
-INCLUDE boot/syslinux/wk_pxe_linux_extras.cfg
-#UFD#INCLUDE boot/syslinux/wk_pxe_winpe.cfg
-INCLUDE boot/syslinux/wk_hdt.cfg
-
-INCLUDE boot/syslinux/wk_tail.cfg
diff --git a/.linux_items/include/syslinux/wk_pxe_extras_entry.cfg b/.linux_items/include/syslinux/wk_pxe_extras_entry.cfg
deleted file mode 100644
index ec76c263..00000000
--- a/.linux_items/include/syslinux/wk_pxe_extras_entry.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-LABEL wk_pxe_extras
-TEXT HELP
-Show extra boot options
-ENDTEXT
-MENU LABEL Extras
-KERNEL vesamenu.c32
-APPEND boot/syslinux/wk_pxe_extras.cfg
diff --git a/.linux_items/include/syslinux/wk_pxe_linux.cfg b/.linux_items/include/syslinux/wk_pxe_linux.cfg
index f7bf816d..caa6a1cc 100644
--- a/.linux_items/include/syslinux/wk_pxe_linux.cfg
+++ b/.linux_items/include/syslinux/wk_pxe_linux.cfg
@@ -3,8 +3,30 @@ TEXT HELP
A live Linux environment
* HW diagnostics, file-based backups, data recovery, etc
ENDTEXT
-MENU LABEL Linux
+MENU LABEL Linux (PXE)
LINUX boot/x86_64/vmlinuz
-INITRD boot/intel_ucode.img,boot/x86_64/archiso.img
-APPEND archisobasedir=%INSTALL_DIR% archiso_http_srv=http://${pxeserver}/ quiet
+INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
+APPEND archisobasedir=%INSTALL_DIR% archiso_http_srv=http://${pxeserver}/ loglevel=3
+SYSAPPEND 3
+
+LABEL wk_http_linux_i3
+TEXT HELP
+A live Linux environment (i3)
+ * HW diagnostics, file-based backups, data recovery, etc
+ENDTEXT
+MENU LABEL Linux (PXE) (i3)
+LINUX boot/x86_64/vmlinuz
+INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
+APPEND archisobasedir=%INSTALL_DIR% archiso_http_srv=http://${pxeserver}/ loglevel=3 i3
+SYSAPPEND 3
+
+LABEL wk_http_linux_cli
+TEXT HELP
+A live Linux environment (CLI)
+ * HW diagnostics, file-based backups, data recovery, etc
+ENDTEXT
+MENU LABEL Linux (PXE) (CLI)
+LINUX boot/x86_64/vmlinuz
+INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
+APPEND archisobasedir=%INSTALL_DIR% archiso_http_srv=http://${pxeserver}/ loglevel=4 nomodeset nox
SYSAPPEND 3
diff --git a/.linux_items/include/syslinux/wk_pxe_linux_extras.cfg b/.linux_items/include/syslinux/wk_pxe_linux_extras.cfg
deleted file mode 100644
index f29b2724..00000000
--- a/.linux_items/include/syslinux/wk_pxe_linux_extras.cfg
+++ /dev/null
@@ -1,21 +0,0 @@
-LABEL wk_http_linux_i3
-TEXT HELP
-A live Linux environment (i3)
- * HW diagnostics, file-based backups, data recovery, etc
-ENDTEXT
-MENU LABEL Linux (i3)
-LINUX boot/x86_64/vmlinuz
-INITRD boot/intel_ucode.img,boot/x86_64/archiso.img
-APPEND archisobasedir=%INSTALL_DIR% archiso_http_srv=http://${pxeserver}/ quiet i3
-SYSAPPEND 3
-
-LABEL wk_http_linux_cli
-TEXT HELP
-A live Linux environment (CLI)
- * HW diagnostics, file-based backups, data recovery, etc
-ENDTEXT
-MENU LABEL Linux (CLI)
-LINUX boot/x86_64/vmlinuz
-INITRD boot/intel_ucode.img,boot/x86_64/archiso.img
-APPEND archisobasedir=%INSTALL_DIR% archiso_http_srv=http://${pxeserver}/ nox nomodeset
-SYSAPPEND 3
diff --git a/.linux_items/include/syslinux/wk_pxe_winpe.cfg b/.linux_items/include/syslinux/wk_pxe_winpe.cfg
index 91d615d7..097df277 100644
--- a/.linux_items/include/syslinux/wk_pxe_winpe.cfg
+++ b/.linux_items/include/syslinux/wk_pxe_winpe.cfg
@@ -3,6 +3,6 @@ TEXT HELP
A live Windows environment
* Create partition backups, Install Windows, etc
ENDTEXT
-MENU LABEL Windows PE
+MENU LABEL Windows PE (PXE)
COM32 boot/syslinux/linux.c32
APPEND boot/wimboot gui initrdfile=winpe/x86_64/bootmgr,winpe/x86_64/BCD,winpe/x86_64/boot.sdi,winpe/x86_64/boot.wim
diff --git a/.linux_items/include/syslinux/wk_sys.cfg b/.linux_items/include/syslinux/wk_sys.cfg
index 0d375cf3..55a47e7f 100644
--- a/.linux_items/include/syslinux/wk_sys.cfg
+++ b/.linux_items/include/syslinux/wk_sys.cfg
@@ -2,6 +2,6 @@ INCLUDE boot/syslinux/wk_head.cfg
INCLUDE boot/syslinux/wk_sys_linux.cfg
#UFD#INCLUDE boot/syslinux/wk_sys_winpe.cfg
-INCLUDE boot/syslinux/wk_sys_extras_entry.cfg
+#DISABLED_UPSTREAM_BUG#INCLUDE boot/syslinux/wk_hdt.cfg
INCLUDE boot/syslinux/wk_tail.cfg
diff --git a/.linux_items/include/syslinux/wk_sys_extras.cfg b/.linux_items/include/syslinux/wk_sys_extras.cfg
deleted file mode 100644
index 3e5af215..00000000
--- a/.linux_items/include/syslinux/wk_sys_extras.cfg
+++ /dev/null
@@ -1,8 +0,0 @@
-INCLUDE boot/syslinux/wk_head.cfg
-
-INCLUDE boot/syslinux/wk_sys_linux.cfg
-INCLUDE boot/syslinux/wk_sys_linux_extras.cfg
-#UFD#INCLUDE boot/syslinux/wk_sys_winpe.cfg
-INCLUDE boot/syslinux/wk_hdt.cfg
-
-INCLUDE boot/syslinux/wk_tail.cfg
diff --git a/.linux_items/include/syslinux/wk_sys_extras_entry.cfg b/.linux_items/include/syslinux/wk_sys_extras_entry.cfg
deleted file mode 100644
index ce8fd3ac..00000000
--- a/.linux_items/include/syslinux/wk_sys_extras_entry.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-LABEL wk_sys_extras
-TEXT HELP
-Show extra boot options
-ENDTEXT
-MENU LABEL Extras
-KERNEL vesamenu.c32
-APPEND boot/syslinux/wk_sys_extras.cfg
diff --git a/.linux_items/include/syslinux/wk_sys_linux.cfg b/.linux_items/include/syslinux/wk_sys_linux.cfg
index 4b3b08c9..d4319c00 100644
--- a/.linux_items/include/syslinux/wk_sys_linux.cfg
+++ b/.linux_items/include/syslinux/wk_sys_linux.cfg
@@ -5,5 +5,27 @@ A live Linux environment
ENDTEXT
MENU LABEL Linux
LINUX boot/x86_64/vmlinuz
-INITRD boot/intel_ucode.img,boot/x86_64/archiso.img
-APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% quiet copytoram loglevel=3
+INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
+APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=3
+
+LABEL wk_linux_i3
+TEXT HELP
+A live Linux environment (i3)
+ * HW diagnostics, file-based backups, data recovery, etc
+ENDTEXT
+MENU LABEL Linux (i3)
+LINUX boot/x86_64/vmlinuz
+INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
+APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=3 i3
+SYSAPPEND 3
+
+LABEL wk_linux_cli
+TEXT HELP
+A live Linux environment (CLI)
+ * HW diagnostics, file-based backups, data recovery, etc
+ENDTEXT
+MENU LABEL Linux (CLI)
+LINUX boot/x86_64/vmlinuz
+INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
+APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram nox nomodeset
+SYSAPPEND 3
diff --git a/.linux_items/include/syslinux/wk_sys_linux_extras.cfg b/.linux_items/include/syslinux/wk_sys_linux_extras.cfg
deleted file mode 100644
index 882c705e..00000000
--- a/.linux_items/include/syslinux/wk_sys_linux_extras.cfg
+++ /dev/null
@@ -1,21 +0,0 @@
-LABEL wk_linux_i3
-TEXT HELP
-A live Linux environment (i3)
- * HW diagnostics, file-based backups, data recovery, etc
-ENDTEXT
-MENU LABEL Linux (i3)
-LINUX boot/x86_64/vmlinuz
-INITRD boot/intel_ucode.img,boot/x86_64/archiso.img
-APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% quiet copytoram loglevel=3 i3
-SYSAPPEND 3
-
-LABEL wk_linux_cli
-TEXT HELP
-A live Linux environment (CLI)
- * HW diagnostics, file-based backups, data recovery, etc
-ENDTEXT
-MENU LABEL Linux (CLI)
-LINUX boot/x86_64/vmlinuz
-INITRD boot/intel_ucode.img,boot/x86_64/archiso.img
-APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram nox nomodeset
-SYSAPPEND 3
diff --git a/.linux_items/packages/aur b/.linux_items/packages/aur
index 11874fa5..326ca732 100644
--- a/.linux_items/packages/aur
+++ b/.linux_items/packages/aur
@@ -2,7 +2,6 @@ aic94xx-firmware
bash-pipes
hfsprogs
i3lock-fancy-git
-inxi
mprime
nvme-cli
openbox-patched
diff --git a/.linux_items/packages/live_add b/.linux_items/packages/live_add
index ea784699..4a7245b4 100644
--- a/.linux_items/packages/live_add
+++ b/.linux_items/packages/live_add
@@ -34,7 +34,6 @@ htop
i3-gaps
i3lock-fancy-git
i3status
-inxi
ldns
leafpad
lha
diff --git a/Build Linux b/Build Linux
index af01c928..56233d51 100755
--- a/Build Linux
+++ b/Build Linux
@@ -229,7 +229,8 @@ function update_live_env() {
ssh-keygen -b 4096 -C "$username@$hostname" -N "" -f "$SKEL_DIR/.ssh/id_rsa"
echo 'rm /root/.ssh/id*' >> "$LIVE_DIR/airootfs/root/customize_airootfs.sh"
echo 'rm /root/.zlogin' >> "$LIVE_DIR/airootfs/root/customize_airootfs.sh"
- sed -r '/.*PermitRootLogin.*/d' "$LIVE_DIR/airootfs/root/customize_airootfs.sh"
+ sed -i -r '/.*PermitRootLogin.*/d' "$LIVE_DIR/airootfs/root/customize_airootfs.sh"
+ echo "sed -i -r '/.*PermitRootLogin.*/d' /etc/ssh/sshd_config" >> "$LIVE_DIR/airootfs/root/customize_airootfs.sh"
cp "$ROOT_DIR/.linux_items/authorized_keys" "$SKEL_DIR/.ssh/authorized_keys"
# Root user
diff --git a/README.md b/README.md
index 37c7f431..84e9a6cb 100644
--- a/README.md
+++ b/README.md
@@ -119,7 +119,7 @@ There's a `build-ufd` script which does the following:
* Mount the device(s) or network share(s) that contain the Linux ISO, WinPE ISO, and Main Kit folder.
* Connect the UFD but don't mount it.
* Get the device name of the UFD.
- * You can use $ `inxi -Dxx` or $ `lsblk --fs` to help.
+ * You can use $ `hw-drive-info` to help.
* $ `sudo build-ufd --ufd-device [device] --linux-iso [path] --main-kit [path] --winpe-iso [path]`
* **2nd Warning**: All data will be erased from the UFD resulting in **DATA LOSS**.
* NOTE: The Main Kit folder will be renamed on the UFD using `$KIT_NAME_FULL`